Commit 179e2c1f authored by Noric Couderc's avatar Noric Couderc
Browse files

Refactoring: Moved data classes to help with making PapiTracerRunner

This PapiTracerRunner shares similarities with PapiRunner, so we make
an interface that contains stuff that's common to the two classes.
parent 68eac27c
......@@ -3,6 +3,7 @@ package se.lth.cs
import org.openjdk.jmh.infra.Blackhole
import java.io.Writer
import se.lth.cs.bcgen.*
import se.lth.cs.papicounters.PapiBenchmarkAnalyzer
import se.lth.cs.timing.StopWatchRunner
import se.lth.cs.timing.TimedDataStructure
import se.lth.cs.timing.list.TimedArrayList
......@@ -29,7 +30,7 @@ class SyntheticBenchmarkFeaturePrinter(out: Writer,
private val normalizeFeatures = normalizeFeatures
private var benchmarkResults : Map<String, List<PapiRunner.BenchmarkRunData>> = mapOf()
private var benchmarkResults : Map<String, List<PapiBenchmarkAnalyzer.BenchmarkRunData>> = mapOf()
/**
* Prints the header for benchmark features
......@@ -72,7 +73,7 @@ class SyntheticBenchmarkFeaturePrinter(out: Writer,
}
}
private fun printHardwareCounters(identifier: String, results: Map<String, List<PapiRunner.BenchmarkRunData>>) {
private fun printHardwareCounters(identifier: String, results: Map<String, List<PapiBenchmarkAnalyzer.BenchmarkRunData>>) {
val hardwareFeatures = results[identifier]!!
for (benchData in hardwareFeatures) {
printer.printRecord(identifier, benchData.counter, "hardware", benchData.value)
......
package se.lth.cs.papicounters
import papi.EventSet
import se.lth.cs.bcgen.BCBenchmarkPackage
interface PapiBenchmarkAnalyzer {
data class RunSpec(val numRuns: Int,
val counter : String,
val eventSet: EventSet,
val syntheticBenchmark: BCBenchmarkPackage<*>)
data class BenchmarkRunData(val benchmark : BCBenchmarkPackage<*>,
val counter : String,
val value : Double)
fun runSpec(spec : RunSpec) : List<Long>
fun runApplications(syntheticBenchmarks: List<BCBenchmarkPackage<*>>):
List<Triple<BCBenchmarkPackage<*>, String, List<Long>>>
}
\ No newline at end of file
......@@ -5,9 +5,10 @@ import papi.EventSet
import papi.Papi
import papi.PapiException
import se.lth.cs.bcgen.BCBenchmarkPackage
import se.lth.cs.papicounters.PapiBenchmarkAnalyzer
import java.io.FileWriter
open class PapiRunner(private val numRuns: Int, counters: CounterSpecification) {
open class PapiRunner(private val numRuns: Int, counters: CounterSpecification) : PapiBenchmarkAnalyzer {
init {
Papi.init()
......@@ -15,10 +16,6 @@ open class PapiRunner(private val numRuns: Int, counters: CounterSpecification)
val counterSpec = counters
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.")
/**
......@@ -58,30 +55,25 @@ open class PapiRunner(private val numRuns: Int, counters: CounterSpecification)
return data
}
data class RunSpec(val numRuns: Int,
val counter : String,
val eventSet: EventSet,
val syntheticBenchmark: BCBenchmarkPackage<*>)
/**
* Creates a list of specifications of what counter to get from what benchmarks
*/
fun createRunSpecs(syntheticBenchmarks: List<BCBenchmarkPackage<*>>): List<RunSpec> {
fun createRunSpecs(syntheticBenchmarks: List<BCBenchmarkPackage<*>>): List<PapiBenchmarkAnalyzer.RunSpec> {
val counters = counterSpec.currentSpec
// Let's say we want to minimize the counter change
// We put it in the outer loop
val specification = mutableListOf<RunSpec>()
val specification = mutableListOf<PapiBenchmarkAnalyzer.RunSpec>()
for (c in counters) {
val eventSet = EventSet.create(c.value)
for (b in syntheticBenchmarks) {
specification.add(RunSpec(numRuns, c.key, eventSet, b))
specification.add(PapiBenchmarkAnalyzer.RunSpec(numRuns, c.key, eventSet, b))
}
}
return specification.toList()
}
open fun runSpec(spec : RunSpec): List<Long> {
override fun runSpec(spec : PapiBenchmarkAnalyzer.RunSpec): List<Long> {
// println("Running benchmark: " + spec.syntheticBenchmark.benchmarkIdentifier)
val writer = FileWriter("/dev/null")
val samples = mutableListOf<Long>()
......@@ -161,7 +153,7 @@ open class PapiRunner(private val numRuns: Int, counters: CounterSpecification)
}
fun runApplications(syntheticBenchmarks: List<BCBenchmarkPackage<*>>): List<Triple<BCBenchmarkPackage<*>, String, List<Long>>> {
override fun runApplications(syntheticBenchmarks: List<BCBenchmarkPackage<*>>): List<Triple<BCBenchmarkPackage<*>, String, List<Long>>> {
// return syntheticBenchmarks.map { b -> runApplication(iterations, b) }
val specs = createRunSpecs(syntheticBenchmarks)
val numberBenchmarks = specs.size
......@@ -181,20 +173,26 @@ open class PapiRunner(private val numRuns: Int, counters: CounterSpecification)
}
fun runApplicationsMedian(syntheticBenchmarks: List<BCBenchmarkPackage<*>>) : List<BenchmarkRunData> {
fun runApplicationsMedian(syntheticBenchmarks: List<BCBenchmarkPackage<*>>) :
List<PapiBenchmarkAnalyzer.BenchmarkRunData> {
val samples = runApplications(syntheticBenchmarks)
return samples.map {
BenchmarkRunData(it.first, it.second, medianLong(it.third))
}
}
fun runApplicationsNormalized(syntheticBenchmarks: List<BCBenchmarkPackage<*>>) : List<BenchmarkRunData> {
fun runApplicationsNormalized(syntheticBenchmarks: List<BCBenchmarkPackage<*>>) :
List<PapiBenchmarkAnalyzer.BenchmarkRunData> {
val countersMedians = runApplicationsMedian(syntheticBenchmarks)
val instructionsForBenchmark = countersMedians.filter { it.counter == "PAPI_TOT_INS" }
.associate { Pair(it.benchmark, it.value) }
return countersMedians.map {
BenchmarkRunData(it.benchmark, it.counter, it.value / instructionsForBenchmark[it.benchmark]!!)
PapiBenchmarkAnalyzer.BenchmarkRunData(
it.benchmark,
it.counter,
it.value / instructionsForBenchmark[it.benchmark]!!
)
}
}
......@@ -215,7 +213,7 @@ open class PapiRunner(private val numRuns: Int, counters: CounterSpecification)
* A mockup class which returns deterministic results when you "run" a spec.
*/
class MockupPapiRunner(numRuns : Int, counters : CounterSpecification) : PapiRunner(numRuns, counters) {
override fun runSpec(spec : RunSpec) : List<Long> {
override fun runSpec(spec : PapiBenchmarkAnalyzer.RunSpec) : List<Long> {
val seed = spec.syntheticBenchmark.seed
// We map the counters to integers
// val counterToInt = mapOf<String, Long>(
......
package se.lth.cs.papicounters
import se.lth.cs.CounterSpecification
import se.lth.cs.PapiRunner
/**
* This is a class that works exactly like the PAPI Runner, except it uses
* instrumented collections instead of getting the counters from "outside".
* The tracing collections allow to get more information (breakdown of the features per each method
* instead of each run)
*/
class PapiTracerRunner(numRuns : Int, counters : CounterSpecification) : PapiRunner(numRuns, counters) {
override fun runSpec(spec: PapiBenchmarkAnalyzer.RunSpec): List<Long> {
// We would need a way to set the eventset of tracing collections here.
return listOf()
}
}
\ No newline at end of file
import com.google.common.graph.*
import org.junit.Assert
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeAll
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.openjdk.jmh.infra.Blackhole
import papi.Constants
import papi.Papi
import se.lth.cs.CounterSpecification.Companion.fromFile
import se.lth.cs.bcgen.BCBenchmarkPackage
import se.lth.cs.papicounters.PapiTracerRunner
import se.lth.cs.smartmodules.tracer.Tracer
import se.lth.util.ArrayListTracer
import java.io.ByteArrayOutputStream
import java.io.File
import java.io.PrintStream
class TracingCollectionRunnerTest {
......@@ -19,6 +22,8 @@ class TracingCollectionRunnerTest {
companion object {
val blackhole = Blackhole("Today's password is swordfish. I understand instantiating Blackholes directly is dangerous.")
var runner: PapiTracerRunner? = null
@BeforeAll()
@JvmStatic
fun initPapi() {
......@@ -109,4 +114,21 @@ class TracingCollectionRunnerTest {
// What we need: A drop-in replacement for PapiRunner, which uses these collections instead.
@BeforeEach
fun setup() {
val papiAvailableCounters = File("../papi_avail")
Assertions.assertTrue(papiAvailableCounters.exists())
val specification = fromFile(papiAvailableCounters)
runner = PapiTracerRunner(10, specification)
}
@Test
fun testRunner() {
val benches = listOf(
BCBenchmarkPackage.LIST(10, 10, 0, ArrayList<Int>())
)
val res = runner!!.runApplicationsMedian(benches)
Assertions.assertFalse(res.isEmpty())
}
}
\ No newline at end of file
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