From f12020c6718e7de28bab125a4608b47f7e38f59b Mon Sep 17 00:00:00 2001 From: Reiner Jung <reiner.jung@email.uni-kiel.de> Date: Wed, 31 Aug 2022 13:21:53 +0200 Subject: [PATCH] Updated compile results tool, not finished yet. --- test.rc | 2 + tools/compile-results/build.gradle | 2 +- tools/compile-results/design.rst | 58 +++++++++++++++ .../tools/results/CompileResultsMain.java | 54 ++++++++++++++ .../tools/results/ElementProducer.java | 32 ++++++++ .../tools/results/LogAppenderStage.java | 66 +++++++++++++++++ .../tools/results/SummarizeResultsMain.java | 74 ------------------- .../tools/results/TeetimeConfiguration.java | 41 +++++----- .../moobench/tools/results/YamlLogSink.java | 13 ++++ .../tools/results/YamlReaderStage.java | 24 ++++++ .../tools/results/data/Experiment.java | 38 ++++++++++ .../tools/results/data/ExperimentLog.java | 26 +++++++ .../tools/results/data/Measurements.java | 63 ++++++++++++++++ 13 files changed, 401 insertions(+), 92 deletions(-) create mode 100644 tools/compile-results/design.rst create mode 100644 tools/compile-results/src/main/java/moobench/tools/results/CompileResultsMain.java create mode 100644 tools/compile-results/src/main/java/moobench/tools/results/ElementProducer.java create mode 100644 tools/compile-results/src/main/java/moobench/tools/results/LogAppenderStage.java delete mode 100644 tools/compile-results/src/main/java/moobench/tools/results/SummarizeResultsMain.java create mode 100644 tools/compile-results/src/main/java/moobench/tools/results/YamlLogSink.java create mode 100644 tools/compile-results/src/main/java/moobench/tools/results/YamlReaderStage.java create mode 100644 tools/compile-results/src/main/java/moobench/tools/results/data/Experiment.java create mode 100644 tools/compile-results/src/main/java/moobench/tools/results/data/ExperimentLog.java create mode 100644 tools/compile-results/src/main/java/moobench/tools/results/data/Measurements.java diff --git a/test.rc b/test.rc index 87bfb6d..a4b5bfe 100644 --- a/test.rc +++ b/test.rc @@ -1,3 +1,5 @@ +MOOBENCH_ARCHIVE="${BASE_DIR}/tools/benchmark/build/distributions/benchmark.tar" + export SLEEP_TIME=10 export NUM_OF_LOOPS=1 export THREADS=1 diff --git a/tools/compile-results/build.gradle b/tools/compile-results/build.gradle index 571174c..95fff6a 100644 --- a/tools/compile-results/build.gradle +++ b/tools/compile-results/build.gradle @@ -4,7 +4,7 @@ plugins { } application { - mainClass = 'moobench.tools.results.SummarizeResultsMain' + mainClass = 'moobench.tools.results.CompileResultsMain' } dependencies { diff --git a/tools/compile-results/design.rst b/tools/compile-results/design.rst new file mode 100644 index 0000000..8d88a60 --- /dev/null +++ b/tools/compile-results/design.rst @@ -0,0 +1,58 @@ +Compile Results +=============== + +Compile results reads in a set of YAML-files, appends them to longer YAML-logs, +creates a JSON-file over the last N builds and outputs a set of data to be +displayed in a HTML table. + +Parameter +--------- + +-i input paths (multiple path) +-l log path (one path, the individual log paths will be computed from the input paths) +-w window length in number of builds +-t path for table +-j json output + +Log Paths +--------- + +log_file_path = log path + "/all-" + basename(input path) + +Pipeline +-------- + +ElementProducer :: yamlInputPathsProducer +ElementProducer :: yamlLogPathsProducer + +YamlReaderStage :: yamlInputReaderStage +YamlReaderStage :: yamlLogReaderStage + +LogAppender :: logAppender +Distributor :: distributor + +YamlLogSink :: yamlLogSink +ChartAssemblerStage :: chartAssemblerStage +JsonLogSink :: jsonLogSink +GenerateHtmlTable :: generateHtmlTable +FileSink :: fileSink + +yamlInputPathsProducer -> yamlInputReaderStage -> logAppender.newRecord +yamlLogPathsProducer -> yamlLogReaderStage -> logAppender.log + +logAppender.output -- log -> distributor +distributor -> yamlLogSink +distributor -> chartAssemblerStage -> jsonLogSink +distributor -> generateHtmlTable -> fileSink + +Data Structure +-------------- + +Log +- string name +- List<Entry> entries + +Entry +- long timestamp +- Map<String, List<Double>> + diff --git a/tools/compile-results/src/main/java/moobench/tools/results/CompileResultsMain.java b/tools/compile-results/src/main/java/moobench/tools/results/CompileResultsMain.java new file mode 100644 index 0000000..8035cf4 --- /dev/null +++ b/tools/compile-results/src/main/java/moobench/tools/results/CompileResultsMain.java @@ -0,0 +1,54 @@ +/** + * + */ +package moobench.tools.results; + +import java.io.File; +import java.nio.file.Files; +import java.nio.file.Path; + +import com.beust.jcommander.JCommander; + +import kieker.common.configuration.Configuration; +import kieker.common.exception.ConfigurationException; +import kieker.tools.common.AbstractService; + +/** + * Read the CSV output of the R script and the existing JSON file and append a + * record to the JSON file based on the CSV dataset. Further compute a list of + * the last 50 runs and the last relative values. + * + * @author Reiner Jung + * + */ +public class CompileResultsMain extends AbstractService<TeetimeConfiguration, Settings> { + + public static void main(final String[] args) { + final CompileResultsMain main = new CompileResultsMain(); + System.exit(main.run("compile-result", "Compile Results", args, new Settings())); + } + + @Override + protected TeetimeConfiguration createTeetimeConfiguration() throws ConfigurationException { + return new TeetimeConfiguration(this.parameterConfiguration); + } + + @Override + protected File getConfigurationFile() { + return null; + } + + @Override + protected boolean checkConfiguration(Configuration configuration, JCommander commander) { + return true; + } + + @Override + protected boolean checkParameters(JCommander commander) throws ConfigurationException { + return true; + } + + @Override + protected void shutdownService() { + } +} diff --git a/tools/compile-results/src/main/java/moobench/tools/results/ElementProducer.java b/tools/compile-results/src/main/java/moobench/tools/results/ElementProducer.java new file mode 100644 index 0000000..3695517 --- /dev/null +++ b/tools/compile-results/src/main/java/moobench/tools/results/ElementProducer.java @@ -0,0 +1,32 @@ +/** + * + */ +package moobench.tools.results; + +import java.util.List; + +import teetime.framework.AbstractProducerStage; + +/** + * @author Reiner Jung + * @param <O> + * @since 1.3.0 + * + * @param <O> type of the elements + */ +public class ElementProducer<O> extends AbstractProducerStage<O> { + + private List<O> elements; + + public ElementProducer(List<O> elements) { + this.elements = elements; + } + + @Override + protected void execute() throws Exception { + for (O element : elements) { + this.outputPort.send(element); + } + } + +} diff --git a/tools/compile-results/src/main/java/moobench/tools/results/LogAppenderStage.java b/tools/compile-results/src/main/java/moobench/tools/results/LogAppenderStage.java new file mode 100644 index 0000000..0c7f466 --- /dev/null +++ b/tools/compile-results/src/main/java/moobench/tools/results/LogAppenderStage.java @@ -0,0 +1,66 @@ +/** + * + */ +package moobench.tools.results; + +import java.util.Map; + +import moobench.tools.results.data.Experiment; +import moobench.tools.results.data.ExperimentLog; +import teetime.framework.AbstractStage; +import teetime.framework.InputPort; +import teetime.framework.OutputPort; + +/** + * @author Reiner Jung + * @since 1.3.0 + */ +public class LogAppenderStage extends AbstractStage { + + private final InputPort<ExperimentLog> newDataInputPort = this.createInputPort(ExperimentLog.class); + private final InputPort<ExperimentLog> logInputPort = this.createInputPort(ExperimentLog.class); + private final OutputPort<ExperimentLog> outputPort = this.createOutputPort(ExperimentLog.class); + + private Map<String,ExperimentLog> logs; + + public InputPort<ExperimentLog> getNewDataInputPort() { + return newDataInputPort; + } + + public InputPort<ExperimentLog> getLogInputPort() { + return logInputPort; + } + + public OutputPort<ExperimentLog> getOutputPort() { + return outputPort; + } + + @Override + protected void execute() throws Exception { + ExperimentLog newData = this.newDataInputPort.receive(); + if (newData != null) { + appendData(newData); + } + ExperimentLog logData = this.logInputPort.receive(); + if (logData != null) { + appendData(logData); + } + } + + private void appendData(ExperimentLog newData) { + ExperimentLog presentLog = logs.get(newData.getKind()); + if (presentLog != null) { + for (Experiment experiment : newData.getExperiments()) { + presentLog.getExperiments().add(experiment); + } + } + } + + @Override + protected void onTerminating() { + for (ExperimentLog experimentLog : logs.values()) { + this.outputPort.send(experimentLog); + } + super.onTerminating(); + } +} diff --git a/tools/compile-results/src/main/java/moobench/tools/results/SummarizeResultsMain.java b/tools/compile-results/src/main/java/moobench/tools/results/SummarizeResultsMain.java deleted file mode 100644 index f12a692..0000000 --- a/tools/compile-results/src/main/java/moobench/tools/results/SummarizeResultsMain.java +++ /dev/null @@ -1,74 +0,0 @@ -/** - * - */ -package moobench.tools.results; - -import java.io.File; -import java.nio.file.Files; -import java.nio.file.Path; - -import com.beust.jcommander.JCommander; - -import kieker.common.configuration.Configuration; -import kieker.common.exception.ConfigurationException; -import kieker.tools.common.AbstractService; - -/** - * Read the CSV output of the R script and the existing JSON file and append a - * record to the JSON file based on the CSV dataset. Further compute a list of - * the last 50 runs and the last relative values. - * - * @author Reiner Jung - * - */ -public class SummarizeResultsMain extends AbstractService<TeetimeConfiguration, Settings> { - - public static void main(final String[] args) { - final SummarizeResultsMain main = new SummarizeResultsMain(); - System.exit(main.run("summarize-result", "Summarize Results", args, new Settings())); - } - - @Override - protected TeetimeConfiguration createTeetimeConfiguration() throws ConfigurationException { - return new TeetimeConfiguration(this.parameterConfiguration); - } - - @Override - protected File getConfigurationFile() { - return null; - } - - @Override - protected boolean checkConfiguration(Configuration configuration, JCommander commander) { - return true; - } - - @Override - protected boolean checkParameters(JCommander commander) throws ConfigurationException { - if (!Files.exists(this.parameterConfiguration.getMainLogJson().getParent())) { - this.logger.error("Main log does not exist {}", this.parameterConfiguration.getMainLogJson().toString()); - return false; - } else if (!Files.exists(this.parameterConfiguration.getMainLogJson())) { - this.logger.info("Main log file does not exist, creating one {}", this.parameterConfiguration.getMainLogJson().toString()); - } - if (!Files.isDirectory(this.parameterConfiguration.getPartialLogJson().getParent())) { - this.logger.error("Partial log directory does not exist {}", this.parameterConfiguration.getPartialLogJson().getParent().toString()); - return false; - } - for (Path path : parameterConfiguration.getResultCsvPaths()) { - if (!Files.exists(this.parameterConfiguration.getMainLogJson())) { - this.logger.error("Experiment data file does not exist {}", path.toString()); - return false; - } - } - if (!Files.exists(this.parameterConfiguration.getMappingFile())) { - this.logger.error("Mapping file does not exist {}", this.parameterConfiguration.getMappingFile().toString()); - return false; - } - return true; - } - - @Override - protected void shutdownService() { - } -} diff --git a/tools/compile-results/src/main/java/moobench/tools/results/TeetimeConfiguration.java b/tools/compile-results/src/main/java/moobench/tools/results/TeetimeConfiguration.java index 68dafd0..8232d5c 100644 --- a/tools/compile-results/src/main/java/moobench/tools/results/TeetimeConfiguration.java +++ b/tools/compile-results/src/main/java/moobench/tools/results/TeetimeConfiguration.java @@ -7,6 +7,7 @@ import java.util.Map; import com.fasterxml.jackson.databind.JsonNode; +import moobench.tools.results.data.ExperimentLog; import teetime.framework.Configuration; import teetime.stage.basic.distributor.Distributor; import teetime.stage.basic.distributor.strategy.CopyByReferenceStrategy; @@ -21,22 +22,28 @@ public class TeetimeConfiguration extends Configuration { ElementProducer<Path> yamlInputPathsProducer = new ElementProducer<>(settings.getInputPaths()); ElementProducer<Path> yamlLogPathsProducer = new ElementProducer<>(logFilePaths); - - LogAppender :: logAppender - Distributor :: distributor - - YamlLogSink :: yamlLogSink - ChartAssemblerStage :: chartAssemblerStage - JsonLogSink :: jsonLogSink - GenerateHtmlTable :: generateHtmlTable - FileSink :: fileSink - - yamlInputPathsProducer -> logAppender.newRecord - yamlLogPathsProducer -> logAppender.log - - logAppender.output -- log -> distributor - distributor -> yamlLogSink - distributor -> chartAssemblerStage -> jsonLogSink - distributor -> generateHtmlTable -> fileSink + + YamlReaderStage yamlInputReader = new YamlReaderStage(); + YamlReaderStage yamlLogReader = new YamlReaderStage(); + + LogAppenderStage logAppenderStage = new LogAppenderStage(); + Distributor<ExperimentLog> distributor = new Distributor<>(new CopyByReferenceStrategy()); + + YamlLogSink yamlLogSink = new YamlLogSink(); + + //ChartAssemblerStage :: chartAssemblerStage + //JsonLogSink :: jsonLogSink + //GenerateHtmlTable :: generateHtmlTable + //FileSink :: fileSink + + this.connectPorts(yamlInputPathsProducer.getOutputPort(), yamlInputReader.getInputPort()); + this.connectPorts(yamlLogPathsProducer.getOutputPort(), yamlLogReader.getInputPort()); + + this.connectPorts(yamlInputReader.getOutputPort(), logAppenderStage.getNewDataInputPort()); + this.connectPorts(yamlLogReader.getOutputPort(), logAppenderStage.getLogInputPort()); + + this.connectPorts(logAppenderStage.getOutputPort(), distributor.getInputPort()); + + this.connectPorts(distributor.getNewOutputPort(), yamlLogSink.getInputPort()); } } diff --git a/tools/compile-results/src/main/java/moobench/tools/results/YamlLogSink.java b/tools/compile-results/src/main/java/moobench/tools/results/YamlLogSink.java new file mode 100644 index 0000000..7603550 --- /dev/null +++ b/tools/compile-results/src/main/java/moobench/tools/results/YamlLogSink.java @@ -0,0 +1,13 @@ +package moobench.tools.results; + +import moobench.tools.results.data.ExperimentLog; +import teetime.framework.AbstractConsumerStage; + +public class YamlLogSink extends AbstractConsumerStage<ExperimentLog> { + + @Override + protected void execute(ExperimentLog element) throws Exception { + // TODO Auto-generated method stub + } + +} diff --git a/tools/compile-results/src/main/java/moobench/tools/results/YamlReaderStage.java b/tools/compile-results/src/main/java/moobench/tools/results/YamlReaderStage.java new file mode 100644 index 0000000..e64b2e5 --- /dev/null +++ b/tools/compile-results/src/main/java/moobench/tools/results/YamlReaderStage.java @@ -0,0 +1,24 @@ +package moobench.tools.results; + +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; + +import org.yaml.snakeyaml.Yaml; +import org.yaml.snakeyaml.constructor.Constructor; + +import moobench.tools.results.data.ExperimentLog; +import teetime.stage.basic.AbstractTransformation; + +public class YamlReaderStage extends AbstractTransformation<Path, ExperimentLog> { + + @Override + protected void execute(Path path) throws Exception { + Yaml yaml = new Yaml(new Constructor(ExperimentLog.class)); + InputStream inputStream = Files.newInputStream(path); + ExperimentLog data = yaml.load(inputStream); + + this.outputPort.send(data); + } + +} diff --git a/tools/compile-results/src/main/java/moobench/tools/results/data/Experiment.java b/tools/compile-results/src/main/java/moobench/tools/results/data/Experiment.java new file mode 100644 index 0000000..d08c2dc --- /dev/null +++ b/tools/compile-results/src/main/java/moobench/tools/results/data/Experiment.java @@ -0,0 +1,38 @@ +/** + * + */ +package moobench.tools.results.data; + +import java.util.HashMap; +import java.util.Map; + +/** + * @author Reiner Jung + * + */ +public class Experiment { + + double timestamp; + Map<String,Measurements> measurements = new HashMap<>(); + + public double getTimestamp() { + return timestamp; + } + + public void setTimestamp(double timestamp) { + this.timestamp = timestamp; + } + + public Map<String,Measurements> getMeasurements() { + return measurements; + } + public void setMeasurements(Map<String,Measurements> measurements) { + this.measurements = measurements; + } + + @Override + public String toString() { + return String.format("time: %f, measurements: %d\n", timestamp, measurements.size()); + } + +} diff --git a/tools/compile-results/src/main/java/moobench/tools/results/data/ExperimentLog.java b/tools/compile-results/src/main/java/moobench/tools/results/data/ExperimentLog.java new file mode 100644 index 0000000..e619816 --- /dev/null +++ b/tools/compile-results/src/main/java/moobench/tools/results/data/ExperimentLog.java @@ -0,0 +1,26 @@ +package moobench.tools.results.data; + +import java.util.ArrayList; +import java.util.List; + +public class ExperimentLog { + + String kind; + List<Experiment> experiments = new ArrayList<>(); + + public String getKind() { + return kind; + } + + public void setKind(String kind) { + this.kind = kind; + } + + public List<Experiment> getExperiments() { + return experiments; + } + + public void setExperiments(List<Experiment> experiments) { + this.experiments = experiments; + } +} diff --git a/tools/compile-results/src/main/java/moobench/tools/results/data/Measurements.java b/tools/compile-results/src/main/java/moobench/tools/results/data/Measurements.java new file mode 100644 index 0000000..e6d1dc8 --- /dev/null +++ b/tools/compile-results/src/main/java/moobench/tools/results/data/Measurements.java @@ -0,0 +1,63 @@ +package moobench.tools.results.data; + +public class Measurements { + + private double mean; + private double convidence; + private double standardDeviation; + private double lowerQuartile; + private double median; + private double upperQuartile; + private double max; + private double min; + + public Measurements(double mean, double standardDeviation, double convidence, double lowerQuartile, double median, double upperQuartile, double min, double max) { + this.mean = mean; + this.convidence = convidence; + this.standardDeviation = standardDeviation; + this.lowerQuartile = lowerQuartile; + this.median = median; + this.upperQuartile = upperQuartile; + this.min = min; + this.max = max; + } + + public double getMean() { + return mean; + } + + /** + * Returns the convidence value, to get the convidence interval you need to compute the interval as + * [mean-convidence:mean+convidence] + * + * @return convidence value + */ + public double getConvidence() { + return convidence; + } + + public double getStandardDeviation() { + return standardDeviation; + } + + public double getLowerQuartile() { + return lowerQuartile; + } + + public double getMedian() { + return median; + } + + public double getUpperQuartile() { + return upperQuartile; + } + + public double getMin() { + return min; + } + + public double getMax() { + return max; + } + +} -- GitLab