Commit c50c18d5 authored by eisenmann's avatar eisenmann

Updated generation

Issue-Ref: 4009
Issue-Url: https://af3-developer.fortiss.org/issues/4009Signed-off-by: Martin Eisenmann's avatarEisenmann <eisenmann@fortiss.org>
parent d13e4981
......@@ -21,9 +21,6 @@ Require-Bundle: org.fortiss.af3.exploration,
Export-Package: org.fortiss.af3.exploration.ga.backend,
org.fortiss.af3.exploration.ilp.backend,
org.fortiss.af3.exploration.smt.backend,
org.fortiss.af3.exploration.smt.model,
org.fortiss.af3.exploration.smt.model.impl,
org.fortiss.af3.exploration.smt.model.util,
org.fortiss.af3.exploration.smt.modeltransformation,
org.fortiss.af3.exploration.smt.util,
test.org.fortiss.af3.exploration.smt
......@@ -32,4 +32,6 @@ public interface ISolver {
public void cleanup();
public double getLastExecutionTime();
public double getFirstSolTime();
}
......@@ -32,6 +32,7 @@ import java.util.function.Function;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.jobs.Job;
import org.fortiss.af3.exploration.AF3ExplorationActivator;
import org.fortiss.af3.exploration.ISolver;
import org.fortiss.af3.exploration.dseml.model.arithmetic.ArithmeticLiteral;
......@@ -64,6 +65,7 @@ import org.fortiss.af3.platform.model.ExecutionUnit;
import org.fortiss.af3.task.model.Task;
import org.fortiss.tooling.base.model.element.IModelElement;
import ilog.concert.IloException;
import io.jenetics.Genotype;
import io.jenetics.IntegerGene;
import io.jenetics.Phenotype;
......@@ -275,6 +277,11 @@ public class SolverGA implements ISolver {
return lastExecutionTime;
}
@Override
public double getFirstSolTime() {
return lastExecutionTime;
}
private void solveOptimized(int numberOfRuns, IProgressMonitor monitor,
ExplorationSolution expSolution) {
JeneticsCancelThread gaCancelThread = null;
......
......@@ -38,6 +38,7 @@ import java.util.Map.Entry;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.emf.common.util.EList;
import org.fortiss.af3.exploration.AF3ExplorationActivator;
import org.fortiss.af3.exploration.ISolver;
......@@ -50,6 +51,7 @@ import org.fortiss.af3.exploration.model.ExplorationSpecification;
import org.fortiss.af3.exploration.model.IExplorationConstraint;
import org.fortiss.af3.exploration.model.IExplorationObjective;
import org.fortiss.af3.exploration.model.IExplorationTarget;
import org.fortiss.af3.exploration.model.project.RuleSet;
import org.fortiss.af3.exploration.model.solutions.ExplorationResult;
import org.fortiss.af3.exploration.model.solutions.ExplorationSolution;
import org.fortiss.af3.exploration.model.solutions.SingleExplorationSolution;
......@@ -88,6 +90,8 @@ public class SolverILP implements ISolver {
private double lastExecutionTime;
private double firstsolTime;
/**
* Thread used to poll {@link IProgressMonitor} provided by the Eclipse {@link Job} running the
* CPLEX solver for cancel requests.
......@@ -246,10 +250,15 @@ public class SolverILP implements ISolver {
return lastExecutionTime;
}
@Override
public double getFirstSolTime() {
return firstsolTime;
}
private boolean solveOptimized(int numberOfRuns, IProgressMonitor monitor,
ExplorationSolution expSolution) throws IloException, UnknownObjectException {
lastExecutionTime = 0.0;
for(int i = 0; i < numberOfRuns; i++) {
lastExecutionTime = 0.0;
CPLEXCancelThread ilpCancelThread = null;
if(monitor != null) {
ilpCancelThread = new CPLEXCancelThread(cplex, monitor);
......@@ -263,6 +272,9 @@ public class SolverILP implements ISolver {
long start = System.nanoTime();
boolean solve = cplex.solve();
lastExecutionTime += (System.nanoTime() - start) / 1e6;
if(i == 0) {
firstsolTime = (System.nanoTime() - start) / 1e6;
}
if(ilpCancelThread != null && ilpCancelThread.requestStop()) {
return false;
......@@ -368,7 +380,7 @@ public class SolverILP implements ISolver {
for(Entry<IExplorationObjective<?>, IloNumExpr> entry : objectiveMapping.entrySet()) {
@SuppressWarnings("unchecked") Class<Number> expectedType =
(Class<Number>)entry.getKey().getResultType();
Number value = cplex.getValue(entry.getValue());
Number value = Double.valueOf(Math.round(cplex.getValue(entry.getValue())));
ExplorationResult<Number> result = createExplorationResult(expectedType, value);
@SuppressWarnings("unchecked") IExplorationObjective<Number> castedObjective =
(IExplorationObjective<Number>)entry.getKey();
......
......@@ -145,8 +145,10 @@ public class BasicDeploymentConstraint {
// forall ((s SignalImpl)), forall ((r RouteImpl))
ForAll forAllCH = createForAll();
forAllCH.setUnfold(true);
forAllCH.setSet(channels.getCastedSet(IModelElement.class));
ForAll forAllRoutes = createForAll();
forAllRoutes.setUnfold(true);
forAllRoutes.setSet(routeSet.getCastedSet(IModelElement.class));
forAllCH.setExpression(forAllRoutes);
......
......@@ -18,7 +18,6 @@ package org.fortiss.af3.exploration.smt.modeltransformation;
import static com.microsoft.z3.Z3javaAPIWrapper.createBoolConst;
import static com.microsoft.z3.Z3javaAPIWrapper.createOptimize;
import static java.lang.System.currentTimeMillis;
import static org.eclipse.core.runtime.Assert.isTrue;
import static org.eclipse.core.runtime.Platform.getLocation;
import static org.fortiss.af3.exploration.model.solutions.SolutionState.OPTIMAL;
import static org.fortiss.af3.exploration.model.solutions.SolutionState.OPTIMIZED;
......@@ -50,11 +49,13 @@ import java.util.HashSet;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TimerTask;
import javax.activation.UnsupportedDataTypeException;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.emf.common.util.EList;
import org.fortiss.af3.exploration.AF3ExplorationActivator;
import org.fortiss.af3.exploration.ISolver;
......@@ -62,9 +63,11 @@ import org.fortiss.af3.exploration.dseml.model.expression.SuperSet;
import org.fortiss.af3.exploration.model.ExplorationSpecification;
import org.fortiss.af3.exploration.model.IExplorationConstraint;
import org.fortiss.af3.exploration.model.IExplorationObjective;
import org.fortiss.af3.exploration.model.project.RuleSet;
import org.fortiss.af3.exploration.model.solutions.ExplorationResult;
import org.fortiss.af3.exploration.model.solutions.ExplorationSolution;
import org.fortiss.af3.exploration.model.solutions.SingleExplorationSolution;
import org.fortiss.af3.exploration.util.ExplorationUtils;
import org.fortiss.tooling.base.model.element.IModelElement;
import com.microsoft.z3.ArithExpr;
......@@ -156,6 +159,8 @@ public abstract class SolverRun implements ISolver {
private double lastExecutionTime;
private double firstSolTime;
/** Constructor. */
public SolverRun(final String solutionNamePrefix) {
this.solutionNamePrefix = solutionNamePrefix;
......@@ -206,15 +211,15 @@ public abstract class SolverRun implements ISolver {
return expSolution;
}
if(expSolution.getSolutionState() == UNSAT) {
// Problem is not solvable: Dump UnSAT core for user aid.
parameters.put("unsat_core", "true");
try(Context context2 = new Context(parameters)) {
transformation = new DSMLtoSMTTransformator(context2);
transformation.transform(explorationSpec);
solveNonOptimized(context2, parameters, transformation, expSolution, monitor);
}
}
// if(expSolution.getSolutionState() == UNSAT) {
// // Problem is not solvable: Dump UnSAT core for user aid.
// parameters.put("unsat_core", "true");
// try(Context context2 = new Context(parameters)) {
// transformation = new DSMLtoSMTTransformator(context2);
// transformation.transform(explorationSpec);
// solveNonOptimized(context2, parameters, transformation, expSolution, monitor);
// }
// }
} catch(Z3Exception e) {
error(getDefault(), "[Z3] " + e.getMessage(), e);
} finally {
......@@ -235,6 +240,11 @@ public abstract class SolverRun implements ISolver {
return lastExecutionTime;
}
@Override
public double getFirstSolTime() {
return firstSolTime;
}
/**
* Extracts the failed constraints from the provided UNSAT cores and stores them in
* the given {@link ExplorationSolution}.
......@@ -350,8 +360,19 @@ public abstract class SolverRun implements ISolver {
logZ3info(("\n SMT Problem: \n" + (solver.toString())));
Map<Expr, IExplorationObjective<?>> objectiveMapping = transformation.getObjectiveMapping();
lastExecutionTime = 0;
boolean cnt = false;
java.util.Timer timeoutTimer = new java.util.Timer();
timeoutTimer.schedule(new TimerTask() {
@Override
public void run() {
context.interrupt();
System.out.println("Interrupted");
}
}, timeout);
lastExecutionTime = 0;
for(int i = 0; i < numberOfRuns || cnt; ++i) {
Z3CancelThread z3CancelThread =
monitor != null ? new Z3CancelThread(context, monitor) : null;
......@@ -368,6 +389,9 @@ public abstract class SolverRun implements ISolver {
long start = System.nanoTime();
Status check = solver.Check();
lastExecutionTime += (System.nanoTime() - start) / 1e6;
if(i == 0) {
firstSolTime = (System.nanoTime() - start) / 1e6;
}
if(z3CancelThread != null && z3CancelThread.requestStop()) {
return false;
......@@ -391,15 +415,17 @@ public abstract class SolverRun implements ISolver {
if(monitor != null) {
monitor.worked(1);
}
cnt = false;
continue;
}
cnt = true;
if(check.equals(Status.UNKNOWN)) {
break;
} else if(check.equals(Status.UNKNOWN)) {
singleSolution.setSolutionState(OPTIMIZED);
} else {
singleSolution.setSolutionState(OPTIMAL);
System.out.println("Timeout reached");
if(expSolution.getSolutions().size() > 0) {
System.out.println("Some solutions found");
}
break;
}
singleSolution.setSolutionState(OPTIMAL);
cnt = true;
Model model = solver.getModel();
logZ3info("\n SMT Model: \n" + model);
......@@ -420,6 +446,8 @@ public abstract class SolverRun implements ISolver {
}
}
timeoutTimer.cancel();
updateExplorationSolutionState(expSolution);
return true;
......@@ -437,7 +465,8 @@ public abstract class SolverRun implements ISolver {
return;
}
if(solutions.stream().anyMatch(s -> s.getSolutionState() == OPTIMIZED)) {
if(expSolution.getSolutionState() == OPTIMIZED ||
solutions.stream().anyMatch(s -> s.getSolutionState() == OPTIMIZED)) {
expSolution.setSolutionState(OPTIMIZED);
return;
}
......@@ -449,7 +478,7 @@ public abstract class SolverRun implements ISolver {
}
// UNSAT state is preserved if no solution model was returned.
isTrue(expSolution.getSolutionState() == UNSAT);
// isTrue(expSolution.getSolutionState() == UNSAT);
}
/**
......
......@@ -78,12 +78,12 @@ public class PerformanceTest {
@Parameters
public static Collection<Object[]> testProjects() {
String projects = "DSE_Generated-.*_[0-9]?[0-9].af3_23";
String projects = "DSE_Generated-.*_[0-9]?[0-9]?[0-9].af3_23";
return Arrays.asList(new Object[][] {
// @CodeFormatterOff
// {projects, new TestSMTPareto(), 1},
// {projects, new TestSMTLex(), 1},
{projects, new TestSMTPareto(), 1},
{projects, new TestILP(), 1},
// {projects, new TestSMTLex(), 1},
{projects, new TestGA(), 1}
// @CodeFormatterOn
});
......
......@@ -37,7 +37,7 @@ import test.org.fortiss.af3.exploration.smt.suite.testruns.TestRun;
abstract public class TestProcedure {
/** SMT timeout in ms. */
protected int SMT_TIMEOUT_MS = 1200000;
protected int SMT_TIMEOUT_MS = 14400000;
/** Name of the test project to load. */
protected String testProject;
......
......@@ -79,12 +79,13 @@ public abstract class TimingTestProcedure extends TestProcedure {
ExplorationSolution explorationSolution =
solver.solve(explorationSpecification, SMT_TIMEOUT_MS, new NullProgressMonitor());
double deltaTime = solver.getLastExecutionTime();
double firstTime = solver.getFirstSolTime();
deleteDuplicates(explorationSolution);
String[] split = testProject.split("\\|");
ResultLogger.logSolution(split[0], split[1], solver.getClass().getSimpleName(), currentRun,
explorationSolution, deltaTime);
explorationSolution, deltaTime, firstTime);
solver.cleanup();
......@@ -94,21 +95,50 @@ public abstract class TimingTestProcedure extends TestProcedure {
private void deleteDuplicates(ExplorationSolution sol) {
LinkedList<SingleExplorationSolution> existingSols =
new LinkedList<SingleExplorationSolution>();
existingSols.addAll(sol.getSolutions());
for(int i = sol.getSolutions().size() - 1; i >= 0; i--) {
SingleExplorationSolution ses = sol.getSolutions().get(i);
boolean contained = false;
boolean solDominated = false;
for(SingleExplorationSolution ses2 : existingSols) {
boolean dominated = false;
boolean notDominated = false;
for(IExplorationTarget<?> key : ses.keySet()) {
if(((Double)ses.get(key).getResult()) > ((Double)ses2.get(key).getResult())) {
dominated = true;
} else if(((Double)ses.get(key).getResult()) < ((Double)ses2.get(key)
.getResult())) {
notDominated = true;
}
}
if(dominated && !notDominated) {
solDominated = true;
}
}
if(solDominated) {
sol.getSolutions().remove(i);
}
}
existingSols.clear();
for(int i = sol.getSolutions().size() - 1; i >= 0; i--) {
SingleExplorationSolution ses = sol.getSolutions().get(i);
boolean solEqual = false;
for(SingleExplorationSolution ses2 : existingSols) {
boolean equal = true;
for(IExplorationTarget<?> key : ses.keySet()) {
equal &= ((Number)ses.get(key).getResult())
.doubleValue() >= ((Number)ses2.get(key).getResult()).doubleValue();
if(((Double)ses.get(key).getResult())
.doubleValue() != ((Double)ses2.get(key).getResult()).doubleValue()) {
equal = false;
}
}
if(equal) {
solEqual = true;
}
contained |= equal;
}
if(contained) {
if(solEqual) {
sol.getSolutions().remove(i);
} else {
existingSols.add(ses);
existingSols.add(sol.getSolutions().get(i));
}
}
}
......
......@@ -72,21 +72,22 @@ public class ResultLogger {
}
private void _logSolution(String project, String comment, String solver, int run,
ExplorationSolution sol, double time) {
ExplorationSolution sol, double time, double firstTime) {
if(!initDone) {
info(getDefault(), this.getClass().getSimpleName() + " not initialized");
return;
}
try {
logWriter.write(String.join(",", project.replace("-", ",").replace(".af3_23", ""),
comment, solver, Integer.toString(run), Double.toString(time),
sol.getSolutionState().toString(), Integer.toString(sol.getSolutions().size()),
sol.getSolutions().stream()
.map(sl -> sl.keySet().stream()
logWriter
.write(String.join(",", project.replace("-", ",").replace(".af3_23", ""),
comment, solver, Integer.toString(run), Double.toString(time),
Double.toString(firstTime), sol.getSolutionState().toString(),
Integer.toString(sol.getSolutions().size()),
sol.getSolutions().stream().map(sl -> sl.keySet().stream()
.map(k -> k.getName() + ":" + sl.get(k).getResult().toString())
.collect(Collectors.joining("-")))
.collect(Collectors.joining("|"))) +
"\n");
.collect(Collectors.joining("|"))) +
"\n");
} catch(IOException e) {
error(getDefault(), e.getMessage());
}
......@@ -100,7 +101,7 @@ public class ResultLogger {
instance = new ResultLogger();
try {
instance.logWriter.write(
"Project,Platform_Architecture,Component_Architecture,Comment,Solver,Run,Time,SolutionState,SolutionSize,Solutions\n");
"Project,Platform_Architecture,Component_Architecture,Comment,Solver,Run,Time,TimeToFirst,SolutionState,SolutionSize,Solutions\n");
} catch(IOException e) {
error(getDefault(), e.getMessage());
}
......@@ -111,8 +112,8 @@ public class ResultLogger {
}
public static void logSolution(String project, String comment, String solver, int run,
ExplorationSolution sol, double time) {
instance._logSolution(project, comment, solver, run, sol, time);
ExplorationSolution sol, double time, double firstTime) {
instance._logSolution(project, comment, solver, run, sol, time, firstTime);
}
}
......@@ -17,7 +17,6 @@ package org.fortiss.af3.exploration.testgenerator;
import static org.fortiss.af3.exploration.testgenerator.util.AnnotationGenerationUtils.expandArchitecturesByAnnotations;
import static org.fortiss.af3.exploration.testgenerator.util.CompArchGeneratonUtil.generateLogicalArchitectures;
import static org.fortiss.af3.exploration.testgenerator.util.DseUtils.expandByDseProblems;
import static org.fortiss.af3.exploration.testgenerator.util.FileWriterUtil.write;
import static org.fortiss.af3.exploration.testgenerator.util.GraphMetricUtils.getGraphMetrics;
import static org.fortiss.af3.exploration.testgenerator.util.ProjectUtils.createAF3Projects;
......@@ -29,6 +28,7 @@ import static org.fortiss.tooling.kernel.utils.EcoreUtils.copy;
import static org.fortiss.tooling.kernel.utils.EcoreUtils.pickInstanceOf;
import static org.fortiss.tooling.kernel.utils.LoggingUtils.info;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
......@@ -57,6 +57,8 @@ import org.fortiss.tooling.kernel.utils.UniqueIDUtils;
*/
public class ExplorationTestCaseGenerator {
public static final boolean GENERATE = true;
/**
* Generates a set of {@link FileProject}s in the workspace that contain a deployment problem
* for the DSE.
......@@ -73,27 +75,46 @@ public class ExplorationTestCaseGenerator {
Collection<PlatformArchitecture> platformArchitectures =
copy(pickInstanceOf(PlatformArchitecture.class, templateProject.getRootElements()));
// List<String> toIgnore =
// Arrays.asList(new String[] {"CommonBus_24", "Star_24", "MultiStar_24_6"});
//
// platformArchitectures.removeIf(pa -> toIgnore.contains(pa.getName()));
List<String> toIgnore = Arrays.asList(new String[] {
/*
* "Staggered_3_2_3", "Staggered_4_2_4_2_4", "CommonBus_8", "Star_8",
* "MultiStar_8_2", "CommonBus_16", "Star_16", "MultiStar_16_4",
*/ "CommonBus_24", "Star_24", "MultiStar_24_6"});
platformArchitectures.removeIf(pa -> toIgnore.contains(pa.getName()));
// Generate component Architectures
Collection<ComponentArchitecture> genCompArchs =
generateLogicalArchitectures(compArchNum, minComponentNum, maxComponentNum);
Collection<ComponentArchitecture> genCompArchs;
if(GENERATE) {
genCompArchs =
generateLogicalArchitectures(compArchNum, minComponentNum, maxComponentNum);
} else {
genCompArchs = copy(
pickInstanceOf(ComponentArchitecture.class, templateProject.getRootElements()));
}
if(isDumpTestgenGraphmetricsEnabled()) {
dumpGraphMetrics(genCompArchs);
}
Collection<FileProject> fileProjects =
createAF3Projects(genCompArchs, platformArchitectures, "DSE_Generated");
fileProjects = expandArchitecturesByAnnotations(fileProjects);
Collection<FileProject> fileProjects;
if(!GENERATE) {
Collection<TaskArchitecture> taskArchs =
copy(pickInstanceOf(TaskArchitecture.class, templateProject.getRootElements()));
fileProjects = createAF3Projects(genCompArchs, platformArchitectures, taskArchs,
"DSE_Generated");
} else {
fileProjects = createAF3Projects(genCompArchs, platformArchitectures, "DSE_Generated");
}
if(GENERATE) {
fileProjects = expandArchitecturesByAnnotations(fileProjects);
}
for(FileProject fp : fileProjects) {
UniqueIDUtils.generateAllIDs(fp);
}
fileProjects = expandByDseProblems(fileProjects);
// fileProjects = DseUtils.expandByDseProblems(fileProjects);
info(AF3ExplorationActivator.getDefault(),
"Test cases are generated in the runtime Workspace.");
......
......@@ -93,6 +93,8 @@ public class AnnotationGenerationUtils {
/** Possible values for the annotations */
private final static Integer[] ANNOTATION_AMOUNT = {70, 85, 100, 115, 130};
public final static int CENTER_SCALE_FACTOR = 5;
private static int getRandomAnnotation(double e, double var) {
return Math.max(0, Math.min(ANNOTATION_AMOUNT.length - 1,
(int)Math.round(e + var * new Random().nextDouble())));
......@@ -111,51 +113,63 @@ public class AnnotationGenerationUtils {
/** Sets the values of {@link HardwareCost} annotations. */
private static Collection<FileProject> defineCost(Collection<FileProject> fileProjects) {
return defineAnnotation(fileProjects, HardwareCost.class,
Collection<FileProject> fps = defineAnnotation(fileProjects, HardwareCost.class,
val -> (cost -> cost.setCost(val)), 1);
for(FileProject fp : fps) {
PlatformArchitecture platArch =
pickFirstInstanceOf(PlatformArchitecture.class, fp.getRootElements());
List<GenericExecutionUnit> ecus =
getChildrenWithType(platArch, GenericExecutionUnit.class);
for(GenericExecutionUnit ecu : ecus) {
if(ecu.getName().contains("Center")) {
int cost = getAnnotationValue(ecu, HardwareCost.class, Integer.class);
try {
setAnnotationValue(ecu, HardwareCost.class, cost * CENTER_SCALE_FACTOR);
} catch(Exception e) {
e.printStackTrace();
}
}
}
}
return fps;
}
/** Sets the values of {@link HardwareCost} annotations. */
private static Collection<FileProject>
definePowerConsumption(Collection<FileProject> fileProjects) {
return defineAnnotation(fileProjects, PowerConsumption.class,
Collection<FileProject> fps = defineAnnotation(fileProjects, PowerConsumption.class,
val -> (power -> power.setPower(val)), 1);
}
/** Sets the values of {@link RamSize} annotations. */
private static Collection<FileProject> defineFlashAndRAM(Collection<FileProject> fileProjects) {
int variations = 1;
Random rand = new Random();
Collection<FileProject> expandedProjects = new ArrayList<>();
for(FileProject origProject : fileProjects) {
for(int i = 0; i < variations; i++) {
FileProject project = copy(origProject);
PlatformArchitecture platArch =
pickFirstInstanceOf(PlatformArchitecture.class, project.getRootElements());
List<GenericExecutionUnit> types =
getChildrenWithType(platArch, GenericExecutionUnit.class);
types.forEach(ecu -> {
int costIndex = Arrays.binarySearch(ANNOTATION_AMOUNT,
getAnnotationValue(ecu, HardwareCost.class, Integer.class));
int powerIndex = Arrays.binarySearch(ANNOTATION_AMOUNT,
getAnnotationValue(ecu, PowerConsumption.class, Integer.class));
int index = (int)Math.round(2 * (costIndex + 3 * powerIndex) / 4.0);
double share = 0.5 + (rand.nextDouble() / 4);
getAnnotation(ecu, FlashSize.class)