Skip to content

Commit

Permalink
Merge branch 'feature/statistics' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
maxkratz committed Jul 28, 2021
2 parents 025b149 + 00d3f78 commit 1823349
Show file tree
Hide file tree
Showing 9 changed files with 454 additions and 30 deletions.
2 changes: 1 addition & 1 deletion network.model.rules/src/gt/PatternMatchingConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public enum PatternMatcher {
}

/**
* Pattern matching mechanism for the {@link VnePmMdvneAlgorithm}.
* Pattern matching mechanism for the VnePmMdvneAlgorithm.
*/
public static PatternMatcher pm = PatternMatcher.HIPE;

Expand Down
11 changes: 11 additions & 0 deletions statistics/.classpath
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-13">
<attributes>
<attribute name="module" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" path="src"/>
<classpathentry combineaccessrules="false" kind="src" path="/vne.scenarios"/>
<classpathentry kind="output" path="bin"/>
</classpath>
17 changes: 17 additions & 0 deletions statistics/.project
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>statistics</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>
1 change: 1 addition & 0 deletions statistics/resources/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*.csv
Empty file added statistics/resources/.gitkeep
Empty file.
116 changes: 116 additions & 0 deletions statistics/src/statistics/Runner.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
package statistics;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import scenario.util.CsvUtil;

/**
* Runner class to combine multiple CSV files containing measurements to one statistic CSV file
* containing the mean and the standard derivation.
*
* @author Maximilian Kratz {@literal <[email protected]>}
*/
public class Runner {

// TODO: Find a way to dynamically determine upper limit (e.g., by using 'find')
/**
* Number of experiments (= runs).
*/
private static final int NUM_OF_EXPS = 3;

/**
* Private constructor ensures no object instantiation.
*/
private Runner() {}

/**
* Main method to start the runner. Argument must contain the base name of the experiment to load
* metric files from, e.g., 'pm_fat-tree-4-pods_l3_k2'.
*
* @param args Arguments to parse, i.e., args[0] must hold the experiment's name to load.
*/
public static void main(final String[] args) {
if (args == null || args.length < 1) {
throw new IllegalArgumentException("Please specify the experiment name to load files from.");
}

final String expName = args[0];

//
// Statistics CSV file
//

final List<List<Double[]>> data = new LinkedList<List<Double[]>>();

for (int i = 1; i <= NUM_OF_EXPS; i++) {
final List<Double[]> line = CsvUtil.loadCsvFile(expName + "_run" + i + ".csv");
data.add(line);
}

final String outputName = expName + "_stats.csv";

// Currently, the number of metrics is hard-coded against CsvUtil.java
double[] outputMean = new double[18];
double[] outputStdDev = new double[18];

// Iterate over all lines of the files
for (int v = 0; v < data.get(0).size(); v++) {
// Iterate over all metrics
for (int i = 0; i < 18; i++) {
final Double[] values = new Double[data.size()];

// Iterate over the data sets (= files)
for (int f = 0; f < data.size(); f++) {
values[f] = data.get(f).get(v)[i];
}

// Calculate values
outputMean[i] = StatisticUtils.mean(values);
outputStdDev[i] = StatisticUtils.stdDev(values);
}

// Write line to statistic CSV file
final String[] line = StatisticUtils.assembleCsvLine(v, outputMean, outputStdDev);
CsvUtil.appendCsvStatsLine(outputName, line);
}

//
// Time summing CSV file
//

final Map<String, Double[]> timeSums = new HashMap<String, Double[]>();
timeSums.put("time_total", new Double[3]);
timeSums.put("time_pm", new Double[3]);
timeSums.put("time_ilp", new Double[3]);
timeSums.put("time_deploy", new Double[3]);
timeSums.put("time_rest", new Double[3]);

for (final String key : timeSums.keySet()) {
for (int i = 0; i < timeSums.get(key).length; i++) {
timeSums.get(key)[i] = 0.0;
}
}

for (int i = 0; i < NUM_OF_EXPS; i++) {
for (int line = 0; line < data.get(i).size(); line++) {
timeSums.get("time_pm")[i] += data.get(i).get(line)[0];
timeSums.get("time_ilp")[i] += data.get(i).get(line)[1];
timeSums.get("time_deploy")[i] += data.get(i).get(line)[2];
timeSums.get("time_rest")[i] += data.get(i).get(line)[3];
timeSums.get("time_total")[i] += //
data.get(i).get(line)[0] //
+ data.get(i).get(line)[1] //
+ data.get(i).get(line)[2] //
+ data.get(i).get(line)[3];
}
}

final String[] line = StatisticUtils.assembleTimeSumCsvLine(timeSums);
CsvUtil.createCsvTimeSumFile(expName + "_timesums.csv", line);

System.out.println("=> Finished statistics file: " + outputName);
}

}
58 changes: 58 additions & 0 deletions statistics/src/statistics/RunnerWrapper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package statistics;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashSet;
import java.util.Set;

/**
* Runner wrapper class that searches for CSV metric files and starts the Runner class accordingly.
*
* @author Maximilian Kratz {@literal <[email protected]>}
*/
public class RunnerWrapper {

/**
* Private constructor ensures no object instantiation.
*/
private RunnerWrapper() {}

/**
* Main method to start the runner wrapper. Argument must contain the base path to search CSV
* files recursive in.
*
* @param args Arguments to parse, i.e., args[0] must hold the base path.
*/
public static void main(final String[] args) {
if (args == null || args.length < 1) {
throw new IllegalArgumentException("Please specify the experiment name to load files from.");
}

final String path = args[0];
final Set<String> experiments = new HashSet<String>();

try {
Files.walk(Paths.get(path)) //
.filter(Files::isRegularFile) //
.forEach(p -> {
final String pabs = p.toAbsolutePath().toString();
if (pabs.contains(".csv") && pabs.contains("_run")) {
// Cut of "_run1.csv" from filename
experiments.add(pabs.substring(0, pabs.indexOf(".csv") - 5));
}
});
} catch (final IOException e) {
System.out.println("=> Catched an IOException. Halting.");
e.printStackTrace();
System.exit(1);
}

// Start basic runner for each experiment
experiments.forEach(e -> {
Runner.main(new String[] {e});
});
System.out.println("=> Runner wrapper finished.");
}

}
102 changes: 102 additions & 0 deletions statistics/src/statistics/StatisticUtils.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
package statistics;

import java.util.Map;

/**
* Utility class for the statistics project.
*
* @author Maximilian Kratz {@literal <[email protected]>}
*/
public class StatisticUtils {

/**
* Private constructor ensures no object instantiation.
*/
private StatisticUtils() {}

/**
* Assembles one line for the output CSV files with the statistics. Takes a counter (= line
* number), the array of doubles for the mean, and an array of double for the standard derivation
* and combines them to an array of strings in this form:
*
* {counter, mean[0], stddev[0], mean[1], stddev[1], ...}
*
* @param counter Line counter.
* @param mean Array of doubles that defines the mean values.
* @param stddev Array of doubles that defines the standard derivation values.
* @return Array of string as described above.
*/
static String[] assembleCsvLine(final int counter, final double[] mean, final double[] stddev) {
if (mean.length != stddev.length) {
throw new IllegalArgumentException("Array length differs.");
}

final String[] output = new String[mean.length * 2 + 1];
output[0] = String.valueOf(counter);

for (int i = 0; i < mean.length * 2; i += 2) {
output[i + 1] = String.valueOf(mean[i / 2]);
output[i + 2] = String.valueOf(stddev[i / 2]);
}

return output;
}

/**
* Assembles one line for the output CSV file with time summing.
*
* @param timeSums Mapping of time values to double array.
* @return String that represents the line of the output CSV file.
*/
static String[] assembleTimeSumCsvLine(final Map<String, Double[]> timeSums) {
final String[] sums = new String[10];
sums[0] = String.valueOf(StatisticUtils.mean(timeSums.get("time_total")));
sums[1] = String.valueOf(StatisticUtils.stdDev(timeSums.get("time_total")));
sums[2] = String.valueOf(StatisticUtils.mean(timeSums.get("time_pm")));
sums[3] = String.valueOf(StatisticUtils.stdDev(timeSums.get("time_pm")));
sums[4] = String.valueOf(StatisticUtils.mean(timeSums.get("time_ilp")));
sums[5] = String.valueOf(StatisticUtils.stdDev(timeSums.get("time_ilp")));
sums[6] = String.valueOf(StatisticUtils.mean(timeSums.get("time_deploy")));
sums[7] = String.valueOf(StatisticUtils.stdDev(timeSums.get("time_deploy")));
sums[8] = String.valueOf(StatisticUtils.mean(timeSums.get("time_rest")));
sums[9] = String.valueOf(StatisticUtils.stdDev(timeSums.get("time_rest")));
return sums;
}

/**
* Calculates the mean for a given double array.
*
* @param values Array of doubles.
* @return Mean.
*/
static double mean(final Double[] values) {
if (values == null) {
throw new IllegalArgumentException("Argument was null.");
}

double adds = 0;
for (int i = 0; i < values.length; i++) {
adds += values[i];
}

return adds / values.length;
}

/**
* Calculates the standard derivation for a given double array.
*
* @param values Array of doubles.
* @return Standard derivation.
*/
static double stdDev(final Double[] values) {
final double mean = mean(values);
double val = 0;

for (int i = 0; i < values.length; i++) {
val += Math.pow(values[i] - mean, 2) / values.length;
}

return Math.sqrt(val);
}

}
Loading

0 comments on commit 1823349

Please sign in to comment.