From bd0c5096f2ee70a85b1664419033125d6f7e69be Mon Sep 17 00:00:00 2001
From: Johannes Mey <johannes.mey@tu-dresden.de>
Date: Sun, 20 Jan 2019 11:48:38 +0100
Subject: [PATCH] fixed KMeans for test cases, prepared eval functions for
clusters
---
.../src/main/jastadd/solvers/Helpers.jadd | 15 ++
.../main/jastadd/solvers/ai/AbstractEval.jrag | 10 +
.../src/main/jastadd/solvers/ai/ai.jrag | 154 ++++++++++++++-
.../src/main/jastadd/solvers/ilp/ILP.ast | 1 +
.../src/main/jastadd/solvers/ilp/ILP.jadd | 19 ++
.../src/main/jastadd/solvers/ilp/ILP.jrag | 2 +-
.../solving/clustering/HardwareComponent.java | 36 ++--
.../st/mquat/solving/clustering/KMeans.java | 180 +++++++++++-------
.../mquat/solving/ilp/AbstractILPSolver.java | 2 +
.../solving/ilp/AbstractILPTransformer.java | 26 ++-
.../solving/ilp/ConcreteILPTransformer.java | 5 +
.../inf/st/mquat/solving/ilp/ILPMain.java | 2 +-
.../st/mquat/solving/ilp/ILPTransformer.java | 2 +
13 files changed, 359 insertions(+), 95 deletions(-)
create mode 100644 jastadd-mquat-base/src/main/jastadd/solvers/ai/AbstractEval.jrag
diff --git a/jastadd-mquat-base/src/main/jastadd/solvers/Helpers.jadd b/jastadd-mquat-base/src/main/jastadd/solvers/Helpers.jadd
index 6294668..c5653a7 100644
--- a/jastadd-mquat-base/src/main/jastadd/solvers/Helpers.jadd
+++ b/jastadd-mquat-base/src/main/jastadd/solvers/Helpers.jadd
@@ -15,6 +15,21 @@ aspect Helpers {
return assignment;
}
+ uncache Clause.simpleClusterAssignment(Request request, ResourceClass resource);
+ syn Assignment Clause.simpleClusterAssignment(Request request, ResourceClass resourceClass) {
+ Assignment assignment = new Assignment();
+ assignment.setRequest(request);
+ Implementation impl = containingImplementation();
+ if (impl != null) {
+ assignment.setImplementation(impl);
+
+ ResourceClassMapping mapping = new ResourceClassMapping(impl.getResourceRequirement().getInstance(0),new List<>(),resourceClass);
+ // Resource.populateResourceMapping(mapping,impl.getResourceRequirement(),resource);
+ assignment.setResourceMapping(mapping);
+ }
+ return assignment;
+ }
+
public Solution Root.createRandomSolution(java.util.Random random) {
diff --git a/jastadd-mquat-base/src/main/jastadd/solvers/ai/AbstractEval.jrag b/jastadd-mquat-base/src/main/jastadd/solvers/ai/AbstractEval.jrag
new file mode 100644
index 0000000..a8db7a5
--- /dev/null
+++ b/jastadd-mquat-base/src/main/jastadd/solvers/ai/AbstractEval.jrag
@@ -0,0 +1,10 @@
+aspect eval {
+
+
+ uncache Clause.checkUsing(Request request, ResourceClass resourceClass);
+ syn boolean Clause.checkUsing(Request request, ResourceClass resourceClass) = checkUsing(simpleClusterAssignment(request, resourceClass));
+
+ uncache Clause.evalUsing(Request request, ResourceClass target);
+ syn double Clause.evalUsing(Request request, ResourceClass target) = evalUsing(simpleClusterAssignment(request, target));
+
+}
diff --git a/jastadd-mquat-base/src/main/jastadd/solvers/ai/ai.jrag b/jastadd-mquat-base/src/main/jastadd/solvers/ai/ai.jrag
index 9fd4c96..1beae78 100644
--- a/jastadd-mquat-base/src/main/jastadd/solvers/ai/ai.jrag
+++ b/jastadd-mquat-base/src/main/jastadd/solvers/ai/ai.jrag
@@ -6,8 +6,160 @@ aspect AI {
syn int Resource.amount() = 1;
eq MultiResource.amount() = getAmount();
+ syn int ResourceClass.amount() {
+ int amount = 0;
+ for (ResourceRef ref : getResourceRefList()) {
+ amount += ref.getRef().amount();
+ }
+ return amount;
+ }
+
+ /**
+ * the non-terminal attribute to compute the abstract ILP subtree
+ */
syn ILP Root.getAbstractILP() {
- return null;
+ de.tudresden.inf.st.mquat.utils.StopWatch stopWatch = de.tudresden.inf.st.mquat.utils.StopWatch.start();
+
+ long timeoutValue = (long) de.tudresden.inf.st.mquat.utils.StaticSettings.get(ILP_TIMEOUT_VALUE);
+ java.util.concurrent.TimeUnit timeoutUnit = (java.util.concurrent.TimeUnit) de.tudresden.inf.st.mquat.utils.StaticSettings.get(ILP_TIMEOUT_UNIT);
+ long timeoutNanos = timeoutUnit.toNanos(timeoutValue);
+
+ ILP result = new ILP();
+ IlpVarInfo info = new IlpVarInfo();
+
+ IlpObjective objective = new IlpObjective();
+ objective.setKind(IlpObjectiveKind.MINIMIZE);
+ IlpLeftHandSide olhs = new IlpLeftHandSide();
+ objective.setIlpLeftHandSide(olhs);
+ result.setIlpObjective(objective);
+ for (Request request : this.getRequestList()) {
+ for (Component comp : request.relevantComponents()) {
+ IlpLeftHandSide oneCompLhs = new IlpLeftHandSide();
+ for (Implementation impl : comp.getImplementationList()) {
+ if (stopWatch.time() > timeoutNanos) {
+ return ilpTimeout("Timeout in implementation " + impl.name());
+ }
+ oneCompLhs.addIlpTerm(new IlpTerm(1, info.getIlpVariable(request, impl)));
+ IlpLeftHandSide oneImplLhs = new IlpLeftHandSide();
+
+ // #1 Objective function
+ for (ResourceClass resourceClass : this.getHardwareModel().getResourceClassList()) {
+ // r1#c2#i3#hw4
+ IlpTerm term = new IlpTerm();
+ IlpVariable var = info.getIlpVariable(request, impl, resourceClass);
+ term.setRef(var);
+ Optional<Clause> providingObjectiveClause = impl.findFirstProvidingClause(getObjective().getPropertyRef().getRef());
+ if (providingObjectiveClause.isPresent()) {
+ term.setValue(providingObjectiveClause.get().evalUsing(request, resourceClass));
+ } else {
+ term.setValue(0);
+ }
+ olhs.addIlpTerm(term);
+ oneImplLhs.addIlpTerm(new IlpTerm(1, var));
+ }
+ for (Clause reqClause : impl.requirementClauses()) {
+ if (stopWatch.time() > timeoutNanos) {
+ return ilpTimeout("Timeout in NFP-Negotiation");
+ }
+ Designator designator = reqClause.getDesignator();
+ IlpLeftHandSide reqLhs = new IlpLeftHandSide();
+ if (designator.isSoftwareDesignator()) {
+ for (Tuple<Implementation, Clause> tuple : reqClause.providingClausesOfRequiredComponent()) {
+ Implementation providingImpl = tuple.getKey();
+ Clause providingClause = tuple.getValue();
+ for (ResourceClass resourceClass : this.getHardwareModel().getResourceClassList()) {
+ reqLhs.addIlpTerm(new IlpTerm(providingClause.evalUsing(request, resourceClass),
+ info.getIlpVariable(request, providingImpl, resourceClass)));
+ }
+ }
+ for (ResourceClass resourceClass : this.getHardwareModel().getResourceClassList()) {
+ // we always use negative eval-value to get the required value on the right side (literally)
+ reqLhs.addIlpTerm(new IlpTerm(makeNegative(reqClause.evalUsing(request, resourceClass)),
+ info.getIlpVariable(request, impl, resourceClass)));
+ }
+ // 2b. non-functional requirements of required components
+ result.addIlpConstraint(new IlpConstraint(
+ request.getIlpName() + "_" + impl.getIlpName() + "_reqs_" +
+ designator.asSoftwareDesignator().getPropertyRef().getRef().getIlpName() + "_from_" +
+ designator.asSoftwareDesignator().getInstanceRef().getRef().referringComponent().getIlpName(),
+ reqLhs, reqClause.getClauseComparator(), 0));
+ } else {
+ for (ResourceClass resourceClass : this.getHardwareModel().getResourceClassList()) {
+ // check if constraint is fulfilled, otherwise remember this illegal combination
+ if (!reqClause.checkUsing(request, resourceClass)) {
+ info.getIlpVariable(request, impl, resourceClass).setIllegal(true);
+ }
+ }
+ }
+ }
+
+ oneImplLhs.addIlpTerm(new IlpTerm(-1, info.getIlpVariable(request, impl)));
+ // implementation variable definition
+ result.addIlpConstraint(new IlpConstraint(request.getIlpName() + "_single_" + impl.getIlpName(),
+ oneImplLhs, ClauseComparator.EQ, 0));
+ for (ComponentRequirement req : impl.getComponentRequirementList()) {
+ IlpLeftHandSide reqImplLhs = new IlpLeftHandSide();
+ for (Implementation reqImpl : req.getComponentRef().getRef().getImplementationList()) {
+ reqImplLhs.addIlpTerm(new IlpTerm(1, info.getIlpVariable(request, reqImpl)));
+ }
+ reqImplLhs.addIlpTerm(new IlpTerm(-1, info.getIlpVariable(request, impl)));
+ // 1c. required components
+ result.addIlpConstraint(new IlpConstraint(request.getIlpName() + "_" + impl.getIlpName() +
+ "_req_" + req.getComponentRef().getRef().getIlpName(),
+ reqImplLhs, ClauseComparator.GE, 0));
+ }
+ }
+ // 1b.
+ result.addIlpConstraint(new IlpConstraint(request.getIlpName() + "_opc_" + comp.getIlpName(),
+ oneCompLhs, ClauseComparator.LE, 1));
+ }
+ IlpLeftHandSide targetLhs = new IlpLeftHandSide();
+ for (Implementation impl : request.getTarget().getRef().getImplementationList()) {
+ IlpVariable var = info.getIlpVariable(request, impl);
+ targetLhs.addIlpTerm(new IlpTerm(1, var));
+ }
+ // 1a. functional requirement of the request
+ result.addIlpConstraint(new IlpConstraint(request.getIlpName() + "_target", targetLhs, ClauseComparator.EQ, 1));
+ for (Clause requiredClause : request.getConstraintList()) {
+ IlpLeftHandSide reqLhs = new IlpLeftHandSide();
+ Property requiredProperty = requiredClause.getDesignator().asSoftwareDesignator().getPropertyRef().getRef();
+ for(Implementation impl : request.getTarget().getRef().getImplementationList()) {
+ for (ResourceClass resourceClass : this.getHardwareModel().getResourceClassList()) {
+ Optional<Clause> providingClause = impl.findFirstProvidingClause(requiredProperty);
+ if (providingClause.isPresent()) {
+ IlpVariable var = info.getIlpVariable(request, impl, resourceClass);
+ reqLhs.addIlpTerm(new IlpTerm(providingClause.get().evalUsing(request, resourceClass), var));
+ }
+ }
+ }
+ // 2a. non-functional requirement of the request
+ result.addIlpConstraint(new IlpConstraint(request.getIlpName() + "_req_" + requiredProperty.getIlpName(),
+ reqLhs, requiredClause.getClauseComparator(),
+ requiredClause.evalUsing(request, (ResourceClass) null)));
+ }
+ }
+ if (stopWatch.time() > timeoutNanos) {
+ return ilpTimeout("Timeout after constraint creation");
+ }
+ /*
+ #2 Constraints
+ #2.1 Request constraints (requiredNFPs)
+ #2.2 Architecture constraints (One SW on one HW, Only one mode/configuration per impl and per SW)
+ #2.3 NFP-negotiation (Satisfy requirements from SW to both SW and HW)
+ */
+
+ // 2.2 Architecture constraints: Only one config per hardware resource
+ for (IlpConstraint constraint : info.resourceConstraints.values()) {
+ // 1d.
+ result.addIlpConstraint(constraint);
+ }
+
+ // variables
+ for (IlpVariable var : info.vars.values()) {
+ result.addIlpVariable(var);
+ }
+
+ return result;
}
}
\ No newline at end of file
diff --git a/jastadd-mquat-base/src/main/jastadd/solvers/ilp/ILP.ast b/jastadd-mquat-base/src/main/jastadd/solvers/ilp/ILP.ast
index fc06d7c..7384d30 100644
--- a/jastadd-mquat-base/src/main/jastadd/solvers/ilp/ILP.ast
+++ b/jastadd-mquat-base/src/main/jastadd/solvers/ilp/ILP.ast
@@ -9,6 +9,7 @@ IlpConstraint ::= <Name:String> IlpLeftHandSide <ClauseComparator:ClauseComparat
abstract IlpVariable ::= <Name:String> <Request:Request> <Impl:Implementation> <Illegal:boolean>;
IlpAllResourcesVariable:IlpVariable ;
IlpMappingVariable:IlpVariable ::= <Resource:Resource> ;
+IlpClassMappingVariable:IlpVariable ::= <ResourceClass:ResourceClass> ;
// sum of terms
IlpLeftHandSide ::= IlpTerm* ;
diff --git a/jastadd-mquat-base/src/main/jastadd/solvers/ilp/ILP.jadd b/jastadd-mquat-base/src/main/jastadd/solvers/ilp/ILP.jadd
index e0fb837..eb19a31 100644
--- a/jastadd-mquat-base/src/main/jastadd/solvers/ilp/ILP.jadd
+++ b/jastadd-mquat-base/src/main/jastadd/solvers/ilp/ILP.jadd
@@ -42,10 +42,12 @@ aspect ILP {
public class IlpVarInfo {
public java.util.Map<String, IlpVariable> vars;
public java.util.Map<Resource, IlpConstraint> resourceConstraints;
+ public java.util.Map<ResourceClass, IlpConstraint> resourceClassConstraints;
public IlpVarInfo() {
vars = new java.util.TreeMap<>();
resourceConstraints = new java.util.HashMap<>();
+ resourceClassConstraints = new java.util.HashMap<>();
}
public IlpVariable getIlpVariable(Request request, Implementation impl, Resource resource) {
@@ -65,6 +67,23 @@ aspect ILP {
return result;
}
+ public IlpVariable getIlpVariable(Request request, Implementation impl, ResourceClass resourceClass) {
+ String varName = request.getIlpName() + "#" + impl.getIlpName() + "#" + resourceClass.getIlpName();
+ IlpVariable result = vars.get(varName);
+ IlpConstraint resourceClassConstraint = resourceClassConstraints.get(resourceClass);
+ if (resourceClassConstraint == null) {
+ resourceClassConstraint = new IlpConstraint("one_on_" + resourceClass.getIlpName(), new IlpLeftHandSide(),
+ ClauseComparator.LE, resourceClass.amount());
+ resourceClassConstraints.put(resourceClass, resourceClassConstraint);
+ }
+ if (result == null) {
+ result = new IlpClassMappingVariable(varName, request, impl, false, resourceClass);
+ vars.put(varName, result);
+ resourceClassConstraint.getIlpLeftHandSide().addIlpTerm(new IlpTerm(1, result));
+ }
+ return result;
+ }
+
public IlpVariable getIlpVariable(Request request, Implementation impl) {
String varName = request.getIlpName() + "#" + impl.getIlpName();
IlpVariable result = vars.get(varName);
diff --git a/jastadd-mquat-base/src/main/jastadd/solvers/ilp/ILP.jrag b/jastadd-mquat-base/src/main/jastadd/solvers/ilp/ILP.jrag
index f8d8c98..951aa25 100644
--- a/jastadd-mquat-base/src/main/jastadd/solvers/ilp/ILP.jrag
+++ b/jastadd-mquat-base/src/main/jastadd/solvers/ilp/ILP.jrag
@@ -159,7 +159,7 @@ aspect ILP {
// 2a. non-functional requirement of the request
result.addIlpConstraint(new IlpConstraint(request.getIlpName() + "_req_" + requiredProperty.getIlpName(),
reqLhs, requiredClause.getClauseComparator(),
- requiredClause.evalUsing(request, null)));
+ requiredClause.evalUsing(request, (Resource) null)));
}
}
if (stopWatch.time() > timeoutNanos) {
diff --git a/jastadd-mquat-solver-ilp/src/main/java/de/tudresden/inf/st/mquat/solving/clustering/HardwareComponent.java b/jastadd-mquat-solver-ilp/src/main/java/de/tudresden/inf/st/mquat/solving/clustering/HardwareComponent.java
index 5f334aa..4e9e2e5 100644
--- a/jastadd-mquat-solver-ilp/src/main/java/de/tudresden/inf/st/mquat/solving/clustering/HardwareComponent.java
+++ b/jastadd-mquat-solver-ilp/src/main/java/de/tudresden/inf/st/mquat/solving/clustering/HardwareComponent.java
@@ -9,27 +9,27 @@ import weka.core.Instance;
*/
public class HardwareComponent {
- private Resource resource;
- private Instance instance;
+ private Resource resource;
+ private Instance instance;
- public HardwareComponent(Resource resource, int attributes_number) {
- this.resource = resource;
- this.instance = new DenseInstance(attributes_number);
- }
+ public HardwareComponent(Resource resource, int attributes_number) {
+ this.resource = resource;
+ this.instance = new DenseInstance(attributes_number);
+ }
- public Resource getResource() {
- return resource;
- }
+ public Resource getResource() {
+ return resource;
+ }
- public void setResource(Resource resource) {
- this.resource = resource;
- }
+ public void setResource(Resource resource) {
+ this.resource = resource;
+ }
- public Instance getInstance() {
- return instance;
- }
+ public Instance getInstance() {
+ return instance;
+ }
- public void setInstance(Instance instance) {
- this.instance = instance;
- }
+ public void setInstance(Instance instance) {
+ this.instance = instance;
+ }
}
diff --git a/jastadd-mquat-solver-ilp/src/main/java/de/tudresden/inf/st/mquat/solving/clustering/KMeans.java b/jastadd-mquat-solver-ilp/src/main/java/de/tudresden/inf/st/mquat/solving/clustering/KMeans.java
index 04ea64d..59a7a8c 100644
--- a/jastadd-mquat-solver-ilp/src/main/java/de/tudresden/inf/st/mquat/solving/clustering/KMeans.java
+++ b/jastadd-mquat-solver-ilp/src/main/java/de/tudresden/inf/st/mquat/solving/clustering/KMeans.java
@@ -1,8 +1,11 @@
package de.tudresden.inf.st.mquat.solving.clustering;
import de.tudresden.inf.st.mquat.jastadd.model.Resource;
+import de.tudresden.inf.st.mquat.jastadd.model.ResourceType;
import de.tudresden.inf.st.mquat.jastadd.model.Root;
-import weka.clusterers.*;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import weka.clusterers.SimpleKMeans;
import weka.core.Attribute;
import weka.core.Instances;
@@ -20,87 +23,120 @@ import java.util.Map;
* @author Dmytro Pukhkaiev
* @version 0.1
*/
-public class KMeans{
- // dataset
- private Instances resources;
- // number of clusters
- private int k;
- // list of resources
- private ArrayList<HardwareComponent> hardwareComponentList = new ArrayList<>();
-
- public KMeans(Root model) {
- // create attributes for instances
- Attribute cpu = new Attribute("cpu");
- Attribute ram = new Attribute("ram");
- Attribute disk = new Attribute("disk");
- Attribute network = new Attribute("network");
- ArrayList<Attribute> attributeList = new ArrayList<Attribute>();
- attributeList.add(cpu);
- attributeList.add(ram);
- attributeList.add(disk);
- attributeList.add(network);
-
- // create a dataset
- resources = new Instances("resources", attributeList, 0);
-
- //instantiate items in the dataset
- for (Resource resource : model.getHardwareModel().getResourceList()) {
- if (resource.getType().getName().getName().equals("ComputeNode")) {
- HardwareComponent hardwareComponent = new HardwareComponent(resource, resource.getNumSubResource());
- hardwareComponent.getInstance().setDataset(resources);
-
- for (Resource sub : resource.getSubResourceList()) {
- String typeName = sub.getType().getName().getName();
- switch (typeName) {
- case "CPU":
- hardwareComponent.getInstance().setValue(cpu, sub.getCurrentValueByPropertyName("frequency"));
- break;
- case "RAM":
- hardwareComponent.getInstance().setValue(ram, sub.getCurrentValueByPropertyName("total"));
- break;
- case "DISK":
- hardwareComponent.getInstance().setValue(disk, sub.getCurrentValueByPropertyName("total"));
- break;
- case "NETWORK":
- hardwareComponent.getInstance().setValue(network, sub.getCurrentValueByPropertyName("throughput"));
- break;
- default:
- throw new RuntimeException("Unable to transform unknown resource of type" + typeName);
- }
- }
-
- hardwareComponentList.add(hardwareComponent);
- }
+public class KMeans {
+ private static final Logger logger = LogManager.getLogger(KMeans.class);
+
+ // dataset
+ private Instances resources;
+
+ // the model
+ private Root model;
+
+ // list of resources
+ private ArrayList<HardwareComponent> hardwareComponentList = new ArrayList<>();
+
+ public KMeans(Root model) {
+
+ this.model = model;
+
+ // create attributes for instances
+ Attribute cpu = new Attribute("cpu");
+ Attribute ram = new Attribute("ram");
+ Attribute disk = new Attribute("disk");
+ Attribute network = new Attribute("network");
+
+ ArrayList<Attribute> attributeList = new ArrayList<>();
+
+ // we expect one top-level resource type and consider at most four sub-resources of the following names
+ for (ResourceType resourceType : model.getHardwareModel().getResourceType(0).getSubTypeList()) {
+ switch (resourceType.name().toLowerCase()) {
+ case "cpu":
+ attributeList.add(cpu);
+ break;
+ case "ram":
+ attributeList.add(ram);
+ break;
+ case "disk":
+ attributeList.add(disk);
+ break;
+ case "network":
+ attributeList.add(network);
+ }
+ }
+
+ // create a dataset
+ resources = new Instances("resources", attributeList, 0);
+
+ //instantiate items in the dataset
+ for (Resource resource : model.getHardwareModel().getResourceList()) {
+ if (resource.getType().getName().getName().equals("ComputeNode")) {
+ HardwareComponent hardwareComponent = new HardwareComponent(resource, resource.getNumSubResource());
+ hardwareComponent.getInstance().setDataset(resources);
+
+ for (Resource sub : resource.getSubResourceList()) {
+ String typeName = sub.getType().getName().getName();
+ switch (typeName) {
+ case "CPU":
+ hardwareComponent.getInstance().setValue(cpu, sub.getCurrentValueByPropertyName("frequency"));
+ break;
+ case "RAM":
+ hardwareComponent.getInstance().setValue(ram, sub.getCurrentValueByPropertyName("total"));
+ break;
+ case "DISK":
+ hardwareComponent.getInstance().setValue(disk, sub.getCurrentValueByPropertyName("total"));
+ break;
+ case "NETWORK":
+ hardwareComponent.getInstance().setValue(network, sub.getCurrentValueByPropertyName("throughput"));
+ break;
+ default:
+ throw new RuntimeException("Unable to transform unknown resource of type" + typeName);
+ }
}
- for (HardwareComponent hwc : hardwareComponentList)
- resources.add(hwc.getInstance());
+ hardwareComponentList.add(hardwareComponent);
+ }
+ }
+
+ for (HardwareComponent hwc : hardwareComponentList)
+ resources.add(hwc.getInstance());
+
+ }
- k = (int) (0.2 * model.getHardwareModel().getResourceList().asJavaCollection().size());
+ public Map<Integer, ArrayList<Resource>> buildClusters(int numClusters) {
+ if (numClusters < 1) {
+ logger.error("Unable to cluster the model in less than one cluster (numClusters was " + numClusters + ")");
+ throw new RuntimeException();
}
- public Map<Integer, ArrayList<Resource>> buildClusters(){
+ logger.info("Clustering " + model.getHardwareModel().getNumResource() + " resources in " + numClusters + " clusters");
- SimpleKMeans algorithm = new SimpleKMeans();
- Map<Integer, ArrayList<Resource>> Clusters = new HashMap<>();
+ SimpleKMeans algorithm = new SimpleKMeans();
+ Map<Integer, ArrayList<Resource>> Clusters = new HashMap<>();
- for (int i = 0; i < k; i ++)
- Clusters.put(i, new ArrayList<>());
- try {
- algorithm.setNumClusters(k);
- algorithm.setPreserveInstancesOrder(true);
- algorithm.buildClusterer(resources);
+ for (int i = 0; i < numClusters; i++)
+ Clusters.put(i, new ArrayList<>());
+ try {
+ algorithm.setNumClusters(numClusters);
+ algorithm.setPreserveInstancesOrder(true);
+ algorithm.buildClusterer(resources);
- int[] assignments = algorithm.getAssignments();
+ int[] assignments = algorithm.getAssignments();
- for (int i = 0; i < assignments.length; i++){
- Clusters.get(assignments[i]).add(hardwareComponentList.get(i).getResource());
- }
+ for (int i = 0; i < assignments.length; i++) {
+ Clusters.get(assignments[i]).add(hardwareComponentList.get(i).getResource());
+ }
- } catch (Exception e) {
- e.printStackTrace();
- }
- return Clusters;
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ // print cluster statistics
+ logger.info("Clusters:");
+ for (int c = 0; c < numClusters; c++) {
+ logger.info("Cluster " + c + ": " + Clusters.get(c).size() + " resources");
}
+
+ return Clusters;
+ }
}
diff --git a/jastadd-mquat-solver-ilp/src/main/java/de/tudresden/inf/st/mquat/solving/ilp/AbstractILPSolver.java b/jastadd-mquat-solver-ilp/src/main/java/de/tudresden/inf/st/mquat/solving/ilp/AbstractILPSolver.java
index 59cb830..b7d0e40 100644
--- a/jastadd-mquat-solver-ilp/src/main/java/de/tudresden/inf/st/mquat/solving/ilp/AbstractILPSolver.java
+++ b/jastadd-mquat-solver-ilp/src/main/java/de/tudresden/inf/st/mquat/solving/ilp/AbstractILPSolver.java
@@ -61,6 +61,8 @@ public abstract class AbstractILPSolver implements BenchmarkableSolver {
public synchronized Solution solve(Root model) throws SolvingException {
StopWatch watch = StopWatch.start();
+ transformer.prepareModel(model);
+
reset();
if (model.getNumRequest() == 0) {
return Solution.emptySolutionOf(model);
diff --git a/jastadd-mquat-solver-ilp/src/main/java/de/tudresden/inf/st/mquat/solving/ilp/AbstractILPTransformer.java b/jastadd-mquat-solver-ilp/src/main/java/de/tudresden/inf/st/mquat/solving/ilp/AbstractILPTransformer.java
index 46049ad..08d9927 100644
--- a/jastadd-mquat-solver-ilp/src/main/java/de/tudresden/inf/st/mquat/solving/ilp/AbstractILPTransformer.java
+++ b/jastadd-mquat-solver-ilp/src/main/java/de/tudresden/inf/st/mquat/solving/ilp/AbstractILPTransformer.java
@@ -1,7 +1,10 @@
package de.tudresden.inf.st.mquat.solving.ilp;
-import de.tudresden.inf.st.mquat.jastadd.model.ILP;
-import de.tudresden.inf.st.mquat.jastadd.model.Root;
+import de.tudresden.inf.st.mquat.jastadd.model.*;
+import de.tudresden.inf.st.mquat.solving.clustering.KMeans;
+
+import java.util.ArrayList;
+import java.util.Map;
public class AbstractILPTransformer implements ILPTransformer {
@@ -15,5 +18,24 @@ public class AbstractILPTransformer implements ILPTransformer {
return "-abstract";
}
+ @Override
+ public void prepareModel(Root model) {
+ int numClusters = Math.max(2,model.getHardwareModel().getNumResource()/5);
+ KMeans kmeans = new KMeans(model);
+
+ Map<Integer, ArrayList<Resource>> clusters = kmeans.buildClusters(numClusters);
+
+ for (int clusterId : clusters.keySet()) {
+
+ ResourceClass resourceClass = new ResourceClass();
+ resourceClass.setName(new Name("class_" + clusterId));
+
+ for (Resource resource : clusters.get(clusterId)) {
+ resource.setResourceClassRef(resourceClass.createRef());
+ resourceClass.addResourceRef(resource.createRef());
+ }
+ }
+ }
+
}
diff --git a/jastadd-mquat-solver-ilp/src/main/java/de/tudresden/inf/st/mquat/solving/ilp/ConcreteILPTransformer.java b/jastadd-mquat-solver-ilp/src/main/java/de/tudresden/inf/st/mquat/solving/ilp/ConcreteILPTransformer.java
index 0ba3cfc..eacb97c 100644
--- a/jastadd-mquat-solver-ilp/src/main/java/de/tudresden/inf/st/mquat/solving/ilp/ConcreteILPTransformer.java
+++ b/jastadd-mquat-solver-ilp/src/main/java/de/tudresden/inf/st/mquat/solving/ilp/ConcreteILPTransformer.java
@@ -14,4 +14,9 @@ public class ConcreteILPTransformer implements ILPTransformer {
public String getSuffix() {
return "";
}
+
+ @Override
+ public void prepareModel(Root model) {
+ // do nothing
+ }
}
diff --git a/jastadd-mquat-solver-ilp/src/main/java/de/tudresden/inf/st/mquat/solving/ilp/ILPMain.java b/jastadd-mquat-solver-ilp/src/main/java/de/tudresden/inf/st/mquat/solving/ilp/ILPMain.java
index cb99848..70e621a 100644
--- a/jastadd-mquat-solver-ilp/src/main/java/de/tudresden/inf/st/mquat/solving/ilp/ILPMain.java
+++ b/jastadd-mquat-solver-ilp/src/main/java/de/tudresden/inf/st/mquat/solving/ilp/ILPMain.java
@@ -91,7 +91,7 @@ public class ILPMain {
ScenarioGenerator gen = new ScenarioGenerator(new ScenarioDescription(1, 2, 0, 0, 0, 2, 2, 2.5, 3, 1, 0));
Root model = gen.generate();
KMeans kMeans = new KMeans(model);
- Map<Integer, ArrayList<Resource>> clusters = kMeans.buildClusters();
+ Map<Integer, ArrayList<Resource>> clusters = kMeans.buildClusters(model.getHardwareModel().getNumResource()/5);
Solver external = new GLPKSolver().setDeleteFilesOnExit(false);
Solution solution = external.solve(model);
logger.info(model.print(new MquatWriteSettings(" ")));
diff --git a/jastadd-mquat-solver-ilp/src/main/java/de/tudresden/inf/st/mquat/solving/ilp/ILPTransformer.java b/jastadd-mquat-solver-ilp/src/main/java/de/tudresden/inf/st/mquat/solving/ilp/ILPTransformer.java
index 8c75aee..da5a1a7 100644
--- a/jastadd-mquat-solver-ilp/src/main/java/de/tudresden/inf/st/mquat/solving/ilp/ILPTransformer.java
+++ b/jastadd-mquat-solver-ilp/src/main/java/de/tudresden/inf/st/mquat/solving/ilp/ILPTransformer.java
@@ -7,4 +7,6 @@ public interface ILPTransformer {
ILP getILP(Root model);
String getSuffix();
+
+ void prepareModel(Root model);
}
--
GitLab