diff --git a/trainbenchmark/trainbenchmark-alternate-scripts/build.gradle b/trainbenchmark/trainbenchmark-alternate-scripts/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..fc879099b2d9c4ca1b83fd0cc48db6657cce75ad
--- /dev/null
+++ b/trainbenchmark/trainbenchmark-alternate-scripts/build.gradle
@@ -0,0 +1,83 @@
+dependencies {
+ compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.2.3'
+ compile group: 'com.fasterxml.jackson.dataformat', name: 'jackson-dataformat-yaml', version: '2.3.0'
+
+ compile project(':trainbenchmark-generator')
+ compile project(':trainbenchmark-generator-emf')
+ compile project(':trainbenchmark-generator-graph-tinkerpop')
+ compile project(':trainbenchmark-generator-json4ag')
+ compile project(':trainbenchmark-generator-dot')
+ compile project(':trainbenchmark-tool')
+ compile project(':trainbenchmark-tool-jastadd-base')
+ compile project(':trainbenchmark-tool-jastadd-namelookup')
+ compile project(':trainbenchmark-tool-jastadd-namelookup-base')
+ compile project(':trainbenchmark-tool-jastadd-namelookup-incremental')
+ compile project(':trainbenchmark-tool-jastadd-optimized')
+ compile project(':trainbenchmark-tool-jastadd-optimized-base')
+ compile project(':trainbenchmark-tool-jastadd-optimized-incremental')
+// compile project(':trainbenchmark-tool-jastadd-specialized')
+// compile project(':trainbenchmark-tool-jastadd-specialized-base')
+// compile project(':trainbenchmark-tool-jastadd-specialized-incremental')
+// compile project(':trainbenchmark-tool-jastadd-relast')
+// compile project(':trainbenchmark-tool-jastadd-relast-incremental')
+ compile project(':trainbenchmark-tool-tinkergraph')
+ compile project(':trainbenchmark-tool-viatra')
+}
+
+task cleanResults(type: Delete) {
+ doLast {
+ def resultDir = "../results"
+ file(resultDir).eachDir{ dir ->
+ delete "${dir}"
+ }
+ }
+}
+
+task combinedBenchmark(dependsOn: 'classes', type: JavaExec) {
+ group = 'Benchmark'
+ description = 'Runs the \'classic\' TrainBenchmark script'
+ main = 'de.tudresden.inf.st.train.scripts.BenchmarkMain'
+ classpath = sourceSets.main.runtimeClasspath
+ args 'combined'
+}
+
+task individualRepairBenchmark(dependsOn: 'classes', type: JavaExec) {
+ group = 'Benchmark'
+ main = 'de.tudresden.inf.st.train.scripts.BenchmarkMain'
+ classpath = sourceSets.main.runtimeClasspath
+ args 'individual_repair'
+}
+
+task individualInjectBenchmark(dependsOn: 'classes', type: JavaExec) {
+ group = 'Benchmark'
+ main = 'de.tudresden.inf.st.train.scripts.BenchmarkMain'
+ classpath = sourceSets.main.runtimeClasspath
+ args 'individual_inject'
+}
+
+task individualIncrementalBenchmark(dependsOn: 'classes', type: JavaExec) {
+ group = 'Benchmark'
+ main = 'de.tudresden.inf.st.train.scripts.BenchmarkMain'
+ classpath = sourceSets.main.runtimeClasspath
+ args 'individual_incremental'
+}
+
+
+task generate(dependsOn: 'classes', type: JavaExec) {
+ group = 'Benchmark'
+ description = 'Generates the models for all benchmarks'
+ main = 'de.tudresden.inf.st.train.scripts.GenerateMain'
+ classpath = sourceSets.main.runtimeClasspath
+}
+
+//task memory(dependsOn: 'classes', type: JavaExec) {
+// group = 'Benchmark'
+// main = 'MemoryScript'
+// classpath = sourceSets.main.runtimeClasspath
+//}
+//
+//task qpt(dependsOn: 'classes', type: JavaExec) {
+// group = 'Benchmark'
+// main = 'QueryPlanTester'
+// classpath = sourceSets.main.runtimeClasspath
+//}
diff --git a/trainbenchmark/trainbenchmark-alternate-scripts/src/main/java/de/tudresden/inf/st/train/scripts/BenchmarkMain.java b/trainbenchmark/trainbenchmark-alternate-scripts/src/main/java/de/tudresden/inf/st/train/scripts/BenchmarkMain.java
new file mode 100644
index 0000000000000000000000000000000000000000..c5dca00cfa62bd4fec9cd314ef0672b37949e1a8
--- /dev/null
+++ b/trainbenchmark/trainbenchmark-alternate-scripts/src/main/java/de/tudresden/inf/st/train/scripts/BenchmarkMain.java
@@ -0,0 +1,144 @@
+package de.tudresden.inf.st.train.scripts;
+
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import hu.bme.mit.trainbenchmark.benchmark.config.*;
+import hu.bme.mit.trainbenchmark.benchmark.result.ResultHelper;
+import hu.bme.mit.trainbenchmark.benchmark.runcomponents.BenchmarkRunner;
+import hu.bme.mit.trainbenchmark.config.ExecutionConfig;
+import hu.bme.mit.trainbenchmark.constants.RailwayOperation;
+
+import java.io.IOException;
+import java.util.*;
+
+/**
+ * Main entry point to start benchmarks.
+ * Created by rschoene on 10/12/17.
+ */
+public class BenchmarkMain {
+
+ @SuppressWarnings("unchecked")
+ private static void runBenchmarkSeries(BenchmarkConfigBaseBuilder configBaseBuilder, BenchmarkConfigBuilder configBuilder,
+ ExecutionConfig ec, ModelSetConfig modelSetConfig, BenchmarkSettingsBasics bbs) {
+ Map<String, String> jvmSettingsMap = Utils.createJvmSettingsMap(bbs);
+ String jvmDefaultSettings = jvmSettingsMap.getOrDefault("*",
+ "-Xms{Xms} -Xmx{Xmx} -server -Xverify:none");
+ try {
+ for (int size = modelSetConfig.getMinSize(); size <= modelSetConfig.getMaxSize(); size *= 2) {
+ String modelFilename = "railway-" + modelSetConfig.getModelVariant() + "-" + size;
+
+ System.out.println("------------------------------------------------------------");
+ System.out.println("Model: " + modelFilename);
+ System.out.println("------------------------------------------------------------");
+
+ configBaseBuilder.setModelFilename(modelFilename);
+ BenchmarkConfigBase configBase = configBaseBuilder.createConfigBase();
+ BenchmarkConfig config = (BenchmarkConfig) configBuilder.setConfigBase(configBase).createConfig();
+
+ if (!bbs.isDryRun()) {
+ ResultHelper.prepare(config, ec);
+ }
+ String jvmSetting = jvmSettingsMap.getOrDefault(config.getToolName(), jvmDefaultSettings);
+
+ int exitValue = BenchmarkRunner.runPerformanceBenchmark(config, ec, jvmSetting);
+ if (exitValue != 0) {
+ System.out.println("Timeout or error occurred, skipping models for larger sizes. Error code: " + exitValue);
+ break;
+ }
+ }
+ } catch (InterruptedException | IOException e) {
+ System.out.println("Exception occurred during execution.");
+ e.printStackTrace();
+ }
+ }
+
+ public static void main(String args[]) throws Exception {
+ // set benchmark variant from program arguments
+ if (args.length == 0) {
+ System.err.println("Need to specify one argument identifying the benchmark variant");
+ System.exit(1);
+ }
+ String benchmarkVariant = args[0];
+
+ // read basic settings (min, maxsize, etc.)
+ ObjectMapper mapper = Utils.getMapper();
+ BenchmarkSettingsBasics bbs = Utils.readFromResource(mapper, "basic-settings.json",
+ BenchmarkSettingsBasics.class);
+ try {
+ BenchmarkSettingsBasics loca_bbs = Utils.readFromResource(mapper, "local-basic-settings.json",
+ BenchmarkSettingsBasics.class);
+ Utils.updateBasicsWithLocal(bbs, loca_bbs);
+ } catch (IOException e) {
+ System.out.println("No file 'local-basic-settings.json' found. Using default!");
+ }
+
+ // import tools to use
+ List<BenchmarkConfigBuilder<? extends BenchmarkConfig, ? extends BenchmarkConfigBuilder<?, ?>>> builders =
+ BenchmarkSettingsAvailableTools.getBuilders(bbs.getTools());
+ System.out.println(builders);
+
+ // read workloads based on benchmark variant
+ String workloadsFilename = "workloads.json";
+ BenchmarkSettingsVariantWorkloads bsvw = Utils.readFromResource(mapper, workloadsFilename,
+ BenchmarkSettingsVariantWorkloads.class);
+
+ Optional<BenchmarkSettingsWorkloads> workloadsOpt = bsvw.getVariants().stream()
+ .filter(w -> w.getName().equals(benchmarkVariant))
+ .findFirst();
+ if (!workloadsOpt.isPresent()) {
+ System.err.println("Could not find workloads for given variant, check " + workloadsFilename
+ + " and argument " + benchmarkVariant);
+ System.exit(4);
+ }
+ BenchmarkSettingsWorkloads workloads = workloadsOpt.get();
+
+ // start benchmark
+ String now = ResultHelper.getNow();
+ ExecutionConfig ec = new ExecutionConfig(4000, 8000, bbs.isDryRun());
+
+ System.out.println("Please remember to stop all other Java processes.");
+ System.out.println();
+ System.out.println("If in doubt, check with this command:");
+ System.out.println("$ ps auxw | grep jav[a]");
+ System.out.println();
+ System.out.println("If there are other Java processes, use:");
+ System.out.println("$ killall -9 java");
+ System.out.println();
+ System.out.println("############################################################");
+ System.out.println("Benchmark parameters:");
+ System.out.println("- execution config: " + ec);
+ System.out.println(bbs);
+// System.out.println("- range: minSize=" + bbs.getMinSize() +", maxSize=" + bbs.getMaxSize());
+// System.out.println("- timeout: " + bbs.getTimeout());
+// System.out.println("- runs: " + bbs.getRuns());
+ System.out.println("############################################################");
+ System.out.println();
+
+ workloads.getWorkloads().forEach(workloadConfiguration -> {
+ String workloadName = workloadConfiguration.getWorkloadName();
+ String modelVariant = workloadConfiguration.getModelVariant();
+ List<RailwayOperation> operations = workloadConfiguration.getOperations();
+ TransformationChangeSetStrategy strategy = workloadConfiguration.getStrategy();
+ int constant = workloadConfiguration.getConstant();
+ int queryTransformationCount = workloadConfiguration.getQueryTransformationCount();
+
+ System.out.println("============================================================");
+ System.out.println("Workload: " + workloadName);
+ System.out.println("============================================================");
+
+ ModelSetConfig modelSetConfig = new ModelSetConfig(modelVariant, bbs.getMinSize(), bbs.getMaxSize());
+ BenchmarkConfigBaseBuilder bcbb = new BenchmarkConfigBaseBuilder()
+ .setBenchmarkId(now).setTimeout(bbs.getTimeout()).setRuns(bbs.getRuns())
+ .setOperations(operations).setWorkload(workloadName)
+ .setQueryTransformationCount(queryTransformationCount).setTransformationConstant(constant)
+ .setTransformationChangeSetStrategy(strategy);
+
+ builders.forEach( bcb -> runBenchmarkSeries(bcbb, bcb, ec, modelSetConfig, bbs));
+ });
+
+// if (binding.variables.get("reportUrl")) {
+// BenchmarkReporter.reportReady(reportUrl)
+// }
+ }
+
+}
diff --git a/trainbenchmark/trainbenchmark-alternate-scripts/src/main/java/de/tudresden/inf/st/train/scripts/BenchmarkSettingsAvailableFormats.java b/trainbenchmark/trainbenchmark-alternate-scripts/src/main/java/de/tudresden/inf/st/train/scripts/BenchmarkSettingsAvailableFormats.java
new file mode 100644
index 0000000000000000000000000000000000000000..439a0801d10840f94907902fb355864c04a7d921
--- /dev/null
+++ b/trainbenchmark/trainbenchmark-alternate-scripts/src/main/java/de/tudresden/inf/st/train/scripts/BenchmarkSettingsAvailableFormats.java
@@ -0,0 +1,71 @@
+package de.tudresden.inf.st.train.scripts;
+
+import de.tudresden.inf.st.trainbenchmark.generator.json4ag.config.Json4AgGeneratorConfigBuilder;
+import hu.bme.mit.trainbenchmark.generator.config.*;
+import hu.bme.mit.trainbenchmark.generator.emf.config.EmfGeneratorConfigBuilder;
+import hu.bme.mit.trainbenchmark.generator.graph.tinkerpop.config.TinkerGraphFormat;
+import hu.bme.mit.trainbenchmark.generator.graph.tinkerpop.config.TinkerGraphGeneratorConfigBuilder;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * Format settings of a benchmark shared throughout all variants.
+ * Created by rschoene on 10/13/17.
+ */
+public class BenchmarkSettingsAvailableFormats {
+ /**
+ * Create a map, from projectName to a set of all builders in this project
+ * @return a mapping from projectName to all builders
+ */
+ public static Map<String, List<GeneratorConfigBuilder<? extends GeneratorConfig, ? extends GeneratorConfigBuilder<?, ?>>>>
+ getAvailableFormats() {
+ // { projectName -> [builder] }
+ GeneratorConfigBase dummyConfigBase = new GeneratorConfigBaseBuilder()
+ .setScenario(Scenario.BATCH).setSize(1)
+ .createGeneratorConfigBase();
+ return getAllBuilders().stream().collect(Collectors.toMap(
+ builder -> builder.setConfigBase(dummyConfigBase).createConfig().getProjectName(),
+ s -> new ArrayList<>(Collections.singletonList(s)),
+ (oldValue, newValue) -> { oldValue.addAll(newValue); return oldValue; }));
+ }
+
+ private static GeneratorConfigBuilder<? extends GeneratorConfig, ? extends GeneratorConfigBuilder<?, ?>>
+ getBuilderByName(String className) {
+ Optional<Object> result = Utils.maybeCreateNewInstance(className);
+ return (GeneratorConfigBuilder<? extends GeneratorConfig, ? extends GeneratorConfigBuilder<?, ?>>) result.orElse(null);
+ }
+
+ private static List<GeneratorConfigBuilder<? extends GeneratorConfig, ? extends GeneratorConfigBuilder<?, ?>>>
+ getAllBuilders() {
+ return Arrays.asList(
+ new EmfGeneratorConfigBuilder(),
+ new TinkerGraphGeneratorConfigBuilder().setGraphFormat(TinkerGraphFormat.GRAPHML),
+ new Json4AgGeneratorConfigBuilder()
+ );
+ }
+
+ /**
+ * Get all builders with the given names of formats. The format name in the config every builder creates
+ * must match one of the given project names.
+ * @param formatNames names of formats
+ * @return a set of matching generator config builders
+ */
+ public static List<GeneratorConfigBuilder<? extends GeneratorConfig, ? extends GeneratorConfigBuilder<?, ?>>>
+ getBuilders(String ... formatNames) {
+ Map<String, List<GeneratorConfigBuilder<? extends GeneratorConfig, ? extends GeneratorConfigBuilder<?, ?>>>>
+ availableFormats = getAvailableFormats();
+ return Arrays.stream(formatNames).map(name -> {
+ List<GeneratorConfigBuilder<? extends GeneratorConfig, ? extends GeneratorConfigBuilder<?, ?>>>
+ builders = availableFormats.get(name);
+ if (builders.isEmpty()) {
+ throw new IllegalArgumentException("Could not find format " + name + ", available formats are: "
+ + availableFormats.keySet());
+ }
+ return builders;
+ }).reduce((set1, set2) -> {
+ set1.addAll(set2);
+ return set1;
+ }).orElse(Collections.emptyList());
+ }
+}
diff --git a/trainbenchmark/trainbenchmark-alternate-scripts/src/main/java/de/tudresden/inf/st/train/scripts/BenchmarkSettingsAvailableTools.java b/trainbenchmark/trainbenchmark-alternate-scripts/src/main/java/de/tudresden/inf/st/train/scripts/BenchmarkSettingsAvailableTools.java
new file mode 100644
index 0000000000000000000000000000000000000000..49dc323b78a5cbb8f5a12c2e9326b5b3c642f2ab
--- /dev/null
+++ b/trainbenchmark/trainbenchmark-alternate-scripts/src/main/java/de/tudresden/inf/st/train/scripts/BenchmarkSettingsAvailableTools.java
@@ -0,0 +1,71 @@
+package de.tudresden.inf.st.train.scripts;
+
+import de.tudresden.inf.st.train.jastadd.config.JastaddNameLookupBenchmarkConfigBuilder;
+import de.tudresden.inf.st.train.jastadd.config.JastaddNameLookupIncrementalBenchmarkConfigBuilder;
+import de.tudresden.inf.st.train.jastadd.config.JastaddOptimizedBenchmarkConfigBuilder;
+import de.tudresden.inf.st.train.jastadd.config.JastaddOptimizedIncrementalBenchmarkConfigBuilder;
+import hu.bme.mit.trainbenchmark.benchmark.config.*;
+import hu.bme.mit.trainbenchmark.benchmark.tinkergraph.config.TinkerGraphBenchmarkConfigBuilder;
+import hu.bme.mit.trainbenchmark.benchmark.viatra.config.ViatraBackend;
+import hu.bme.mit.trainbenchmark.benchmark.viatra.config.ViatraBenchmarkConfigBuilder;
+
+import java.util.*;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+/**
+ * Tool settings of a benchmark shared throughout all variants
+ * Created by rschoene on 10/12/17.
+ */
+public class BenchmarkSettingsAvailableTools {
+ public static Map<String, BenchmarkConfigBuilder<? extends BenchmarkConfig, ? extends BenchmarkConfigBuilder<?, ?>>>
+ getAvailableTools() {
+ // { toolName -> builder }
+ BenchmarkConfigBase dummyConfigBase = new BenchmarkConfigBaseBuilder()
+ .setBenchmarkId("").setTimeout(0L).setRuns(0).setModelFilename("")
+ .setOperations(new ArrayList<>()).setWorkload("")
+ .setTransformationChangeSetStrategy(TransformationChangeSetStrategy.FIXED)
+ .setQueryTransformationCount(0).setTransformationConstant(0)
+ .createConfigBase();
+ return getAllBuilders().stream().collect(Collectors.toMap(
+ builder -> builder.setConfigBase(dummyConfigBase).createConfig().getToolName(),
+ Function.identity()));
+ }
+
+ private static BenchmarkConfigBuilder<? extends BenchmarkConfig, ? extends BenchmarkConfigBuilder<?, ?>>
+ getBuilderByName(String className) {
+ Optional<Object> result = Utils.maybeCreateNewInstance(className);
+ return (BenchmarkConfigBuilder<? extends BenchmarkConfig, ? extends BenchmarkConfigBuilder<?, ?>>) result.orElse(null);
+ }
+
+ private static List<BenchmarkConfigBuilder<? extends BenchmarkConfig, ? extends BenchmarkConfigBuilder<?, ?>>>
+ getAllBuilders() {
+ return Arrays.asList(
+ new JastaddNameLookupBenchmarkConfigBuilder(),
+ new JastaddNameLookupIncrementalBenchmarkConfigBuilder(),
+ new JastaddOptimizedBenchmarkConfigBuilder(),
+ new JastaddOptimizedIncrementalBenchmarkConfigBuilder(),
+ new TinkerGraphBenchmarkConfigBuilder(),
+ new ViatraBenchmarkConfigBuilder().setBackend(ViatraBackend.INCREMENTAL),
+ new ViatraBenchmarkConfigBuilder().setBackend(ViatraBackend.LOCAL_SEARCH)
+ );
+ }
+
+ /**
+ * Get all builders with the given names of tools. The tool name in the config every builder creates must match one
+ * of the given tool names.
+ * @param toolNames names of tools
+ * @return a list of matching benchmark config builders
+ */
+ public static List<BenchmarkConfigBuilder<? extends BenchmarkConfig, ? extends BenchmarkConfigBuilder<?, ?>>>
+ getBuilders(String ... toolNames) {
+ Map<String, BenchmarkConfigBuilder<? extends BenchmarkConfig, ? extends BenchmarkConfigBuilder<?, ?>>> availableTools = getAvailableTools();
+ return Arrays.stream(toolNames).map(name -> {
+ BenchmarkConfigBuilder<? extends BenchmarkConfig, ? extends BenchmarkConfigBuilder<?, ?>> builder = availableTools.get(name);
+ if (builder == null) {
+ throw new IllegalArgumentException("Could not find tool " + name + ", available tools are: " + availableTools.keySet());
+ }
+ return builder;
+ }).collect(Collectors.toList());
+ }
+}
diff --git a/trainbenchmark/trainbenchmark-alternate-scripts/src/main/java/de/tudresden/inf/st/train/scripts/BenchmarkSettingsBasics.java b/trainbenchmark/trainbenchmark-alternate-scripts/src/main/java/de/tudresden/inf/st/train/scripts/BenchmarkSettingsBasics.java
new file mode 100644
index 0000000000000000000000000000000000000000..cf427052309cfb2da890c8eacd7077fddf2d1645
--- /dev/null
+++ b/trainbenchmark/trainbenchmark-alternate-scripts/src/main/java/de/tudresden/inf/st/train/scripts/BenchmarkSettingsBasics.java
@@ -0,0 +1,134 @@
+package de.tudresden.inf.st.train.scripts;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonSetter;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Basic settings bean of a benchmark shared throughout all variants.
+ * Created by rschoene on 10/12/17.
+ */
+public class BenchmarkSettingsBasics {
+
+ static class JVMSetting {
+ private List<String> applyTo;
+ private String args;
+
+ public List<String> getApplyTo() {
+ return applyTo;
+ }
+
+ public void setApplyTo(List<String> applyTo) {
+ this.applyTo = applyTo;
+ }
+
+ public String getArgs() {
+ return args;
+ }
+
+ public void setArgs(String args) {
+ this.args = args;
+ }
+ }
+ @JsonInclude(JsonInclude.Include.NON_DEFAULT)
+ private Integer minSize = null;
+ @JsonInclude(JsonInclude.Include.NON_DEFAULT)
+ private Integer maxSize = null;
+ @JsonInclude(JsonInclude.Include.NON_DEFAULT)
+ private Long timeout = null;
+ @JsonInclude(JsonInclude.Include.NON_DEFAULT)
+ private Integer runs = null;
+ @JsonInclude(JsonInclude.Include.NON_DEFAULT)
+ private Boolean dryRun = null;
+ private String[] tools;
+ private String[] formats;
+ private List<JVMSetting> jvmSettings;
+
+ /** Minimum model size */
+ public Integer getMinSize() {
+ return minSize;
+ }
+
+ public void setMinSize(int minSize) {
+ this.minSize = minSize;
+ }
+
+ /** Maximum model size */
+ public Integer getMaxSize() {
+ return maxSize;
+ }
+
+ public void setMaxSize(int maxSize) {
+ this.maxSize = maxSize;
+ }
+
+ /** Timeout in seconds for each single run. */
+ public Long getTimeout() {
+ return timeout;
+ }
+
+ public void setTimeout(long timeout) {
+ this.timeout = timeout;
+ }
+
+ /** Number of runs per tool-workload combination. */
+ public Integer getRuns() {
+ return runs;
+ }
+
+ public void setRuns(int runs) {
+ this.runs = runs;
+ }
+
+ /** Don't run any Java processes. */
+ public Boolean isDryRun() {
+ return dryRun;
+ }
+
+ @JsonSetter("dry-run")
+ public void setDryRun(boolean dryRun) {
+ this.dryRun = dryRun;
+ }
+
+ /** List of tool names to use */
+ public String[] getTools() {
+ return tools;
+ }
+
+ public void setTools(String[] tools) {
+ this.tools = tools;
+ }
+
+ /** List of format names to use */
+ public String[] getFormats() {
+ return formats;
+ }
+
+ public void setFormats(String[] formats) {
+ this.formats = formats;
+ }
+
+ public List<JVMSetting> getJvmSettings() {
+ return jvmSettings;
+ }
+
+ public void setJvmSettings(List<JVMSetting> jvmSettings) {
+ this.jvmSettings = jvmSettings;
+ }
+
+ @Override
+ public String toString() {
+ return "BenchmarkSettingsBasics{" +
+ "minSize=" + minSize +
+ ", maxSize=" + maxSize +
+ ", timeout=" + timeout +
+ ", runs=" + runs +
+ ", dryRun=" + dryRun +
+ ", tools=" + Arrays.toString(tools) +
+ '}';
+ }
+}
diff --git a/trainbenchmark/trainbenchmark-alternate-scripts/src/main/java/de/tudresden/inf/st/train/scripts/BenchmarkSettingsVariantWorkloads.java b/trainbenchmark/trainbenchmark-alternate-scripts/src/main/java/de/tudresden/inf/st/train/scripts/BenchmarkSettingsVariantWorkloads.java
new file mode 100644
index 0000000000000000000000000000000000000000..ab89bcdf3a68b80e9ecac6525b0ed7fd43a867c0
--- /dev/null
+++ b/trainbenchmark/trainbenchmark-alternate-scripts/src/main/java/de/tudresden/inf/st/train/scripts/BenchmarkSettingsVariantWorkloads.java
@@ -0,0 +1,19 @@
+package de.tudresden.inf.st.train.scripts;
+
+import java.util.List;
+
+/**
+ * List of all workload settings by variant.
+ * Created by rschoene on 10/12/17.
+ */
+public class BenchmarkSettingsVariantWorkloads {
+ private List<BenchmarkSettingsWorkloads> variants;
+
+ public List<BenchmarkSettingsWorkloads> getVariants() {
+ return variants;
+ }
+
+ public void setVariants(List<BenchmarkSettingsWorkloads> variants) {
+ this.variants = variants;
+ }
+}
diff --git a/trainbenchmark/trainbenchmark-alternate-scripts/src/main/java/de/tudresden/inf/st/train/scripts/BenchmarkSettingsWorkload.java b/trainbenchmark/trainbenchmark-alternate-scripts/src/main/java/de/tudresden/inf/st/train/scripts/BenchmarkSettingsWorkload.java
new file mode 100644
index 0000000000000000000000000000000000000000..95b00151ae26fab885202a58e77f63d1086f3a04
--- /dev/null
+++ b/trainbenchmark/trainbenchmark-alternate-scripts/src/main/java/de/tudresden/inf/st/train/scripts/BenchmarkSettingsWorkload.java
@@ -0,0 +1,81 @@
+package de.tudresden.inf.st.train.scripts;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import hu.bme.mit.trainbenchmark.benchmark.config.TransformationChangeSetStrategy;
+import hu.bme.mit.trainbenchmark.constants.RailwayOperation;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+/**
+ * Benchmark setting workload bean.
+ * Created by rschoene on 10/12/17.
+ */
+public class BenchmarkSettingsWorkload {
+ private String workloadName;
+ private String modelVariant;
+ private List<RailwayOperation> operations;
+ private TransformationChangeSetStrategy strategy;
+// private String strategy;
+ private int constant;
+ private int queryTransformationCount;
+ @JsonIgnore
+ private Map<String, RailwayOperation> railwayOps;
+
+ public BenchmarkSettingsWorkload() {
+ railwayOps = Arrays.stream(RailwayOperation.values()).collect(Collectors.toMap(
+ RailwayOperation::toString, Function.identity()
+ ));
+ }
+
+ public String getWorkloadName() {
+ return workloadName;
+ }
+
+ public void setWorkloadName(String workloadName) {
+ this.workloadName = workloadName;
+ }
+
+ public String getModelVariant() {
+ return modelVariant;
+ }
+
+ public void setModelVariant(String modelVariant) {
+ this.modelVariant = modelVariant;
+ }
+
+ public List<RailwayOperation> getOperations() {
+ return operations;
+ }
+
+ public void setOperations(List<String> operations) {
+ this.operations = operations.stream().map(op -> railwayOps.get(op)).collect(Collectors.toList());
+ }
+
+ public TransformationChangeSetStrategy getStrategy() {
+ return strategy;
+ }
+
+ public void setStrategy(TransformationChangeSetStrategy strategy) {
+ this.strategy = strategy;
+ }
+
+ public int getConstant() {
+ return constant;
+ }
+
+ public void setConstant(int constant) {
+ this.constant = constant;
+ }
+
+ public int getQueryTransformationCount() {
+ return queryTransformationCount;
+ }
+
+ public void setQueryTransformationCount(int queryTransformationCount) {
+ this.queryTransformationCount = queryTransformationCount;
+ }
+}
diff --git a/trainbenchmark/trainbenchmark-alternate-scripts/src/main/java/de/tudresden/inf/st/train/scripts/BenchmarkSettingsWorkloads.java b/trainbenchmark/trainbenchmark-alternate-scripts/src/main/java/de/tudresden/inf/st/train/scripts/BenchmarkSettingsWorkloads.java
new file mode 100644
index 0000000000000000000000000000000000000000..d32c2290b4be746cfe5963619a1f07dc968d9592
--- /dev/null
+++ b/trainbenchmark/trainbenchmark-alternate-scripts/src/main/java/de/tudresden/inf/st/train/scripts/BenchmarkSettingsWorkloads.java
@@ -0,0 +1,29 @@
+package de.tudresden.inf.st.train.scripts;
+
+import java.util.List;
+
+/**
+ * Workload settings bean.
+ * Created by rschoene on 10/12/17.
+ */
+public class BenchmarkSettingsWorkloads
+{
+ private String name;
+ private List<BenchmarkSettingsWorkload> workloads;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public List<BenchmarkSettingsWorkload> getWorkloads() {
+ return workloads;
+ }
+
+ public void setWorkloads(List<BenchmarkSettingsWorkload> workloads) {
+ this.workloads = workloads;
+ }
+}
diff --git a/trainbenchmark/trainbenchmark-alternate-scripts/src/main/java/de/tudresden/inf/st/train/scripts/BenchmarkVariant.java b/trainbenchmark/trainbenchmark-alternate-scripts/src/main/java/de/tudresden/inf/st/train/scripts/BenchmarkVariant.java
new file mode 100644
index 0000000000000000000000000000000000000000..d6f04f1183bf0cd409f770347a87f6d769f15276
--- /dev/null
+++ b/trainbenchmark/trainbenchmark-alternate-scripts/src/main/java/de/tudresden/inf/st/train/scripts/BenchmarkVariant.java
@@ -0,0 +1,12 @@
+package de.tudresden.inf.st.train.scripts;
+
+/**
+ * Possible variants to run a benchmark in.
+ * Created by rschoene on 10/12/17.
+ */
+public enum BenchmarkVariant {
+ COMBINED,
+ INDIVIDUAL_INJECT,
+ INDIVIDUAL_REPAIR,
+ INDIVIDUAL_INCREMENTAL
+}
diff --git a/trainbenchmark/trainbenchmark-alternate-scripts/src/main/java/de/tudresden/inf/st/train/scripts/GenerateMain.java b/trainbenchmark/trainbenchmark-alternate-scripts/src/main/java/de/tudresden/inf/st/train/scripts/GenerateMain.java
new file mode 100644
index 0000000000000000000000000000000000000000..367c5f5f0e3b73014640f242af5df01c4cbd6496
--- /dev/null
+++ b/trainbenchmark/trainbenchmark-alternate-scripts/src/main/java/de/tudresden/inf/st/train/scripts/GenerateMain.java
@@ -0,0 +1,113 @@
+package de.tudresden.inf.st.train.scripts;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import hu.bme.mit.trainbenchmark.config.ExecutionConfig;
+import hu.bme.mit.trainbenchmark.generator.config.*;
+import hu.bme.mit.trainbenchmark.generator.runner.GeneratorRunner;
+
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * Main entry point to generate models.
+ * Created by rschoene on 10/13/17.
+ */
+public class GenerateMain {
+ public static void main(String[] args) throws Exception {
+ // read basic settings (min, maxsize, etc.)
+ ObjectMapper mapper = Utils.getMapper();
+ BenchmarkSettingsBasics bbs = Utils.readFromResource(mapper, "basic-settings.json",
+ BenchmarkSettingsBasics.class);
+ try {
+ BenchmarkSettingsBasics loca_bbs = Utils.readFromResource(mapper, "local-basic-settings.json",
+ BenchmarkSettingsBasics.class);
+ Utils.updateBasicsWithLocal(bbs, loca_bbs);
+ } catch (IOException e) {
+ System.out.println("No file 'local-basic-settings.json' found. Using default!");
+ }
+
+ // import formats to use
+ List<GeneratorConfigBuilder<? extends GeneratorConfig, ? extends GeneratorConfigBuilder<?, ?>>> builders =
+ BenchmarkSettingsAvailableFormats.getBuilders(bbs.getFormats());
+ System.out.println(builders);
+ ExecutionConfig ec = new ExecutionConfig(4000, 8000, bbs.isDryRun());
+
+ // start generating (exclude Scenario.MINIMAL)
+ for (Scenario scenario : new Scenario[]{Scenario.BATCH, Scenario.INJECT, Scenario.REPAIR}) {
+ builders.forEach( generatorConfigBuilder -> {
+ try {
+ for (int size = bbs.getMinSize(); size <= bbs.getMaxSize(); size *= 2) {
+ System.out.println("Scenario: " + scenario + ", size: " + size);
+
+ GeneratorConfigBase configBase = new GeneratorConfigBaseBuilder()
+ .setSize(size).setScenario(scenario)
+ .createGeneratorConfigBase();
+ GeneratorConfig config = generatorConfigBuilder.setConfigBase(configBase).createConfig();
+
+ int exitValue = GeneratorRunner.run(config, ec);
+ if (exitValue != 0) {
+ System.out.println("Timeout or error occurred, skipping models for larger sizes. Error code: "
+ + exitValue);
+ break;
+ }
+ }
+ } catch (Exception e) {
+ System.out.println("Exception occurred during execution.");
+ }
+ });
+ }
+ }
+
+}
+
+/*
+import de.tudresden.inf.st.trainbenchmark.generator.json4ag.config.Json4AgGeneratorConfigBuilder
+import de.tudresden.inf.st.trainbenchmark.generator.json4agref.config.Json4AgRefGeneratorConfigBuilder
+import hu.bme.mit.trainbenchmark.config.ExecutionConfig
+import hu.bme.mit.trainbenchmark.generator.config.GeneratorConfigBase
+import hu.bme.mit.trainbenchmark.generator.config.Scenario
+import hu.bme.mit.trainbenchmark.generator.emf.config.EmfGeneratorConfigBuilder
+import hu.bme.mit.trainbenchmark.generator.graph.tinkerpop.config.TinkerGraphFormat
+import hu.bme.mit.trainbenchmark.generator.graph.tinkerpop.config.TinkerGraphGeneratorConfigBuilder
+import hu.bme.mit.trainbenchmark.generator.runner.GeneratorRunner
+
+def ec = new ExecutionConfig(4000, 6000)
+def minSize = 1
+/* def maxSize = 2048 *
+def maxSize = 256
+
+ def scenarios = [
+ Scenario.BATCH,
+ Scenario.INJECT,
+ Scenario.REPAIR,
+ ]
+
+ def formats = [
+ new EmfGeneratorConfigBuilder(),
+ new TinkerGraphGeneratorConfigBuilder().setGraphFormat(TinkerGraphFormat.GRAPHML),
+ new Json4AgGeneratorConfigBuilder(),
+ new Json4AgRefGeneratorConfigBuilder()
+ ]
+
+ for (scenario in scenarios) {
+ formats.each { generatorConfigBuilder ->
+ try {
+ for (def size = minSize; size <= maxSize; size *= 2) {
+ println("Scenario: ${scenario}, size: ${size}")
+
+ def configBase = new GeneratorConfigBase(scenario, size)
+ def config = generatorConfigBuilder.setConfigBase(configBase).createConfig()
+
+ def exitValue = GeneratorRunner.run(config, ec)
+ if (exitValue != 0) {
+ println "Timeout or error occured, skipping models for larger sizes. Error code: ${exitValue}"
+ break
+ }
+ }
+ } catch (all) {
+ println "Exception occured during execution."
+ }
+ }
+ }
+
+ */
diff --git a/trainbenchmark/trainbenchmark-alternate-scripts/src/main/java/de/tudresden/inf/st/train/scripts/Utils.java b/trainbenchmark/trainbenchmark-alternate-scripts/src/main/java/de/tudresden/inf/st/train/scripts/Utils.java
new file mode 100644
index 0000000000000000000000000000000000000000..e155896b5f1f21927c3328f37ed596288e8cd9fb
--- /dev/null
+++ b/trainbenchmark/trainbenchmark-alternate-scripts/src/main/java/de/tudresden/inf/st/train/scripts/Utils.java
@@ -0,0 +1,99 @@
+package de.tudresden.inf.st.train.scripts;
+
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.net.URL;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * Utility methods for the main entry points.
+ * Created by rschoene on 10/13/17.
+ */
+public class Utils {
+ static Map<String, String> createJvmSettingsMap(BenchmarkSettingsBasics bbs) {
+ Map<String, String> result = new HashMap<>();
+ for (BenchmarkSettingsBasics.JVMSetting setting : bbs.getJvmSettings()) {
+ for (String toolName : setting.getApplyTo()) {
+ result.put(toolName, setting.getArgs());
+ }
+ }
+ return result;
+ }
+
+ private static File readFromResource(String filename) throws IOException {
+ URL basicSettingsURL = BenchmarkMain.class.getClassLoader().getResource(filename);
+ if (basicSettingsURL == null) {
+ System.err.println();
+ throw new IOException("Could not access " + filename + ". Exiting.");
+ }
+ return new File(basicSettingsURL.getFile());
+ }
+
+ static <T> T readFromResource(ObjectMapper mapper, String filename, Class<T> clazz) throws IOException {
+ File basicSettingsFile = readFromResource(filename);
+ T result = null;
+ try {
+ result = mapper.readValue(basicSettingsFile, clazz);
+ } catch (Exception e) {
+ System.err.println("Could not load '" + filename + "'. Exiting.");
+ e.printStackTrace();
+ System.exit(2);
+ }
+ return result;
+ }
+
+ static void updateBasicsWithLocal(BenchmarkSettingsBasics base, BenchmarkSettingsBasics local)
+ throws IllegalStateException {
+ List<Method> setter = Arrays.stream(BenchmarkSettingsBasics.class.getMethods())
+ .filter(m -> m.getName().startsWith("set"))
+ .collect(Collectors.toList());
+ for (Method method : BenchmarkSettingsBasics.class.getMethods()) {
+ final String name = method.getName().startsWith("get") ?
+ method.getName().substring(3) :
+ ( method.getName().startsWith("is") ? method.getName().substring(2) : null);
+ if (name == null) {
+ continue;
+ }
+ try {
+ Object result = method.invoke(local);
+ if (result != null) {
+ Optional<Method> matchingSetter = setter.stream()
+ .filter(m -> m.getName().endsWith(name))
+ .findFirst();
+ if (matchingSetter.isPresent()) {
+ matchingSetter.get().invoke(base, result);
+ }
+ }
+ // now do sanity check if set in updated base
+ result = method.invoke(base);
+ if (result == null) {
+ throw new IllegalStateException("Basic setting for " + name + " is not given.");
+ }
+ } catch (IllegalAccessException | InvocationTargetException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ static ObjectMapper getMapper() {
+ ObjectMapper mapper = new ObjectMapper();
+ mapper.configure(JsonParser.Feature.ALLOW_COMMENTS, true);
+ return mapper;
+ }
+
+ static Optional<Object> maybeCreateNewInstance(final String className) {
+ try {
+ return Optional.of(Class.forName(className).newInstance());
+ } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
+ System.err.println("Could not find builder class '" + className + "'");
+ e.printStackTrace();
+ return Optional.empty();
+ }
+ }
+}
diff --git a/trainbenchmark/trainbenchmark-alternate-scripts/src/main/resources/.gitignore b/trainbenchmark/trainbenchmark-alternate-scripts/src/main/resources/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..4ee2202e58823ac10973a1d236e6404a8c11b4ef
--- /dev/null
+++ b/trainbenchmark/trainbenchmark-alternate-scripts/src/main/resources/.gitignore
@@ -0,0 +1,2 @@
+# basic settings can still be commited using --force
+local-basic-settings.json
diff --git a/trainbenchmark/trainbenchmark-alternate-scripts/src/main/resources/basic-settings.json b/trainbenchmark/trainbenchmark-alternate-scripts/src/main/resources/basic-settings.json
new file mode 100644
index 0000000000000000000000000000000000000000..501ab8fc36d9f4507c97454d9dbc36e37b7637b7
--- /dev/null
+++ b/trainbenchmark/trainbenchmark-alternate-scripts/src/main/resources/basic-settings.json
@@ -0,0 +1,32 @@
+{
+ "minSize": 1,
+ "maxSize": 8,
+ "timeout": 900,
+ "runs": 1,
+ "dry-run": true,
+ "tools": [
+ "Jastadd (Name Lookup)",
+ "Jastadd (Incremental Name Lookup)",
+ "Jastadd (Optimized)",
+ "Jastadd (Optimized Incremental)",
+ "TinkerGraph",
+ "VIATRA (Incremental)",
+ "VIATRA (Local Search)"
+ ],
+ "formats": [
+ "emf",
+ "json4ag",
+ "graph-tinkerpop"
+ ],
+ "jvmSettings": [
+ {
+ "applyTo": ["*"],
+ "args": "-Xms%(Xms) -Xmx%(Xmx) -server -Xverify:none"
+// "args": "-Xms%(Xms) -Xmx%(Xmx) -server -XX:+UnlockCommercialFeatures -XX:+FlightRecorder -XX:StartFlightRecording=dumponexit=true -Xverify:none"
+ },
+ {
+ "applyTo": ["Racr (CPP)", "Racr (Python)", "Racr (Scheme)"],
+ "args": "-Xms50M -Xmx50M -server -Xverify:none"
+ }
+ ]
+}
diff --git a/trainbenchmark/trainbenchmark-alternate-scripts/src/main/resources/workloads.json b/trainbenchmark/trainbenchmark-alternate-scripts/src/main/resources/workloads.json
new file mode 100644
index 0000000000000000000000000000000000000000..513e70203ba17237c104e4dd9f72b1510dabadcd
--- /dev/null
+++ b/trainbenchmark/trainbenchmark-alternate-scripts/src/main/resources/workloads.json
@@ -0,0 +1,258 @@
+{
+ "variants": [
+ {
+ "name": "individual_repair",
+ "workloads": [
+ {
+ "workloadName": "ConnectedSegments",
+ "operations": [
+ "ConnectedSegmentsRepair"
+ ],
+ "constant": 5,
+ "queryTransformationCount": 8,
+ "modelVariant": "repair",
+ "strategy": "PROPORTIONAL"
+ },
+ {
+ "workloadName": "PosLength",
+ "operations": [
+ "PosLengthRepair"
+ ],
+ "constant": 5,
+ "queryTransformationCount": 8,
+ "modelVariant": "repair",
+ "strategy": "PROPORTIONAL"
+ },
+ {
+ "workloadName": "RouteSensor",
+ "operations": [
+ "RouteSensorRepair"
+ ],
+ "constant": 5,
+ "queryTransformationCount": 8,
+ "modelVariant": "repair",
+ "strategy": "PROPORTIONAL"
+ },
+ {
+ "workloadName": "SemaphoreNeighbor",
+ "operations": [
+ "SemaphoreNeighborRepair"
+ ],
+ "constant": 5,
+ "queryTransformationCount": 8,
+ "modelVariant": "repair",
+ "strategy": "PROPORTIONAL"
+ },
+ {
+ "workloadName": "SwitchMonitored",
+ "operations": [
+ "SwitchMonitoredRepair"
+ ],
+ "constant": 5,
+ "queryTransformationCount": 8,
+ "modelVariant": "repair",
+ "strategy": "PROPORTIONAL"
+ },
+ {
+ "workloadName": "SwitchSet",
+ "operations": [
+ "SwitchSetRepair"
+ ],
+ "constant": 5,
+ "queryTransformationCount": 8,
+ "modelVariant": "repair",
+ "strategy": "PROPORTIONAL"
+ }
+ ]
+ },
+ {
+ "name": "combined",
+ "workloads": [
+ {
+ "workloadName": "Repair",
+ "operations": [
+ "ConnectedSegmentsRepair",
+ "PosLengthRepair",
+ "RouteSensorRepair",
+ "SemaphoreNeighborRepair",
+ "SwitchMonitoredRepair",
+ "SwitchSetRepair"
+ ],
+ "constant": 5,
+ "queryTransformationCount": 8,
+ "modelVariant": "repair",
+ "strategy": "PROPORTIONAL"
+ },
+ {
+ "workloadName": "Inject",
+ "operations": [
+ "ConnectedSegments",
+ "PosLength",
+ "RouteSensor",
+ "SemaphoreNeighbor",
+ "SwitchMonitored",
+ "SwitchSet",
+ "ConnectedSegmentsInject",
+ "PosLengthInject",
+ "RouteSensorInject",
+ "SemaphoreNeighborInject",
+ "SwitchMonitoredInject",
+ "SwitchSetInject"
+ ],
+ "constant": 10,
+ "queryTransformationCount": 12,
+ "modelVariant": "inject",
+ "strategy": "FIXED"
+ }
+ ]
+ },
+ {
+ "name": "individual_inject",
+ "workloads": [
+ {
+ "workloadName": "ConnectedSegments",
+ "operations": [
+ "ConnectedSegments",
+ "ConnectedSegmentsInject"
+ ],
+ "constant": 10,
+ "queryTransformationCount": 12,
+ "modelVariant": "inject",
+ "strategy": "FIXED"
+ },
+ {
+ "workloadName": "PosLength",
+ "operations": [
+ "PosLength",
+ "PosLengthInject"
+ ],
+ "constant": 10,
+ "queryTransformationCount": 12,
+ "modelVariant": "inject",
+ "strategy": "FIXED"
+ },
+ {
+ "workloadName": "RouteSensor",
+ "operations": [
+ "RouteSensor",
+ "RouteSensorInject"
+ ],
+ "constant": 10,
+ "queryTransformationCount": 12,
+ "modelVariant": "inject",
+ "strategy": "FIXED"
+ },
+ {
+ "workloadName": "SemaphoreNeighbor",
+ "operations": [
+ "SemaphoreNeighbor",
+ "SemaphoreNeighborInject"
+ ],
+ "constant": 10,
+ "queryTransformationCount": 12,
+ "modelVariant": "inject",
+ "strategy": "FIXED"
+ },
+ {
+ "workloadName": "SwitchMonitored",
+ "operations": [
+ "SwitchMonitored",
+ "SwitchMonitoredInject"
+ ],
+ "constant": 10,
+ "queryTransformationCount": 12,
+ "modelVariant": "inject",
+ "strategy": "FIXED"
+ },
+ {
+ "workloadName": "SwitchSet",
+ "operations": [
+ "SwitchSet",
+ "SwitchSetInject"
+ ],
+ "constant": 10,
+ "queryTransformationCount": 12,
+ "modelVariant": "inject",
+ "strategy": "FIXED"
+ }
+ ]
+ },
+ {
+ "name": "individual_incremental",
+ "workloads": [
+ {
+ "workloadName": "ConnectedSegments",
+ "operations": [
+ "ConnectedSegments",
+ "ConnectedSegmentsInject",
+ "ConnectedSegmentsRepair"
+ ],
+ "constant": 10,
+ "queryTransformationCount": 50,
+ "modelVariant": "inject",
+ "strategy": "FIXED"
+ },
+ {
+ "workloadName": "PosLength",
+ "operations": [
+ "PosLength",
+ "PosLengthInject",
+ "PosLengthRepair"
+ ],
+ "constant": 10,
+ "queryTransformationCount": 50,
+ "modelVariant": "inject",
+ "strategy": "FIXED"
+ },
+ {
+ "workloadName": "RouteSensor",
+ "operations": [
+ "RouteSensor",
+ "RouteSensorInject",
+ "RouteSensorRepair"
+ ],
+ "constant": 10,
+ "queryTransformationCount": 50,
+ "modelVariant": "inject",
+ "strategy": "FIXED"
+ },
+ {
+ "workloadName": "SemaphoreNeighbor",
+ "operations": [
+ "SemaphoreNeighbor",
+ "SemaphoreNeighborInject",
+ "SemaphoreNeighborRepair"
+ ],
+ "constant": 10,
+ "queryTransformationCount": 50,
+ "modelVariant": "inject",
+ "strategy": "FIXED"
+ },
+ {
+ "workloadName": "SwitchMonitored",
+ "operations": [
+ "SwitchMonitored",
+ "SwitchMonitoredInject",
+ "SwitchMonitoredRepair"
+ ],
+ "constant": 10,
+ "queryTransformationCount": 50,
+ "modelVariant": "inject",
+ "strategy": "FIXED"
+ },
+ {
+ "workloadName": "SwitchSet",
+ "operations": [
+ "SwitchSet",
+ "SwitchSetInject",
+ "SwitchSetRepair"
+ ],
+ "constant": 10,
+ "queryTransformationCount": 50,
+ "modelVariant": "inject",
+ "strategy": "FIXED"
+ }
+ ]
+ }
+ ]
+}
diff --git a/trainbenchmark/trainbenchmark-config/src/main/java/hu/bme/mit/trainbenchmark/config/ExecutionConfig.java b/trainbenchmark/trainbenchmark-config/src/main/java/hu/bme/mit/trainbenchmark/config/ExecutionConfig.java
index fa0ba9c21b13c1a7e1f5341ecd2a9e23f87f242c..a828d68d792bd8bdea8e49016ac93cea45740d05 100644
--- a/trainbenchmark/trainbenchmark-config/src/main/java/hu/bme/mit/trainbenchmark/config/ExecutionConfig.java
+++ b/trainbenchmark/trainbenchmark-config/src/main/java/hu/bme/mit/trainbenchmark/config/ExecutionConfig.java
@@ -4,14 +4,20 @@ public class ExecutionConfig {
protected Integer initialMemory;
protected Integer maxMemory;
+ protected Boolean dryRun;
- public ExecutionConfig(final Integer initialMemory, final Integer maxMemory) {
+ public ExecutionConfig(final Integer initialMemory, final Integer maxMemory, final boolean dryRun) {
this.initialMemory = initialMemory;
this.maxMemory = maxMemory;
+ this.dryRun = dryRun;
+ }
+
+ public ExecutionConfig(final Integer initialMemory, final Integer maxMemory) {
+ this(initialMemory, maxMemory, true);
}
/**
- *
+ *
* @return The initial memory for the benchmark JVM in MBs.
*/
public Integer getInitialMemory() {
@@ -41,7 +47,15 @@ public class ExecutionConfig {
public String getXmx() {
return maxMemory + "M";
}
-
+
+ /**
+ *
+ * @return whether this benchmark run must not start any Java processes
+ */
+ public Boolean getDryRun() {
+ return dryRun;
+ }
+
public static ExecutionConfig defaultExecutionConfig() {
return new ExecutionConfig(1000, 1000);
}
diff --git a/trainbenchmark/trainbenchmark-reporting/.gitignore b/trainbenchmark/trainbenchmark-reporting/.gitignore
index fb37a9f266860443b1f59ea9af4a8ce2eb089bce..5bfbad9180280146565a6e3c0127cf72266b33b7 100644
--- a/trainbenchmark/trainbenchmark-reporting/.gitignore
+++ b/trainbenchmark/trainbenchmark-reporting/.gitignore
@@ -1,2 +1,2 @@
Rplots.pdf
-
+local-merge_results.json
diff --git a/trainbenchmark/trainbenchmark-reporting/build.gradle b/trainbenchmark/trainbenchmark-reporting/build.gradle
index 5e8f0e2e1aa1f7b6240ab43977b0e13d2eccf0ac..7fc02588564bd4cedce73c2ecfc52d06fb27f0e3 100644
--- a/trainbenchmark/trainbenchmark-reporting/build.gradle
+++ b/trainbenchmark/trainbenchmark-reporting/build.gradle
@@ -1,7 +1,26 @@
+task doMerge(type: Exec) {
+ group = 'Benchmark'
+ description = 'Merges the results'
+ commandLine './do-merge.sh'
+}
+
task plot(type: Exec) {
- commandLine 'Rscript', 'report.R'
+ group = 'Benchmark'
+ description = 'Plots the \'classic\' TrainBenchmark result'
+ commandLine 'Rscript', 'report.R'
+ dependsOn doMerge
}
task plotIndividual(type: Exec) {
- commandLine 'Rscript', 'individual.R'
-}
\ No newline at end of file
+ group = 'Benchmark'
+ description = 'Plots the individual TrainBenchmark results'
+ commandLine 'Rscript', 'individual.R'
+ dependsOn doMerge
+}
+
+task plotToolwise(type: Exec) {
+ group = 'Benchmark'
+ description = 'Plots the individual TrainBenchmark results per tool'
+ commandLine './toolwise.sh'
+ dependsOn doMerge
+}
diff --git a/trainbenchmark/trainbenchmark-reporting/do-merge.sh b/trainbenchmark/trainbenchmark-reporting/do-merge.sh
new file mode 100755
index 0000000000000000000000000000000000000000..cda5cf12b0fecef96942b21b2faf09054e7e097d
--- /dev/null
+++ b/trainbenchmark/trainbenchmark-reporting/do-merge.sh
@@ -0,0 +1 @@
+python merge_results.py --result-dir ../results/ --create-run-dirs --create-toolwise-dirs $@
diff --git a/trainbenchmark/trainbenchmark-reporting/merge_results.json b/trainbenchmark/trainbenchmark-reporting/merge_results.json
new file mode 100644
index 0000000000000000000000000000000000000000..d8de85321024170135a651f07de7db5d5c36a8d8
--- /dev/null
+++ b/trainbenchmark/trainbenchmark-reporting/merge_results.json
@@ -0,0 +1,27 @@
+{
+ "tools": [
+ "tinkergraph",
+ "drools",
+ "mysql",
+ "kiama",
+ "jastadd-java-references",
+ "jastadd-java-references-incremental",
+ "jastadd-symbolic-references-incremental",
+ "jastadd-symbolic-references",
+ "sqlite",
+ "viatra",
+ "racr-cpp",
+ "racr-python",
+ "racr-scheme",
+ "neo4j",
+ "sesame",
+ "emfapi",
+ "rdf4j",
+ "epsilon",
+ "eclipseocl"
+ ],
+ "ignored": [
+ ],
+ "toolwise": [
+ ]
+}
diff --git a/trainbenchmark/trainbenchmark-reporting/merge_results.py b/trainbenchmark/trainbenchmark-reporting/merge_results.py
new file mode 100755
index 0000000000000000000000000000000000000000..a1fdb731eee2fab010b4f47498529971383bb359
--- /dev/null
+++ b/trainbenchmark/trainbenchmark-reporting/merge_results.py
@@ -0,0 +1,242 @@
+#!/usr/bin/env python
+import argparse
+import csv
+import glob
+import json
+import logging
+import os
+import os.path
+import re
+import sys
+
+
+FORMAT = '%(asctime)s %(levelname)-8s %(threadName)-10s (%(filename)s:%(lineno)d): %(message)s'
+BENCHMARK_PATTERN = re.compile('.*-(BatchModel|Repair|Inject)Test.*')
+logger = logging.getLogger('merge_result')
+SIZE_PATTERN = re.compile('.*-railway-[^\\-]*-([^\\-]*)-.csv')
+NAME_PATTERN = re.compile('(times|matches)-([^\\-]*)-.*.csv')
+RUN_PATTERN = re.compile('run-(....)-(..)-(..)-(..)-(..)-(..)')
+RUN_REPLACMENT = r'\1_\2_\3 \4:\5:\6'
+
+
+def include_file_config(args):
+ def override_if_defined(key, convert=lambda x: x):
+ keyArgs = key.replace('-', '_')
+ value = content.get(key) or content.get(keyArgs)
+ if value:
+ setattr(args, keyArgs, convert(value))
+
+ # load config file
+ with open(args.file_config) as fdr:
+ content = json.load(fdr)
+ # update with local version, if existing
+ directory, basename = os.path.split(os.path.abspath(args.file_config))
+ local_config_file = os.path.join(directory, 'local-' + basename)
+ if os.path.exists(local_config_file):
+ with open(local_config_file) as fdr:
+ content.update(json.load(fdr))
+ else:
+ logger.debug('No local config file found.')
+ if not content.get('tools'):
+ logger.error('Key "tools" not found in config file "' + args.file_config + '". Exiting.')
+ sys.exit(1)
+ args.tools = content['tools']
+ override_if_defined('max-size', int)
+ override_if_defined('dry-run', bool)
+ override_if_defined('result-dir')
+ override_if_defined('create-run-dirs', bool)
+ override_if_defined('create-toolwise-dirs', bool)
+ override_if_defined('no-clean', bool)
+ override_if_defined('verbose', bool)
+
+
+def create_link(fileToLink, linkName, dry_run):
+ if dry_run:
+ return
+ if os.path.lexists(linkName):
+ os.unlink(linkName)
+ (logger.info if args.dry_run else logger.debug)('Linking %s to %s', fileToLink, linkName)
+ os.symlink(fileToLink, linkName)
+
+
+def ensure_directory(dir_name, dry_run):
+ if dry_run:
+ return
+ if not os.path.exists(dir_name):
+ logger.info('Creating %s', dir_name)
+ os.mkdir(dir_name)
+
+
+def exceeds(filename, max_size):
+ match = SIZE_PATTERN.match(filename)
+ return int(match.group(1)) > max_size if match else False
+
+
+def remove_if_there(the_list, element_to_remove):
+ if element_to_remove in the_list:
+ the_list.remove(element_to_remove)
+
+
+def new_run_name(old_run_name):
+ return RUN_PATTERN.sub(RUN_REPLACMENT, old_run_name)
+
+
+def copy_replace(fileTocopy, all_runs_dir, tool_name, run, dry_run):
+ """
+ Take fileTocopy, copy it to all_runs_dir, while replacing tool_name with run
+ in both its name and its content
+ """
+ run_name = new_run_name(run)
+ targetFile = os.path.join(
+ all_runs_dir, os.path.basename(fileTocopy).replace(tool_name, run_name))
+ first = True
+ with open(fileTocopy) as fdr_source, open(targetFile, 'w') as fdr_target:
+ for line in fdr_source:
+ if first:
+ first = False
+ else:
+ line = line.replace(tool_name, run_name)
+ fdr_target.write(line)
+
+
+def main(args):
+ """
+ Main process.
+
+ Used directory structure/variables:
+ results/ -> result_dir
+ tools/ -
+ tool1/ -> tool_dir
+ tool1-run1/ -> run_dir
+ times.csv -
+ matches.csv -
+ run-list.csv -
+ all-runs/ -> all_runs_dir
+ times-run1.csv@ -
+ run1/ -> global_run_dir
+ merged/ -> merged_dir
+ individual/ -> merged_dir_individual
+ times.csv@ -
+ combined/ -> merged_dir_benchmark
+ times.csv@ -
+ """
+ log_action = logger.info if args.dry_run else logger.debug
+
+ # Gathering paths, creating top-level directories
+ result_dir = os.path.abspath(args.result_dir)
+ merged_dir = os.path.join(result_dir, 'merged')
+ merged_dir_benchmark = os.path.join(merged_dir, 'benchmark')
+ merged_dir_individual = os.path.join(merged_dir, 'individual')
+ for dir_name in (merged_dir, merged_dir_benchmark, merged_dir_individual):
+ ensure_directory(dir_name, args.dry_run)
+
+ # Gathering tools
+ tools = []
+ reader = csv.reader(args.tools)
+ next(reader)
+ for row in reader:
+ if not row:
+ continue
+ tools.append(row[0])
+ logger.debug('result_dir: %s, tools: %s', result_dir, tools)
+
+ # Clean symlinks if requested or max_size is set
+ if (args.clean or args.max_size) and not args.dry_run:
+ for dir_to_clean in [merged_dir, merged_dir_benchmark, merged_dir_individual]:
+ for link in os.listdir(dir_to_clean):
+ linkName = os.path.join(dir_to_clean, link)
+ if os.path.islink(linkName):
+ os.unlink(linkName)
+ if (args.clean or args.create_toolwise_dirs) and not args.dry_run:
+ for linkName in glob.iglob(os.path.join(result_dir, 'tools', '*', 'all-runs', '*.csv')):
+ os.remove(linkName)
+
+ # Merge results
+ for tool in tools:
+ if tool.startswith('#'):
+ logger.debug('Ignoring tool "%s"', tool[1:])
+ continue
+ already_merged = []
+ tool_dir = os.path.join(result_dir, 'tools', tool)
+ if not os.path.exists(tool_dir):
+ logger.warn('Tool not found: %s', tool)
+ continue
+ all_runs_dir = os.path.join(tool_dir, 'all-runs')
+ ensure_directory(all_runs_dir, args.dry_run)
+ runs = sorted(os.listdir(tool_dir), reverse=True)
+ remove_if_there(runs, 'all-runs')
+ remove_if_there(runs, 'run-list.csv')
+
+ if args.create_toolwise_dirs:
+ # write out run-list.csv
+ with open(os.path.join(tool_dir, 'run-list.csv'), 'w') as fdr:
+ fdr.write('Runs\n')
+ for run in runs:
+ fdr.write(new_run_name(run) + '\n')
+
+ for run in runs:
+ run_dir = os.path.join(tool_dir, run)
+ global_run_dir = os.path.join(result_dir, run)
+ if not os.path.isdir(run_dir):
+ continue
+ ensure_directory(global_run_dir, args.dry_run)
+ for csvFile in os.listdir(run_dir):
+ # link file in run directory
+ fileToLink = os.path.join(tool_dir, run, csvFile)
+ linkName = os.path.join(global_run_dir, csvFile)
+ create_link(fileToLink, linkName, args.dry_run)
+ # skip if max-size is set and size is exceeded
+ if args.max_size and exceeds(fileToLink, args.max_size):
+ continue
+ if args.create_toolwise_dirs:
+ # link in all-runs (rename file accordingly)
+ match = NAME_PATTERN.match(csvFile)
+ if match:
+ if not BENCHMARK_PATTERN.match(csvFile):
+ tool_name = match.group(2)
+ copy_replace(fileToLink, all_runs_dir, tool_name, run, args.dry_run)
+ else:
+ logging.warn('file did not match pattern: %s', csvFile)
+ # link file in merged directory
+ if csvFile not in already_merged:
+ linkName = os.path.join(merged_dir_benchmark if BENCHMARK_PATTERN.match(csvFile)
+ else merged_dir_individual, csvFile)
+ create_link(fileToLink, linkName, args.dry_run)
+ already_merged.append(csvFile)
+ else:
+ log_action('Skipping %s', csvFile)
+
+
+if __name__ == '__main__':
+ parser = argparse.ArgumentParser(
+ description='Merge results of all benchmark runs.',
+ epilog="""The config file must contain the key "tools" specifying the tools to process.
+ It further can contain any long version of arguments to this program as a default value.
+ Any command line parameter will override such a default value.
+ Additionally, a local version of the file will be read, overriding the default values.
+ Its filename is "local-" prepended to the name of the config file.""")
+ parser.add_argument(
+ "-r", "--result-dir", help="Path to result directory to search in.", type=str)
+ parser.add_argument(
+ "-c", "--create-run-dirs", help="Whether to recreate runs directories.",
+ action="store_true")
+ parser.add_argument(
+ "-t", "--create-toolwise-dirs", help="Whether to recreate toolwise regression directories.",
+ action="store_true")
+ parser.add_argument(
+ "-d", "--dry-run", help="Only print action, don't execute them.",
+ action="store_true")
+ parser.add_argument(
+ "-n", "--no-clean", help="Don't remove previously existing symlinks in merged dir.",
+ dest='clean', action="store_false")
+ parser.add_argument(
+ "-v", "--verbose", help="Print debug messages.", action="store_true")
+ parser.add_argument(
+ "-m", "--max-size", type=int,
+ help="Maximum benchmark size to include. Implies cleaning existing symlinks.")
+ parser.add_argument(
+ "-f", "--file-config", default='merge_results.json', help="Config file to use.")
+ args = parser.parse_args()
+ include_file_config(args)
+ logging.basicConfig(format=FORMAT, level=logging.DEBUG if args.verbose else logging.INFO)
+ main(args)
diff --git a/trainbenchmark/trainbenchmark-reporting/toolwise.R b/trainbenchmark/trainbenchmark-reporting/toolwise.R
new file mode 100644
index 0000000000000000000000000000000000000000..3d0db01f39fa4eb0a3d6950c03ef4d8dd6444afc
--- /dev/null
+++ b/trainbenchmark/trainbenchmark-reporting/toolwise.R
@@ -0,0 +1,154 @@
+library(data.table)
+library(reshape2)
+library(plyr)
+library(ggplot2)
+library(ggrepel)
+library(arules)
+library(ggforce)
+
+source('util.R')
+
+args = commandArgs(trailingOnly=TRUE)
+if (length(args)==0) {
+ stop("At least one argument must be supplied (tool-name).\n", call.=FALSE)
+}
+toolName = args[1]
+
+# prepare output directory
+output_dir = paste("../diagrams/merged", toolName, sep="/")
+if (!(dir.exists(output_dir))) {
+ dir.create(output_dir)
+}
+
+# constants
+workloads = c(
+ "PosLength", "SwitchMonitored",
+ "RouteSensor", "SwitchSet",
+ "ConnectedSegments", "SemaphoreNeighbor"
+)
+phases = c("Read", "Check", "Read.and.Check", "Transformation", "Recheck", "Transformation.and.Recheck")
+phasesPrettified = c("Read", "Check", "Read and Check", "Transformation", "Recheck", "Transformation and Recheck")
+
+sizes = list() # 1 2 4 8 16 32 64 128 256 512 1024 2048 4096
+sizes[["Repair"]] = c("8k", "15k", "33k", "66k", "135k", "271k", "566k", "1.1M", "2.2M", "4.6M", "9.3M", "18M", "37M")
+
+runList = read.csv(paste("../results/tools/", toolName, "/run-list.csv", sep=""), colClasses=c(rep("character",1)))
+
+# load the data
+tsvs = list.files(paste("../results/tools/", toolName, "/all-runs/", sep=""), pattern = "times-.*\\.csv", full.names = T, recursive = T)
+
+l = lapply(tsvs, read.csv)
+times = rbindlist(l)
+
+# preprocess the data
+times$Tool = factor(times$Tool, levels = runList$Runs)
+keep_descriptions_first_char(times)
+
+times$Model = gsub("\\D+", "", times$Model)
+times$Model = as.numeric(times$Model)
+times$Time = times$Time / 10^6
+# make the phases a factor with a fixed set of values to help dcasting
+# (e.g. Batch measurements do not have Transformation and Recheck attributes,
+# hence accessing the "Transformation" attribute would throw an error)
+times$Phase = factor(times$Phase, levels = c("Read", "Check", "Transformation", "Recheck"))
+
+times.wide = dcast(data = times,
+ formula = Tool + Workload + Description + Model + Run ~ Phase,
+ value.var = "Time",
+ drop = T,
+ fun.aggregate = mean
+)
+
+# calculate aggregated values
+times.derived = times.wide
+times.derived$Read.and.Check = times.derived$Read + times.derived$Check
+times.derived$Transformation.and.Recheck = times.derived$Transformation + times.derived$Recheck
+
+# calculate the median value of runs
+times.aggregated.runs = ddply(
+ .data = times.derived,
+ .variables = c("Tool", "Workload", "Description", "Model"),
+ .fun = colwise(median),
+ .progress = "text"
+)
+# drop the "Run" column
+times.aggregated.runs = subset(times.aggregated.runs, select = -c(Run))
+
+times.processed = melt(
+ data = times.aggregated.runs,
+ id.vars = c("Tool", "Workload", "Description", "Model"),
+ measure.vars = phases,
+ variable.name = "Phase",
+ value.name = "Time"
+)
+
+# beautify plotted record:
+# 1. change dots to spaces
+# 2. make sure that the phases are still factors
+times.plot = times.processed
+times.plot$Phase = gsub('\\.', ' ', times.plot$Phase)
+times.plot$Phase = factor(times.plot$Phase, levels = phasesPrettified)
+times.plot$Workload = factor(times.plot$Workload, levels = workloads)
+
+### line charts
+for (phase in phasesPrettified) {
+ phase.filename = gsub(' ', '-', phase)
+ workloadSizes = sizes[["Repair"]]
+
+ # filter the dataframe to the current phase
+ df = times.plot[times.plot$Phase == phase, ]
+
+ # do not visualize empty data sets
+ if (nrow(df) == 0) {
+ print(paste("No rows to visualize for phase", phase))
+ next
+ }
+
+ # x axis labels
+ xbreaks = unique(df$Model)
+ currentWorkloadSizes = head(workloadSizes, n=length(xbreaks))
+ xlabels = paste(xbreaks, "\n", currentWorkloadSizes, sep = "")
+
+ # drop every other models size
+ maxLabel = max(log2(max(df$Model)), 2)
+ if (maxLabel %% 2) {
+ start = 3
+ } else {
+ start = 2
+ }
+ filter = seq(start, maxLabel, by=2)
+
+ xlabels[filter] = ""
+
+ # y axis labels
+ yaxis = nice_y_axis()
+ ybreaks = yaxis$ybreaks
+ ylabels = yaxis$ylabels
+
+ p = ggplot(df) + #na.omit(df)) +
+ aes(x = as.factor(Model), y = Time) +
+ labs(title = paste("Individual query execution time,", phase, "phase, ", toolName), x = "Model size\n#Elements", y = "Execution times [ms]") +
+ geom_point(aes(col = Tool, shape = Tool), size = 2.0) +
+ scale_shape_manual(values = seq(0, 15)) +
+ geom_line(aes(col = Tool, group = Tool), size = 0.5) +
+ scale_x_discrete(breaks = xbreaks, labels = xlabels) +
+ scale_y_log10(breaks = ybreaks, labels = ylabels) +
+ guides(color = guide_legend(ncol = 4)) +
+ theme_bw() +
+ theme(
+ plot.title = element_text(hjust = 0.5),
+ text = element_text(size = 10),
+ legend.key = element_blank(),
+ legend.title = element_blank(),
+ legend.position = "bottom",
+ axis.text = element_text(size = 9)
+ )
+ print(p)
+ for (cpage in 1:6) {
+ ggsave(
+ plot = p + facet_grid_paginate(~ Workload, nrow=1, ncol = 1, page=cpage, scale = "free"),
+ filename = paste(output_dir, "/", toolName, "-", phase.filename, "-",workloads[cpage], ".pdf", sep=""),
+ width = 250, height = 150, units = "mm"
+ )
+ }
+}
diff --git a/trainbenchmark/trainbenchmark-reporting/toolwise.py b/trainbenchmark/trainbenchmark-reporting/toolwise.py
new file mode 100644
index 0000000000000000000000000000000000000000..93a2753579af2ef62b9fd7a4cd3100f7d0cff208
--- /dev/null
+++ b/trainbenchmark/trainbenchmark-reporting/toolwise.py
@@ -0,0 +1,33 @@
+import argparse
+import json
+import logging
+import os.path
+import subprocess
+
+
+FORMAT = '%(asctime)s %(levelname)-8s %(threadName)-10s (%(filename)s:%(lineno)d): %(message)s'
+logger = logging.getLogger('toolwise')
+
+
+if __name__ == '__main__':
+ parser = argparse.ArgumentParser(description='Plot results per tool.')
+ parser.add_argument(
+ "-v", "--verbose", help="Print debug messages.", action="store_true")
+ parser.add_argument(
+ "-f", "--file-config", default='merge_results.json', help="Config file to use.")
+ args = parser.parse_args()
+ logging.basicConfig(format=FORMAT, level=logging.DEBUG if args.verbose else logging.INFO)
+ # load config file
+ with open('merge_results.json') as fdr:
+ content = json.load(fdr)
+ # update with local version, if existing
+ directory, basename = os.path.split(os.path.abspath('merge_results.json'))
+ local_config_file = os.path.join(directory, 'local-' + basename)
+ if os.path.exists(local_config_file):
+ with open(local_config_file) as fdr:
+ content.update(json.load(fdr))
+ else:
+ logger.debug('No local config file found.')
+ for tool in content.get('toolwise', []):
+ logging.info('Processing %s now.', tool)
+ subprocess.call(["Rscript", "toolwise.R", tool])
diff --git a/trainbenchmark/trainbenchmark-reporting/toolwise.sh b/trainbenchmark/trainbenchmark-reporting/toolwise.sh
new file mode 100755
index 0000000000000000000000000000000000000000..b9891085ed77d2fefa1f29149d65093e5607e0b9
--- /dev/null
+++ b/trainbenchmark/trainbenchmark-reporting/toolwise.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+python toolwise.py
+# --file-config <file>
+# --verbose
diff --git a/trainbenchmark/trainbenchmark-tool/src/main/java/hu/bme/mit/trainbenchmark/benchmark/config/BenchmarkConfigBase.java b/trainbenchmark/trainbenchmark-tool/src/main/java/hu/bme/mit/trainbenchmark/benchmark/config/BenchmarkConfigBase.java
index 8467833190a8872e79dacdf59a40b8923cbeebb8..8ac9f8c43332d12e21fd930026cc3248119238d4 100644
--- a/trainbenchmark/trainbenchmark-tool/src/main/java/hu/bme/mit/trainbenchmark/benchmark/config/BenchmarkConfigBase.java
+++ b/trainbenchmark/trainbenchmark-tool/src/main/java/hu/bme/mit/trainbenchmark/benchmark/config/BenchmarkConfigBase.java
@@ -24,7 +24,7 @@ public final class BenchmarkConfigBase extends AbstractConfigBase {
/**
* The id for the benchmark, used for determining the result directory.
*/
- protected final int benchmarkId;
+ protected final String benchmarkId;
/**
* The timeout for each measurement run in seconds.
@@ -68,7 +68,7 @@ public final class BenchmarkConfigBase extends AbstractConfigBase {
*/
protected final Optional<Integer> transformationConstant;
- protected BenchmarkConfigBase(final int benchmarkId, final long timeout, final int runs, final String modelFilename,
+ protected BenchmarkConfigBase(final String benchmarkId, final long timeout, final int runs, final String modelFilename,
final List<RailwayOperation> operations, final String workload,
final TransformationChangeSetStrategy transformationChangeSetStrategy,
final Optional<Integer> queryTransformationCount, final Optional<Integer> transformationConstant) {
@@ -84,7 +84,7 @@ public final class BenchmarkConfigBase extends AbstractConfigBase {
this.transformationConstant = transformationConstant;
}
- public int getBenchmarkId() {
+ public String getBenchmarkId() {
return benchmarkId;
}
diff --git a/trainbenchmark/trainbenchmark-tool/src/main/java/hu/bme/mit/trainbenchmark/benchmark/config/BenchmarkConfigBaseBuilder.java b/trainbenchmark/trainbenchmark-tool/src/main/java/hu/bme/mit/trainbenchmark/benchmark/config/BenchmarkConfigBaseBuilder.java
index 03fb69424a80bf657b84135f5034dba2f00c5194..6e5b1d23253344b852bdf14d7ed017b183182adc 100644
--- a/trainbenchmark/trainbenchmark-tool/src/main/java/hu/bme/mit/trainbenchmark/benchmark/config/BenchmarkConfigBaseBuilder.java
+++ b/trainbenchmark/trainbenchmark-tool/src/main/java/hu/bme/mit/trainbenchmark/benchmark/config/BenchmarkConfigBaseBuilder.java
@@ -8,7 +8,7 @@ import com.google.common.base.Preconditions;
import hu.bme.mit.trainbenchmark.constants.RailwayOperation;
public final class BenchmarkConfigBaseBuilder {
- private Integer benchmarkId;
+ private String benchmarkId;
private Long timeout;
private Integer runs;
private String modelFilename;
@@ -65,7 +65,7 @@ public final class BenchmarkConfigBaseBuilder {
return this;
}
- public BenchmarkConfigBaseBuilder setBenchmarkId(final Integer benchmarkId) {
+ public BenchmarkConfigBaseBuilder setBenchmarkId(final String benchmarkId) {
this.benchmarkId = benchmarkId;
return this;
}
diff --git a/trainbenchmark/trainbenchmark-tool/src/main/java/hu/bme/mit/trainbenchmark/benchmark/result/AbstractResult.java b/trainbenchmark/trainbenchmark-tool/src/main/java/hu/bme/mit/trainbenchmark/benchmark/result/AbstractResult.java
index a8143f187ebb36a11ba38191840fdff32191b03d..f2a13294252520192b52c0b2a544adca7c009310 100644
--- a/trainbenchmark/trainbenchmark-tool/src/main/java/hu/bme/mit/trainbenchmark/benchmark/result/AbstractResult.java
+++ b/trainbenchmark/trainbenchmark-tool/src/main/java/hu/bme/mit/trainbenchmark/benchmark/result/AbstractResult.java
@@ -2,6 +2,7 @@ package hu.bme.mit.trainbenchmark.benchmark.result;
import java.io.File;
import java.io.IOException;
+import java.nio.charset.Charset;
import org.apache.commons.io.FileUtils;
@@ -24,8 +25,9 @@ public abstract class AbstractResult {
protected final String MODEL = "Model";
protected final String RUN = "Run";
- protected final int benchmarkId;
+ protected final String benchmarkId;
protected final String toolName;
+ protected final String projectName;
protected final String workload;
protected final String workspaceDir;
protected final String model;
@@ -34,6 +36,7 @@ public abstract class AbstractResult {
public AbstractResult(final BenchmarkConfig bc) {
this.benchmarkId = bc.getConfigBase().getBenchmarkId();
this.toolName = bc.getToolName();
+ this.projectName = bc.getProjectName();
this.workload = bc.getConfigBase().getWorkload();
this.workspaceDir = bc.getConfigBase().getWorkspaceDir();
this.model = bc.getConfigBase().getModelFilename();
@@ -41,13 +44,15 @@ public abstract class AbstractResult {
}
public void serializeCsv(final String csv, final String filePrefix) throws IOException {
- final String matchesCsvPath = String.format("%s/%s-%s-%s-%s-%s.csv", getResultDir(), filePrefix, toolName,
- workload, model, description);
- FileUtils.write(new File(matchesCsvPath), csv);
+ File targetDir = ResultHelper.getResultDirectory(projectName, benchmarkId);
+ String fileName = String.format("%s-%s-%s-%s-%s.csv", filePrefix, toolName, workload, model, description);
+// final String matchesCsvPath = String.format("%s/%s-%s-%s-%s-%s.csv", getResultDir(), filePrefix, toolName,
+// workload, model, description);
+ FileUtils.write(FileUtils.getFile(targetDir, fileName), csv, Charset.defaultCharset());
}
- public String getResultDir() {
- return workspaceDir + ResultHelper.getResultDirForId(benchmarkId);
- }
+// public String getResultDir() {
+// return workspaceDir + ResultHelper.getResultDirForId(benchmarkId);
+// }
}
diff --git a/trainbenchmark/trainbenchmark-tool/src/main/java/hu/bme/mit/trainbenchmark/benchmark/result/ResultHelper.java b/trainbenchmark/trainbenchmark-tool/src/main/java/hu/bme/mit/trainbenchmark/benchmark/result/ResultHelper.java
index 56ca0bbedf4cbe7ffd982a478514efb1aec758d2..737335677b1848f11ccc2e48259ffbeca4e9a694 100644
--- a/trainbenchmark/trainbenchmark-tool/src/main/java/hu/bme/mit/trainbenchmark/benchmark/result/ResultHelper.java
+++ b/trainbenchmark/trainbenchmark-tool/src/main/java/hu/bme/mit/trainbenchmark/benchmark/result/ResultHelper.java
@@ -3,8 +3,15 @@ package hu.bme.mit.trainbenchmark.benchmark.result;
import java.io.File;
import java.io.IOException;
import java.nio.file.*;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
import java.util.Arrays;
+import java.util.Collection;
+import java.util.Date;
+import hu.bme.mit.trainbenchmark.benchmark.config.BenchmarkConfig;
+import hu.bme.mit.trainbenchmark.benchmark.config.BenchmarkConfigBuilder;
+import hu.bme.mit.trainbenchmark.config.ExecutionConfig;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
@@ -12,6 +19,7 @@ public final class ResultHelper {
public static final String WORKSPACE_DIR = "../";
public static final String RESULT_DIR = "results/";
+ public static final String TOOLS_DIR = "tools/";
public static final String DIAGRAM_DIR = "diagrams/";
public static final String SCRIPT_PATH = WORKSPACE_DIR + "trainbenchmark-scripts/src/";
public static final String BENCHMARK_SCRIPT = "BenchmarkScript.groovy";
@@ -94,4 +102,38 @@ public final class ResultHelper {
FileUtils.copyFile(srcFile, destFile);
}
+ public static void createNewResultDirs(Collection<BenchmarkConfigBuilder<? extends BenchmarkConfig, ? extends BenchmarkConfigBuilder<?, ?>>> tools) {
+ }
+
+ /**
+ * Prepare a benchmark run, i.e., creates necessary directories. This operation is idempotent.
+ * @param config the benchmark configuration
+ * @param ec the execution configuration
+ */
+ public static void prepare(BenchmarkConfig config, ExecutionConfig ec) {
+ // ensure directory for the tool
+ File toolDir = getToolDirectory(config.getProjectName());
+ toolDir.mkdir();
+ // ensure directory for the run inside toolDir
+ File runDir = getResultDirectory(toolDir, config.getConfigBase().getBenchmarkId());
+ runDir.mkdir();
+ }
+
+ public static String getNow() {
+ DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
+ return dateFormat.format(new Date());
+ }
+
+ public static File getToolDirectory(String projectName) {
+ return FileUtils.getFile(WORKSPACE_DIR, RESULT_DIR, TOOLS_DIR, projectName);
+ }
+
+ public static File getResultDirectory(File toolDirectory, String benchmarkId) {
+ return FileUtils.getFile(toolDirectory, "run-" + benchmarkId);
+ }
+
+ public static File getResultDirectory(String projectName, String benchmarkId) {
+ return getResultDirectory(getToolDirectory(projectName), benchmarkId);
+ }
+
}
diff --git a/trainbenchmark/trainbenchmark-tool/src/main/java/hu/bme/mit/trainbenchmark/benchmark/runcomponents/BenchmarkRunner.java b/trainbenchmark/trainbenchmark-tool/src/main/java/hu/bme/mit/trainbenchmark/benchmark/runcomponents/BenchmarkRunner.java
index 9136edcca823a519a228c863d31ec4b1aaada6c4..06d8bb80862e12e22e66e9c30b3742560367c0b4 100644
--- a/trainbenchmark/trainbenchmark-tool/src/main/java/hu/bme/mit/trainbenchmark/benchmark/runcomponents/BenchmarkRunner.java
+++ b/trainbenchmark/trainbenchmark-tool/src/main/java/hu/bme/mit/trainbenchmark/benchmark/runcomponents/BenchmarkRunner.java
@@ -11,14 +11,38 @@ import org.apache.commons.exec.Executor;
import org.apache.commons.exec.PumpStreamHandler;
import com.google.common.base.Joiner;
-
+import com.google.common.collect.ImmutableMap;
import hu.bme.mit.trainbenchmark.benchmark.config.BenchmarkConfig;
import hu.bme.mit.trainbenchmark.benchmark.memory.MemoryResult;
import hu.bme.mit.trainbenchmark.config.ExecutionConfig;
+import org.apache.commons.exec.*;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Map;
public class BenchmarkRunner {
- public static int runPerformanceBenchmark(final BenchmarkConfig bc, final ExecutionConfig ec)
+ public static String dictFormat(String format, Map<String, Object> values) {
+ StringBuilder convFormat = new StringBuilder(format);
+ ArrayList<Object> valueList = new ArrayList<>();
+ int currentPos = 1;
+ for (String key : values.keySet()) {
+ String formatKey = "%(" + key + ")",
+ formatPos = "%" + Integer.toString(currentPos) + "$1s";
+ int index = -1;
+ while ((index = convFormat.indexOf(formatKey, index)) != -1) {
+ convFormat.replace(index, index + formatKey.length(), formatPos);
+ index += formatPos.length();
+ }
+ valueList.add(values.get(key));
+ ++currentPos;
+ }
+ return String.format(convFormat.toString(), valueList.toArray());
+ }
+
+ public static int runPerformanceBenchmark(final BenchmarkConfig bc, final ExecutionConfig ec, String jvmSetting)
throws IOException, InterruptedException {
final Joiner joiner = Joiner.on(", ");
System.out.println("Running benchmark.");
@@ -38,9 +62,17 @@ public class BenchmarkRunner {
final String jarPath = String.format("../%s/build/libs/%s-1.0.0-SNAPSHOT-fat.jar %s", projectName, projectName,
configPath);
- final String javaCommand = String.format("java -Xms%s -Xmx%s -server -Xverify:none -jar %s %s", ec.getXms(), ec.getXmx(), jarPath, configPath);
+ final String javaCommand = dictFormat("java " + jvmSetting + " -jar %(jarPath) %(configPath)",
+ ImmutableMap.of("Xms", ec.getXms(), "Xmx", ec.getXmx(),
+ "jarPath", jarPath, "configPath", configPath));
+
+// final String javaCommand = String.format("java -Xms%s -Xmx%s -server -Xverify:none -jar %s %s", ec.getXms(), ec.getXmx(), jarPath, configPath);
// final String javaCommand = String.format("java -Xms%s -Xmx%s -server -XX:+UnlockCommercialFeatures -XX:+FlightRecorder -XX:StartFlightRecording=dumponexit=true -Xverify:none -jar %s %s", ec.getXms(), ec.getXmx(), jarPath, configPath);
final CommandLine cmdLine = CommandLine.parse(javaCommand);
+ if (ec.getDryRun()) {
+ System.out.println("Would have executed: "+ cmdLine.toString());
+ return 0;
+ }
final long timeoutInSeconds = bc.getConfigBase().getTimeout();
final long timeoutInMilliseconds = timeoutInSeconds * 1000;
@@ -63,7 +95,7 @@ public class BenchmarkRunner {
}
public static int runMemoryBenchmark(final BenchmarkConfig bc, final ExecutionConfig defaultEc,
- final int numberOfSteps) throws IOException, InterruptedException {
+ final int numberOfSteps, String jvmSetting) throws IOException, InterruptedException {
// e.g. initialMaxMemory = 12800, we save this (as a final variable), so
// that we will not exceed it
//
@@ -79,7 +111,7 @@ public class BenchmarkRunner {
memoryQuantum /= 2;
final ExecutionConfig ec = new ExecutionConfig(currentMaxMemory, currentMaxMemory);
- if (runPerformanceBenchmark(bc, ec) == 0) {
+ if (runPerformanceBenchmark(bc, ec, jvmSetting) == 0) {
System.out.println("Execution finished, testing with less memory.");
System.out.println();
currentMaxMemory -= memoryQuantum;
diff --git a/trainbenchmark/trainbenchmark-tool/src/main/java/hu/bme/mit/trainbenchmark/benchmark/test/TrainBenchmarkTest.java b/trainbenchmark/trainbenchmark-tool/src/main/java/hu/bme/mit/trainbenchmark/benchmark/test/TrainBenchmarkTest.java
index da4721781f6fffb5136e7780d2cd41f6da93c6da..d8ac00dd5b0e3464cae1cc1d919e46ad59bca0eb 100644
--- a/trainbenchmark/trainbenchmark-tool/src/main/java/hu/bme/mit/trainbenchmark/benchmark/test/TrainBenchmarkTest.java
+++ b/trainbenchmark/trainbenchmark-tool/src/main/java/hu/bme/mit/trainbenchmark/benchmark/test/TrainBenchmarkTest.java
@@ -23,7 +23,7 @@ public abstract class TrainBenchmarkTest {
@Rule
public ErrorCollector collector = new ErrorCollector();
- protected final int benchmarkId = 0;
+ protected final String benchmarkId = "";
protected ExecutionConfig executionConfig = ExecutionConfig.defaultExecutionConfig();
protected final long timeout = 120;
protected final int runs = 1;
diff --git a/trainbenchmark/trainbenchmark-tool/src/main/java/hu/bme/mit/trainbenchmark/benchmark/test/queryspecific/QueryTest.java b/trainbenchmark/trainbenchmark-tool/src/main/java/hu/bme/mit/trainbenchmark/benchmark/test/queryspecific/QueryTest.java
index 4046712c480f14d106115bbea029fe14539d997b..f616b63636e4b2c5cd8a827177fb43b092a29da7 100644
--- a/trainbenchmark/trainbenchmark-tool/src/main/java/hu/bme/mit/trainbenchmark/benchmark/test/queryspecific/QueryTest.java
+++ b/trainbenchmark/trainbenchmark-tool/src/main/java/hu/bme/mit/trainbenchmark/benchmark/test/queryspecific/QueryTest.java
@@ -11,7 +11,7 @@ import hu.bme.mit.trainbenchmark.config.ExecutionConfig;
public abstract class QueryTest {
- protected final int benchmarkId = 0;
+ protected final String benchmarkId = "";
protected ExecutionConfig executionConfig = ExecutionConfig.defaultExecutionConfig();
protected final long timeout = 120;
protected final int runs = 1;