diff --git a/.gitignore b/.gitignore index bde6c8e745c0d31daefd49b6ed4dbf9d2a24e29a..dc2f2ae7b0ad629b9f1825efdaabfe1c518f384c 100644 --- a/.gitignore +++ b/.gitignore @@ -30,3 +30,4 @@ hs_err_pid* .settings/ .classpath .project +results/ diff --git a/README.md b/README.md index 1cf35c2e5ad5d73c5dc094ffc32926b72cac3c40..2e2f6da1497ab337adb0b11cd0de34146e65a7a8 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,8 @@ The following steps need to be completed: 1. Add an include of your project to `settings.gradle` 1. Optional step: Create a test case by extending the [`HandwrittenTestSuite`](https://git-st.inf.tu-dresden.de/stgroup/ttc18/blob/master/jastadd-mquat-solver/src/test/java/de/tudresden/inf/st/mquat/solving/HandwrittenTestSuite.java) 1. Add a compile dependency to your project in `build.gradle` of the project `jastadd-mquat-benchmark` -1. Update [`de.tudresden.inf.st.mquat.benchmark.SolverFactory.createAvailableSolversIfNeeded`](https://git-st.inf.tu-dresden.de/stgroup/ttc18/blob/master/jastadd-mquat-benchmark/src/main/java/de/tudresden/inf/st/mquat/benchmark/SolverFactory.java#L22) to create a new instance of your solver +1. Update [`de.tudresden.inf.st.mquat.benchmark.SolverFactory.createAvailableSolversIfNeeded`] + (https://git-st.inf.tu-dresden.de/stgroup/ttc18/blob/master/jastadd-mquat-benchmark/src/main/java/de/tudresden/inf/st/mquat/benchmark/SolverFactory.java#L22) to create a new instance of your solver 1. Add the name of your solver to the benchmark settings - Use `jastadd-mquat-benchmark/src/main/resources/scenarios.json` for the Gradle task `benchmarkFull` - Use `jastadd-mquat-benchmark/src/main/resources/local-benchmark-settings.json` for the Gralde task `benchmarkCustom` (see [Custom Benchmark](#custom-benchmark) for details) diff --git a/jastadd-mquat-benchmark/build.gradle b/jastadd-mquat-benchmark/build.gradle index eaafbc051d26d58a19aed720a692799fa8d99ab0..f9da75cbda62ed00328be82fa96c00050055db9f 100644 --- a/jastadd-mquat-benchmark/build.gradle +++ b/jastadd-mquat-benchmark/build.gradle @@ -11,6 +11,7 @@ dependencies { compile project(':jastadd-mquat-base') compile project(':jastadd-mquat-solver') compile project(':jastadd-mquat-solver-ilp') + compile project(':jastadd-mquat-solver-emfer') compile project(':jastadd-mquat-solver-simple') compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.8.8.1' compile group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.10.0' @@ -30,7 +31,7 @@ task benchmarkFull(type: JavaExec, dependsOn: assemble) { classpath = sourceSets.test.runtimeClasspath main = 'de.tudresden.inf.st.mquat.benchmark.FullBenchmarkMain' systemProperty "java.library.path", project.glpkPath -// jvmArgs("-Xmx=4096m") + // jvmArgs("-Xmx=2g") if (project.hasProperty("scenario")) { args(scenario.split(',')) } diff --git a/jastadd-mquat-benchmark/src/main/java/de/tudresden/inf/st/mquat/benchmark/SolverFactory.java b/jastadd-mquat-benchmark/src/main/java/de/tudresden/inf/st/mquat/benchmark/SolverFactory.java index 3a28cd527edf9480cafd5a88342d1fef2c6f6da7..4afb9e4334a7de967603f1056f01bbcaeb768949 100644 --- a/jastadd-mquat-benchmark/src/main/java/de/tudresden/inf/st/mquat/benchmark/SolverFactory.java +++ b/jastadd-mquat-benchmark/src/main/java/de/tudresden/inf/st/mquat/benchmark/SolverFactory.java @@ -4,6 +4,7 @@ import de.tudresden.inf.st.mquat.solving.BenchmarkableSolver; import de.tudresden.inf.st.mquat.solving.ilp.ILPDirectSolver; import de.tudresden.inf.st.mquat.solving.ilp.ILPExternalSolver; import de.tudresden.inf.st.mquat.solving.simple.SimpleSolver; +import uniks.EMFeRSolver; import java.util.Map; import java.util.function.Function; @@ -22,9 +23,10 @@ public class SolverFactory { private static Map<String, BenchmarkableSolver> createAvailableSolversIfNeeded() { if (availableSolvers == null) { availableSolvers = Stream.of( - new ILPExternalSolver(), - new ILPDirectSolver(), - new SimpleSolver() + new EMFeRSolver(), + // new ILPExternalSolver(), + new ILPDirectSolver(), + new SimpleSolver() ).collect(Collectors.toMap(BenchmarkableSolver::getName, Function.identity())); } return availableSolvers; diff --git a/jastadd-mquat-benchmark/src/main/resources/scenarios.json b/jastadd-mquat-benchmark/src/main/resources/scenarios.json index 42a8d7b7e3d8435a7dac189021350f4d5736de23..d68e08faef22bb22c3110e01146a738555b94f42 100644 --- a/jastadd-mquat-benchmark/src/main/resources/scenarios.json +++ b/jastadd-mquat-benchmark/src/main/resources/scenarios.json @@ -2,11 +2,12 @@ "path": "results", "logLevel": "info", "solvers": [ - "ilp-direct" + "ilp-direct", // "ilp-external", -// "simple" + "emfer", + "simple" ], - "timeoutValue": 15, + "timeoutValue": 2, "timeoutUnit": "MINUTES", "seed": 0, // "repetitions": 10, @@ -17,12 +18,12 @@ { "id": 3, "name": "small-complex-sw", "variants": 2, "requests": 1, "depth": 5, "resources": 1.5 }, { "id": 4, "name": "medium", "variants": 10, "requests": 15, "depth": 2, "resources": 1.5 }, { "id": 5, "name": "medium-many-hw", "variants": 10, "requests": 15, "depth": 2, "resources": 5 }, - { "id": 6, "name": "medium-complex-sw", "variants": 5, "requests": 10, "depth": 5, "resources": 1.5 }, - { "id": 7, "name": "large", "variants": 20, "requests": 20, "depth": 2, "resources": 1.5 }, - { "id": 8, "name": "large-many-hw", "variants": 20, "requests": 20, "depth": 2, "resources": 5 }, - { "id": 9, "name": "large-complex-sw", "variants": 10, "requests": 20, "depth": 5, "resources": 1.5 }, - { "id": 10, "name": "huge", "variants": 50, "requests": 50, "depth": 2, "resources": 1.5 }, - { "id": 11, "name": "huge-many-hw", "variants": 50, "requests": 50, "depth": 2, "resources": 5 }, - { "id": 12, "name": "huge-complex-sw", "variants": 20, "requests": 50, "depth": 5, "resources": 1.5 } + { "id": 6, "name": "medium-complex-sw", "variants": 5, "requests": 10, "depth": 5, "resources": 1.5 } +// { "id": 7, "name": "large", "variants": 20, "requests": 20, "depth": 2, "resources": 1.5 }, +// { "id": 8, "name": "large-many-hw", "variants": 20, "requests": 20, "depth": 2, "resources": 5 }, +// { "id": 9, "name": "large-complex-sw", "variants": 10, "requests": 20, "depth": 5, "resources": 1.5 }, +// { "id": 10, "name": "huge", "variants": 50, "requests": 50, "depth": 2, "resources": 1.5 }, +// { "id": 11, "name": "huge-many-hw", "variants": 50, "requests": 50, "depth": 2, "resources": 5 }, +// { "id": 12, "name": "huge-complex-sw", "variants": 20, "requests": 50, "depth": 5, "resources": 1.5 } ] } diff --git a/jastadd-mquat-solver-emfer/libs/libEMFER.jar b/jastadd-mquat-solver-emfer/libs/libEMFER.jar index b4797b38d2a2fe903daeac6180408e3ab95512b1..2e9952b882ea7f4b4d91fac33d51afec05e4a234 100644 Binary files a/jastadd-mquat-solver-emfer/libs/libEMFER.jar and b/jastadd-mquat-solver-emfer/libs/libEMFER.jar differ diff --git a/jastadd-mquat-solver-emfer/src/main/java/uniks/EMFeRSolver.java b/jastadd-mquat-solver-emfer/src/main/java/uniks/EMFeRSolver.java index a638bae0fa95e280d4d217046ce9be9a919a5abf..b6eaaeab93a6838ffe6b49280b637dc01fd48f5d 100644 --- a/jastadd-mquat-solver-emfer/src/main/java/uniks/EMFeRSolver.java +++ b/jastadd-mquat-solver-emfer/src/main/java/uniks/EMFeRSolver.java @@ -6,210 +6,227 @@ import de.tudresden.inf.st.mquat.solving.Solver; import de.tudresden.inf.st.mquat.solving.SolverUtils; import de.tudresden.inf.st.mquat.solving.SolvingException; import de.tudresden.inf.st.mquat.utils.StopWatch; +import emfer.EMFeR; +import emfer.reachability.ReachableState; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.eclipse.emf.ecore.EDataType; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EcorePackage; import uniks.ttc18.EAssignment; import uniks.ttc18.ESolution; import uniks.ttc18.Ttc18Factory; -import java.util.*; import java.util.List; +import java.util.Set; +import java.util.Stack; import java.util.concurrent.TimeUnit; public class EMFeRSolver implements BenchmarkableSolver { - private static final Logger logger = LogManager.getLogger(EMFeRSolver.class); + private static final Logger logger = LogManager.getLogger(EMFeRSolver.class); - private Solution lastSolution; - private long lastSolvingTime; + private Solution lastSolution; + private long lastSolvingTime; - private int solutionCounter; + private int solutionCounter; - private StopWatch stopWatch; + private StopWatch stopWatch; - private long maxSolvingTime; - private boolean timedOut; + private long maxSolvingTime; + private boolean timedOut; - public EMFeRSolver() { - this(Long.MAX_VALUE); - } + public EMFeRSolver() { + this(Long.MAX_VALUE); + } - public EMFeRSolver(long maxSolvingTime) { - this.maxSolvingTime = maxSolvingTime; - reset(); - } + public EMFeRSolver(long maxSolvingTime) { + this.maxSolvingTime = maxSolvingTime; + reset(); + } - private static void assignResource(Assignment assignment, Resource resource) { - Implementation impl = assignment.getImplementation(); + private static void assignResource(Assignment assignment, Resource resource) { + Implementation impl = assignment.getImplementation(); - ResourceMapping mapping = new ResourceMapping(impl.getResourceRequirement().getInstance(0), resource, new de.tudresden.inf.st.mquat.jastadd.model.List<>()); - SolverUtils.populateResourceMapping(mapping, impl.getResourceRequirement(), resource); - assignment.setResourceMapping(mapping); - } + ResourceMapping mapping = new ResourceMapping(impl.getResourceRequirement().getInstance(0), resource, new de.tudresden.inf.st.mquat.jastadd.model.List<>()); + SolverUtils.populateResourceMapping(mapping, impl.getResourceRequirement(), resource); + assignment.setResourceMapping(mapping); + } - private int checkAssignment(Solution solution, List<Solution> solutions, List<Assignment> assignments, List<Set<Resource>> possibleResources, int index, Stack<Resource> usedResources) { - int checkCounter = 0; + private int checkAssignment(Solution solution, List<Solution> solutions, List<Assignment> assignments, List<Set<Resource>> possibleResources, int index, Stack<Resource> usedResources) { + int checkCounter = 0; - Assignment assignment = assignments.get(index); - for (Resource resource : possibleResources.get(index)) { + Assignment assignment = assignments.get(index); + for (Resource resource : possibleResources.get(index)) { - if (stopWatch.time(TimeUnit.MILLISECONDS) > maxSolvingTime) { - return checkCounter; - } - - if (usedResources.contains(resource)) continue; - assignResource(assignment, resource); - usedResources.push(resource); - checkCounter++; - if (index == assignments.size() - 1) { - if (solution.isValid()) { - solutionCounter++; - if (solutions.isEmpty() || solution.computeObjective() < solutions.get(solutions.size() - 1).computeObjective()) { - Solution clone = solution.deepCopy(); - solutions.add(clone); - logger.info("found a better solution with an objective of {}.", solution.computeObjective()); - } - - } - } else { - checkCounter += checkAssignment(solution, solutions, assignments, possibleResources, index + 1, usedResources); - } - usedResources.pop(); - } - return checkCounter; - } + if (stopWatch.time(TimeUnit.MILLISECONDS) > maxSolvingTime) { + return checkCounter; + } - @Override - public Solution solve(Root model) throws SolvingException { - reset(); - if (model.getNumRequest() == 0) { - return Solution.emptySolutionOf(model); - } + if (usedResources.contains(resource)) continue; + assignResource(assignment, resource); + usedResources.push(resource); + checkCounter++; + if (index == assignments.size() - 1) { + if (solution.isValid()) { + solutionCounter++; + if (solutions.isEmpty() || solution.computeObjective() < solutions.get(solutions.size() - 1).computeObjective()) { + Solution clone = solution.deepCopy(); + solutions.add(clone); + logger.info("found a better solution with an objective of {}.", solution.computeObjective()); + } - ESolution eSolution = Ttc18Factory.eINSTANCE.createESolution(); + } + } else { + checkCounter += checkAssignment(solution, solutions, assignments, possibleResources, index + 1, usedResources); + } + usedResources.pop(); + } + return checkCounter; + } - EMFeRTrafos emFeRTrafos = new EMFeRTrafos(model); + @Override + public Solution solve(Root model) throws SolvingException + { + stopWatch = StopWatch.start(); - emFeRTrafos.createTopLevelAssignments(eSolution); + EMFeRTrafos emFeRTrafos = new EMFeRTrafos(model); - for (EAssignment topAssignment : eSolution.getAssignments()) - { - emFeRTrafos.createSubAssignments(eSolution, topAssignment); - } + ESolution eSolution = Ttc18Factory.eINSTANCE.createESolution(); + emFeRTrafos.createTopLevelAssignments(eSolution); - int numAssignments = 0; - int numSoftwareSolutions = 0; - int numTotalSoftwareSolutions = 0; + EDataType eString = EcorePackage.eINSTANCE.getEString(); + EObject eObj = null; - stopWatch = StopWatch.start(); + // HashMap<String, Collection<String>> implementation2NodeListMap = emFeRTrafos.computeImplementation2NodeListMap(); - List<Solution> solutions = new ArrayList<>(); + EMFeR emfer = new EMFeR() + .withStart(eSolution) + .withMaxNoOfNewStates(100 * 1000) + .withMetric(root -> -1 * emFeRTrafos.getNumberOfOpenIssues(root)) + .withTrafo("choose implementation", root -> emFeRTrafos.getImplementationChoices(root), (root, impl) -> emFeRTrafos.applyImplementationChoice(root, impl)) + .withTrafo("assign node", root -> emFeRTrafos.getComputeNodeChoices(root), (root, node) -> emFeRTrafos.assignComputeNode(root, node)) + ; - // iterate all possible assignments - // Note, that this only considers assignments of one configuration to each hardware component + int noOfStates = emfer.explore(); + Solution bestSolution = null; + double bestObjective = Double.MAX_VALUE; + int noOfCompleteSolutions = 0; - Solution currentSolution = Solution.createSoftwareSolution(model); + System.out.println("emfer searching for best solution in " + noOfStates); - Solution emferSolution = emFeRTrafos.transform(eSolution); + for (ReachableState state : emfer.getReachabilityGraph().getStates()) + { + ESolution newSolution = (ESolution) state.getRoot(); - boolean valid = emferSolution.isValid(); - // currentSolution = emferSolution; - // currentSolution.trace().process(new LoggerProcessor()); + if (bestSolution == null) + { + bestSolution = emFeRTrafos.transformPartial(newSolution); + } - logger.info("emfer found a solution with an objective of {}.", emferSolution.computeObjective()); + if (emFeRTrafos.getNumberOfOpenIssues(newSolution) == 0) + { + noOfCompleteSolutions ++; + Solution emferSolution = emFeRTrafos.transformPartial(newSolution); - de.tudresden.inf.st.mquat.jastadd.model.List<Resource> resources = model.getHardwareModel().getResources(); + if ( ! emferSolution.isValid()) + { + // System.out.println("solution is invalid: " + newSolution); + continue; + } - boolean hasNextSoftwareAssignment; - do { + double newObjective = emferSolution.computeObjective(); - numTotalSoftwareSolutions++; + // System.out.println("objective " + newObjective + "\n" + newSolution); + if (newObjective < bestObjective) + { + bestSolution = emferSolution; + bestObjective = newObjective; + System.out.println("Found solution with objective: " + bestObjective); + } + } + } - if (currentSolution.isSoftwareValid()) { + if (bestSolution != null) + { + logger.info("emfer found a solution with an objective of {}. Number of complete solutions {} ", bestSolution.computeObjective(), noOfCompleteSolutions ); + } - numSoftwareSolutions++; + lastSolvingTime = stopWatch.time(TimeUnit.MILLISECONDS); - List<Assignment> assignments = currentSolution.allAssignments(); + return bestSolution; + } - // initialize the lists of possible assignments - List<Set<Resource>> possibleResources = new ArrayList<>(assignments.size()); + private boolean isCompleteSolution(ESolution eSolution) + { + for (EAssignment eAssignment : eSolution.getAssignments()) + { + if ( ! isCompleteSolution(eAssignment)) + { + return false; + } + } - for (Assignment assignment : assignments) { - Set<Resource> resourceList = new HashSet<>(); - for (Resource resource : resources) { - // assignResource(assignment, resource); - if (assignment.isValid()) { - resourceList.add(resource); + return true; + } + + private boolean isCompleteSolution(EAssignment eAssignment) + { + if (eAssignment.getImplName() != null && eAssignment.getNodeName() != null) + { + for (EAssignment kid : eAssignment.getAssignments()) + { + if ( ! isCompleteSolution(kid)) + { + return false; } - } - possibleResources.add(resourceList); - } + } - numAssignments += checkAssignment(currentSolution, solutions, assignments, possibleResources, 0, new Stack<>()); + return true; } - - if (stopWatch.time(TimeUnit.MILLISECONDS) > maxSolvingTime) { - this.timedOut = true; - logger.warn("Timeout! Solving terminated!"); - break; + else + { + return false; } - - hasNextSoftwareAssignment = currentSolution.nextSoftwareAssignment(); - } while (hasNextSoftwareAssignment); - - logger.info("Number of total software solutions: {}", numTotalSoftwareSolutions); - logger.info("Number of iterated software solutions: {}", numSoftwareSolutions); - logger.info("Number of iterated solutions: {}", numAssignments); - logger.info("Number of correct solutions: {}", solutionCounter); - - if (solutions.size() > 0) { - lastSolution = solutions.get(solutions.size() - 1); - } else { - lastSolution = Solution.emptySolutionOf(model); - logger.warn("Found no solution!"); - } - - lastSolvingTime = stopWatch.time(TimeUnit.MILLISECONDS); - - return lastSolution; - } - - private void reset() { - this.lastSolution = null; - this.solutionCounter = 0; - this.lastSolvingTime = 0; - this.timedOut = false; - } - - @Override - public String getName() { - return "simple"; - } - - @Override - public long getLastSolvingTime() { - return lastSolvingTime; - } - - @Override - public double getLastObjective() { - if (lastSolution != null) { - return lastSolution.computeObjective(); - } else { - // TODO throw exception or do something reasonable - return 0d; - } - } - - @Override - public Solver setTimeout(long timeoutValue, TimeUnit timeoutUnit) { - this.maxSolvingTime = timeoutUnit.toMillis(timeoutValue); - return this; - } - - @Override - public boolean hadTimeout() { - return this.timedOut; - } + } + + + private void reset() { + this.lastSolution = null; + this.solutionCounter = 0; + this.lastSolvingTime = 0; + this.timedOut = false; + } + + @Override + public String getName() { + return "emfer"; + } + + @Override + public long getLastSolvingTime() { + return lastSolvingTime; + } + + @Override + public double getLastObjective() { + if (lastSolution != null) { + return lastSolution.computeObjective(); + } else { + // TODO throw exception or do something reasonable + return 0d; + } + } + + @Override + public Solver setTimeout(long timeoutValue, TimeUnit timeoutUnit) { + this.maxSolvingTime = timeoutUnit.toMillis(timeoutValue); + return this; + } + + @Override + public boolean hadTimeout() { + return this.timedOut; + } } diff --git a/jastadd-mquat-solver-emfer/src/main/java/uniks/EMFeRTrafos.java b/jastadd-mquat-solver-emfer/src/main/java/uniks/EMFeRTrafos.java index 228b6ffa8fd9eebdcd2a0e4a0a84166e005e8117..13eec82110e5c80b58180f7e2ebe29abab26c410 100644 --- a/jastadd-mquat-solver-emfer/src/main/java/uniks/EMFeRTrafos.java +++ b/jastadd-mquat-solver-emfer/src/main/java/uniks/EMFeRTrafos.java @@ -1,12 +1,15 @@ package uniks; import de.tudresden.inf.st.mquat.jastadd.model.*; +import de.tudresden.inf.st.mquat.jastadd.model.List; import de.tudresden.inf.st.mquat.solving.SolverUtils; +import org.eclipse.emf.ecore.EObject; import uniks.ttc18.EAssignment; +import uniks.ttc18.EChoice; import uniks.ttc18.ESolution; import uniks.ttc18.Ttc18Factory; -import java.util.ArrayList; +import java.util.*; public class EMFeRTrafos { @@ -37,9 +40,9 @@ public class EMFeRTrafos EAssignment topAssignment = Ttc18Factory.eINSTANCE.createEAssignment(); topAssignment.setRequestName(requName); topAssignment.setCompName(targetName.toString()); - String nodeName = model.getHardwareModel().getResource(resourceNum).getName().toString(); - resourceNum++; - topAssignment.setNodeName(nodeName); + // String nodeName = model.getHardwareModel().getResource(resourceNum).getName().toString(); + // resourceNum++; + // topAssignment.setNodeName(nodeName); assignments.add(topAssignment); } } @@ -71,6 +74,100 @@ public class EMFeRTrafos } + + public Solution transformPartial(ESolution eSolution) + { + Solution result = new Solution(); + result.setModel(model); + + // top level + for (EAssignment eAssignment : eSolution.getAssignments()) + { + Assignment dAssignment = new Assignment(); + Request request = findRequest(eAssignment.getRequestName()); + dAssignment.setRequest(request); + dAssignment.setTopLevel(true); + + Component comp = findComp(model, eAssignment.getCompName()); + Implementation implementation = findImplementation(comp, eAssignment.getImplName()); + dAssignment.setImplementation(implementation); + + if (eAssignment.getNodeName() == null) + { + continue; + } + + transformPartialSubAssignments(dAssignment, eAssignment, implementation); + + for (Instance instance : implementation.getResourceRequirement().getInstances()) + { + Resource resource = findResource(eAssignment.getNodeName()); + ResourceMapping resourceMapping = new ResourceMapping(instance, resource, new List<>()); + + SolverUtils.populateResourceMapping(resourceMapping, implementation.getResourceRequirement(), resource); + + dAssignment.setResourceMapping(resourceMapping); + +// if (dAssignment.isValid()) +// { +// System.out.println("assignment is valid " + dAssignment.getImplementation().getName() + " on " + resource.getName()); +// } + } + + result.addAssignment(dAssignment); + } + + return result; + } + + + private void transformPartialSubAssignments(Assignment dAssignment, EAssignment eAssignment, Implementation implementation) + { + for (EAssignment eSubAssignment : eAssignment.getAssignments()) + { + ComponentMapping componentMapping = new ComponentMapping(); + + Assignment dSubAssignment = new Assignment(); + Request request = dAssignment.getRequest(); + dSubAssignment.setRequest(request); + dSubAssignment.setTopLevel(false); + + Component subComp = findComp(model, eSubAssignment.getCompName()); + Implementation subImpl = findImplementation(subComp, eSubAssignment.getImplName()); + + dSubAssignment.setImplementation(subImpl); + + Instance theInstance = findInstance(implementation, "the_" + eSubAssignment.getCompName()); + + componentMapping.setInstance(theInstance); + componentMapping.setAssignment(dSubAssignment); + dAssignment.getComponentMappings().add(componentMapping); + + transformSubAssignments(dSubAssignment, eSubAssignment, subImpl); + + if (eSubAssignment.getNodeName() == null) + { + continue; + } + + for (Instance instance : subImpl.getResourceRequirement().getInstances()) + { + Resource resource = findResource(eSubAssignment.getNodeName()); + ResourceMapping resourceMapping = new ResourceMapping(instance, resource, new List<>()); + SolverUtils.populateResourceMapping(resourceMapping, subImpl.getResourceRequirement(), resource); + dSubAssignment.setResourceMapping(resourceMapping); + + if (dSubAssignment.isValid()) + { + break; + } + } + + } + } + + + ArrayList<Resource> availableResources = null; public Solution transform(ESolution eSolution) @@ -97,6 +194,10 @@ public class EMFeRTrafos Component comp = findComp(model, eAssignment.getCompName()); Implementation implementation = findImplementation(comp, eAssignment.getImplName()); + if (implementation == null) + { + continue; + } dAssignment.setImplementation(implementation); transformSubAssignments(dAssignment, eAssignment, implementation); @@ -139,7 +240,10 @@ public class EMFeRTrafos Component subComp = findComp(model, eSubAssignment.getCompName()); Implementation subImpl = findImplementation(subComp, eSubAssignment.getImplName()); - + if (subImpl == null) + { + continue; + } dSubAssignment.setImplementation(subImpl); for (Instance instance : subImpl.getResourceRequirement().getInstances()) @@ -234,4 +338,335 @@ public class EMFeRTrafos } return null; } + + public Collection<EAssignment> getOpenAssignments(ESolution eSolution) + { + ArrayList<EAssignment> result = new ArrayList<>(); + + for (EAssignment eAssignment : eSolution.getAssignments()) + { + if (eAssignment.getImplName() == null) + { + result.add(eAssignment); + } + + getOpenSubAssignments(eAssignment, result); + } + + return result; + } + + private void getOpenSubAssignments(EAssignment eAssignment, ArrayList<EAssignment> result) + { + for (EAssignment subAssignment : eAssignment.getAssignments()) + { + if (subAssignment.getImplName() == null) + { + result.add(subAssignment); + } + + getOpenSubAssignments(subAssignment, result); + } + } + + public Collection<EObject> getImplementationChoices(EObject root) + { + ArrayList<EObject> result = new ArrayList<>(); + + ESolution eSolution = (ESolution) root; + + for (EAssignment eAssignment : getOpenAssignments(eSolution)) + { + Component comp = findComp(model, eAssignment.getCompName()); + + for (Implementation dImpl : comp.getImplementations()) + { + EChoice eImpl = Ttc18Factory.eINSTANCE.createEChoice(); + eImpl.setAssignment(eAssignment); + eImpl.setResName(dImpl.getName().toString()); + result.add(eImpl); + } + + return result; + } + + return result; + } + + public void applyImplementationChoice(EObject root, EObject handle) + { + EChoice eImpl = (EChoice) handle; + + EAssignment topAssignment = eImpl.getAssignment(); + topAssignment.setImplName(eImpl.getResName()); + + Component comp = findComp(model, topAssignment.getCompName()); + + Implementation dImpl = findImplementation(comp, eImpl.getResName()); + + for (ComponentRequirement componentRequirement : dImpl.getComponentRequirementList()) + { + String kidCompName = componentRequirement.getComponentRef().getRef().getName().toString(); + + EAssignment kidAssignment = Ttc18Factory.eINSTANCE.createEAssignment(); + kidAssignment.setRequestName(topAssignment.getRequestName()); + kidAssignment.setCompName(kidCompName); + + topAssignment.getAssignments().add(kidAssignment); + } + } + + public Collection getComputeNodeChoices(EObject root) + { + ESolution eSolution = (ESolution) root; + ArrayList<EChoice> result = new ArrayList<>(); + + // find assignment that is ready to be deployed + EAssignment eAssignment = getNextUndeployedAssignment(eSolution); + + if (eAssignment == null) + { + return result; + } + + HashSet<String> alreadInUseComputeNodes = getAlreadInUseComputeNodes(eSolution); + + // loop through all compute nodes + for (Resource compNode : model.getHardwareModel().getResourceList()) + { + String compNodeName = compNode.getName().toString(); + +// if (alreadInUseComputeNodes.contains(compNodeName)) +// { +// continue; +// } + + eAssignment.setNodeName(compNodeName); + + // create dSolution + Solution dSolution = transformPartial(eSolution); + + + // if assignment is valid, add choice + boolean allValid = checkAssignments(dSolution); + + if (allValid) + { + EChoice eChoice = Ttc18Factory.eINSTANCE.createEChoice(); + eChoice.setAssignment(eAssignment); + eChoice.setResName(compNodeName); + result.add(eChoice); + +// if (result.size() >= 4) +// { +// break; +// } + } + } + + eAssignment.setNodeName(null); + + if (result.size() == 0) + { + System.out.println("did not find hardware for \n" + eAssignment); + } + + return result; + } + + private boolean checkAssignments(Solution dSolution) + { + for (Assignment dAssignment : dSolution.getAssignmentList()) + { + if (dAssignment.getResource() != null) + { + if (dAssignment.isValid()) + { + // check kids + checkAssignments(dAssignment); + } + else + { + return false; + } + } + } + + return true; + } + + + private boolean checkAssignments(Assignment parent) + { + for (ComponentMapping componentMapping : parent.getComponentMappingList()) + { + Assignment dAssignment = componentMapping.getAssignment(); + + if (dAssignment.getResourceMapping() != null && dAssignment.getResource() != null) + { + if (dAssignment.isValid()) + { + // check kids + checkAssignments(dAssignment); + } + else + { + return false; + } + } + } + + return true; + } + + + private EAssignment getNextUndeployedAssignment(ESolution eSolution) + { + for (EAssignment eAssignment : eSolution.getAssignments()) + { + if ( ! allAssignmentsInTreeHaveAnImplementation(eAssignment)) + { + continue; + } + + if (eAssignment.getNodeName() == null) + { + return eAssignment; + } + + EAssignment kid = getNextUndeployedAssignment(eAssignment); + + if (kid != null) + { + return kid; + } + } + + return null; + } + + private boolean allAssignmentsInTreeHaveAnImplementation(EAssignment eAssignment) + { + if (eAssignment.getImplName() == null) + { + return false; + } + + for (EAssignment kid : eAssignment.getAssignments()) + { + if (! allAssignmentsInTreeHaveAnImplementation(kid)) + { + return false; + } + } + + return true; + } + + private EAssignment getNextUndeployedAssignment(EAssignment eAssignment) + { + for (EAssignment kid : eAssignment.getAssignments()) + { + if (kid.getImplName() == null) + { + continue; + } + + if (kid.getNodeName() == null) + { + return kid; + } + + EAssignment grandKid = getNextUndeployedAssignment(kid); + + if (grandKid != null) + { + return grandKid; + } + } + + return null; + } + + + + private HashSet<String> getAlreadInUseComputeNodes(ESolution eSolution) + { + HashSet<String> result = new HashSet<>(); + + for (EAssignment eAssignment : eSolution.getAssignments()) + { + getAlreadInUseComputeNodes(eAssignment, result); + } + + return result; + } + + + + private void getAlreadInUseComputeNodes(EAssignment eAssignment, Set<String> alreadInUseComputeNodes) + { + if (eAssignment.getNodeName() != null) + { + alreadInUseComputeNodes.add(eAssignment.getNodeName()); + } + + for (EAssignment kidAssignment : eAssignment.getAssignments()) + { + getAlreadInUseComputeNodes(kidAssignment, alreadInUseComputeNodes); + } + } + + private Collection<EAssignment> getNoComputeNodeAssignments(ESolution eSolution) + { + ArrayList<EAssignment> result = new ArrayList<>(); + + for (EAssignment eAssignment : eSolution.getAssignments()) + { + if (eAssignment.getNodeName() == null) + { + result.add(eAssignment); + } + + getOpenSubAssignments(eAssignment, result); + } + + return result; + } + + + + public void assignComputeNode(EObject root, EObject node) + { + EChoice eChoice = (EChoice) node; + eChoice.getAssignment().setNodeName(eChoice.getResName()); + } + + public double getNumberOfOpenIssues(EObject root) + { + ESolution eSolution = (ESolution) root; + + int result = 0; + + for (EAssignment eAssignment : eSolution.getAssignments()) + { + result += getNumberOfAssignmentOpenIssues(eAssignment); + } + + return result; + } + + private int getNumberOfAssignmentOpenIssues(EAssignment eAssignment) + { + int result = 0; + if (eAssignment.getImplName() == null) result++; + if (eAssignment.getNodeName() == null) result++; + + for (EAssignment kid : eAssignment.getAssignments()) + { + result += getNumberOfAssignmentOpenIssues(kid); + } + + return result; + } } diff --git a/jastadd-mquat-solver-emfer/src/test/java/de/tudresden/inf/st/mquat/solving/EMFeRSolverTest.java b/jastadd-mquat-solver-emfer/src/test/java/de/tudresden/inf/st/mquat/solving/EMFeRSolverTest.java index d953849a6efcfc90366a63bb4835925fdc6780a3..9d21b6842e2ef79f5f1b74de6f408c5229ca626a 100644 --- a/jastadd-mquat-solver-emfer/src/test/java/de/tudresden/inf/st/mquat/solving/EMFeRSolverTest.java +++ b/jastadd-mquat-solver-emfer/src/test/java/de/tudresden/inf/st/mquat/solving/EMFeRSolverTest.java @@ -40,11 +40,12 @@ public class EMFeRSolverTest { int nfp = 0; int req = 3; int cpu = 1; - int seed = 0; + int seed = 1; ScenarioGenerator generator = new ScenarioGenerator(new ScenarioDescription(tlc, iac, isd, cac, csd, dep, imp, res, req, cpu, seed)); Root model = generator.generate(); + EMFeRSolver solver = new EMFeRSolver(20000); Solution solution = solver.solve(model); diff --git a/jastadd-mquat-solver-simple/src/test/java/de/tudresden/inf/st/mquat/solving/SimpleSolverTest.java b/jastadd-mquat-solver-simple/src/test/java/de/tudresden/inf/st/mquat/solving/SimpleSolverTest.java index 7647d3e01efa490e23754e80ac4097ce18947842..572b2539b81015fe8c77e6ea1a2bc55d01ea3c98 100644 --- a/jastadd-mquat-solver-simple/src/test/java/de/tudresden/inf/st/mquat/solving/SimpleSolverTest.java +++ b/jastadd-mquat-solver-simple/src/test/java/de/tudresden/inf/st/mquat/solving/SimpleSolverTest.java @@ -37,7 +37,7 @@ public class SimpleSolverTest { int nfp = 0; int req = 3; int cpu = 1; - int seed = 0; + int seed = 1; ScenarioGenerator generator = new ScenarioGenerator(new ScenarioDescription(tlc, iac, isd, cac, csd, dep, imp, res, req, cpu, seed)); diff --git a/settings.gradle b/settings.gradle index e6ec605b4b6a0cfc2bf60b28f153b9c9ee023035..fcba86cf70b92028702f540a33c9b8477b3033b9 100644 --- a/settings.gradle +++ b/settings.gradle @@ -4,7 +4,6 @@ include ':jastadd-mquat-base' include ':jastadd-mquat-benchmark' include ':jastadd-mquat-solver' include ':jastadd-mquat-solver-ilp' -include ':jastadd-mquat-solver-simple' include ':jastadd-mquat-solver-emfer' -include 'jastadd-mquat-solver-emfer' +include ':jastadd-mquat-solver-simple'