Commit e2caae74 authored by Noric Couderc's avatar Noric Couderc
Browse files

Added feature type to printed features

The features go into two boxes: Hardware and software.
We print that next to the feature values, to make it much easier to
sort which one is which.

Required some refactorings:

- Introduced a class BenchmarkRunData which contains data related to
the PAPI counters. We use that instead of Triples.

- Extracted two methods: printSoftwareCounters and printHardwareCounters
parent f997e382
......@@ -16,6 +16,10 @@ open class PapiRunner(numRuns : Int, counters: CounterSpecification) {
val counterSpec = counters
val numRuns = numRuns
data class BenchmarkRunData(val benchmark : BCBenchmarkPackage<*>,
val counter : String,
val value : Double)
protected var blackhole = Blackhole("Today's password is swordfish. I understand instantiating Blackholes directly is dangerous.")
/**
......@@ -219,20 +223,20 @@ open class PapiRunner(numRuns : Int, counters: CounterSpecification) {
}
fun runApplicationsMedian(syntheticBenchmarks: List<BCBenchmarkPackage<*>>) : List<Triple<BCBenchmarkPackage<*>, String, Double>> {
fun runApplicationsMedian(syntheticBenchmarks: List<BCBenchmarkPackage<*>>) : List<BenchmarkRunData> {
val samples = runApplications(syntheticBenchmarks)
return samples.map {
Triple(it.first, it.second, medianLong(it.third))
BenchmarkRunData(it.first, it.second, medianLong(it.third))
}
}
fun runApplicationsNormalized(syntheticBenchmarks: List<BCBenchmarkPackage<*>>) : List<Triple<BCBenchmarkPackage<*>, String, Double>> {
fun runApplicationsNormalized(syntheticBenchmarks: List<BCBenchmarkPackage<*>>) : List<BenchmarkRunData> {
val countersMedians = runApplicationsMedian(syntheticBenchmarks)
val instructionsForBenchmark = countersMedians.filter { it.second == "PAPI_TOT_INS" }
.map { Pair(it.first, it.third) }
.toMap()
val instructionsForBenchmark = countersMedians.filter { it.counter == "PAPI_TOT_INS" }
.associate { Pair(it.benchmark, it.value) }
return countersMedians.map {
Triple(it.first, it.second, it.third / instructionsForBenchmark[it.first]!!)
BenchmarkRunData(it.benchmark, it.counter, it.value / instructionsForBenchmark[it.benchmark]!!)
}
}
......
......@@ -2,8 +2,6 @@ package se.lth.cs
import java.io.Writer
import se.lth.cs.bcgen.*
import java.util.stream.Collectors
import java.util.stream.Stream
class SyntheticBenchmarkFeaturePrinter(out: Writer,
papiRunner: PapiRunner,
......@@ -15,14 +13,14 @@ class SyntheticBenchmarkFeaturePrinter(out: Writer,
private val normalizeFeatures = normalizeFeatures
private var benchmarkResults : Map<String, List<Triple<BCBenchmarkPackage<*>, String, Double>>> = mapOf()
private var benchmarkResults : Map<String, List<PapiRunner.BenchmarkRunData>> = mapOf()
/**
* Prints the header for benchmark features
* (They are printed in long form)
*/
override fun printHeader() {
printer.printRecord("benchmark_id", "feature", "value")
printer.printRecord("benchmark_id", "feature", "feature_type", "value")
}
/**
......@@ -36,8 +34,21 @@ class SyntheticBenchmarkFeaturePrinter(out: Writer,
// Getting the collection name, printing it.
val collection = syntheticBenchmark.dataStructureSimpleName
printer.printRecord(identifier, "collection", collection)
printer.printRecord(identifier, "collection", "collection", collection)
printSoftwareCounters(syntheticBenchmark, identifier)
printHardwareCounters(identifier, benchmarkResults)
}
private fun printHardwareCounters(identifier: String, results: Map<String, List<PapiRunner.BenchmarkRunData>>) {
val hardwareFeatures = results[identifier]!!
for (benchData in hardwareFeatures) {
printer.printRecord(identifier, benchData.counter, "hardware", benchData.value)
}
}
private fun printSoftwareCounters(syntheticBenchmark: BCBenchmarkPackage<*>, identifier: String) {
// Getting the software perf counters
val softwareCounters =
when (normalizeFeatures) {
......@@ -45,12 +56,7 @@ class SyntheticBenchmarkFeaturePrinter(out: Writer,
false -> syntheticBenchmark.methodHistogram()
}
for (kvp in softwareCounters) {
printer.printRecord(identifier, getMethodName(kvp.key), kvp.value)
}
val hardwareFeatures = benchmarkResults[identifier]!!
for (triple in hardwareFeatures) {
printer.printRecord(identifier, triple.second, triple.third)
printer.printRecord(identifier, getMethodName(kvp.key), "software", kvp.value)
}
}
......@@ -62,10 +68,10 @@ class SyntheticBenchmarkFeaturePrinter(out: Writer,
private fun runBenchmarks(syntheticBenchmarks: List<BCBenchmarkPackage<*>>) {
benchmarkResults = when (normalizeFeatures) {
true -> papiRunner.runApplicationsNormalized(syntheticBenchmarks).groupBy {
it.first.benchmarkIdentifier
it.benchmark.benchmarkIdentifier
}
false -> papiRunner.runApplicationsMedian(syntheticBenchmarks).groupBy {
it.first.benchmarkIdentifier
it.benchmark.benchmarkIdentifier
}
}
}
......
......@@ -74,11 +74,11 @@ public class PapiRunnerTest {
3,
100
);
List<Triple<BCBenchmarkPackage<?>, String, Double>> data = runner.runApplicationsMedian(syntheticBenchmarks);
List<PapiRunner.BenchmarkRunData> data = runner.runApplicationsMedian(syntheticBenchmarks);
// We check all known Papi counters are in the map
Assertions.assertFalse(data.isEmpty());
for (Triple<BCBenchmarkPackage<?>, String, Double> counters : data) {
for (PapiRunner.BenchmarkRunData counters : data) {
Assertions.assertTrue(
specification.getCurrentSpec().containsKey(counters.component2())
);
......@@ -102,11 +102,11 @@ public class PapiRunnerTest {
ArrayList<BCBenchmarkPackage<?>> benches = new ArrayList<>();
benches.add(bench);
List<Triple<BCBenchmarkPackage<?>, String, Double>> results = runner.runApplicationsMedian(benches);
List<PapiRunner.BenchmarkRunData> results = runner.runApplicationsMedian(benches);
Assertions.assertFalse(results.isEmpty());
// Check that no counter is repeated twice.
Map<String, List<Triple<BCBenchmarkPackage<?>, String, Double>>> groups =
results.stream().collect(Collectors.groupingBy(x -> x.component2()));
Map<String, List<PapiRunner.BenchmarkRunData>> groups =
results.stream().collect(Collectors.groupingBy(PapiRunner.BenchmarkRunData::getCounter));
Assertions.assertFalse(groups.isEmpty());
......
......@@ -5,13 +5,10 @@ import org.junit.jupiter.api.Test
import se.lth.cs.CounterSpecification
import se.lth.cs.PapiRunner
import se.lth.cs.SyntheticBenchmarkFeaturePrinter
import se.lth.cs.TraceLoader
import se.lth.cs.bcgen.BCBenchmarkPackage
import java.io.File
import java.io.StringReader
import java.io.StringWriter
import java.util.*
import java.util.stream.Collectors
import kotlin.collections.ArrayList
import kotlin.collections.HashMap
......@@ -34,7 +31,7 @@ class SyntheticBenchmarkFeaturePrinterTest {
csvPrinter.printToCSV(toPrint)
Assertions.assertEquals(
"benchmark_id,feature,value", writer.toString().lineSequence().first())
"benchmark_id,feature,feature_type,value", writer.toString().lineSequence().first())
}
/**
......@@ -85,24 +82,28 @@ class SyntheticBenchmarkFeaturePrinterTest {
csvPrinter.printToCSV(listOf<BCBenchmarkPackage<*>>(benchmark))
val expectedBeginning =
"benchmark_id,feature,value\n" +
"Synth:0:10:Map:0:HashMap,collection,HashMap\n" +
"Synth:0:10:Map:0:HashMap,runContainsValue,2\n" +
"Synth:0:10:Map:0:HashMap,runClear,1\n" +
"Synth:0:10:Map:0:HashMap,runPut,3\n" +
"Synth:0:10:Map:0:HashMap,runRemove2,1\n" +
"Synth:0:10:Map:0:HashMap,runKeySet,1\n" +
"Synth:0:10:Map:0:HashMap,runSize,1\n" +
"Synth:0:10:Map:0:HashMap,runContainsKey,1"
"benchmark_id,feature,feature_type,value\n" +
"Synth:0:10:Map:0:HashMap,collection,collection,HashMap\n" +
"Synth:0:10:Map:0:HashMap,runContainsValue,software,2\n" +
"Synth:0:10:Map:0:HashMap,runClear,software,1\n" +
"Synth:0:10:Map:0:HashMap,runPut,software,3\n" +
"Synth:0:10:Map:0:HashMap,runRemove2,software,1\n" +
"Synth:0:10:Map:0:HashMap,runKeySet,software,1\n" +
"Synth:0:10:Map:0:HashMap,runSize,software,1\n" +
"Synth:0:10:Map:0:HashMap,runContainsKey,software,1"
val actualBeginning = writer.toString()
checkEquality(expectedBeginning, actualBeginning)
Assertions.assertEquals(expectedBeginning.lines(),
actualBeginning.lines().filter {
it.contains("benchmark_id") || it.contains("collection") || it.contains("run")} )
Assertions.assertEquals(
expectedBeginning.lines().filter { it.contains("software")},
actualBeginning.lines().filter { it.contains("software")} )
Assertions.assertEquals(
expectedBeginning.lines().filter { it.contains("collection")},
actualBeginning.lines().filter { it.contains("collection")} )
val expectedCounters =
runner.counterSpec.currentSpec.keys
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment