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

Refactoring: Better implementation of feature checking

Instead of changing how features are interpreted depending of whether
they work or not, each feature can check itself if it is supported.

We then have a function which builds a new FeatureSet from an existing
one, filtering out the features that aren't supported.

I also added a method that only returns the features that were mentioned
in the FeatureSet in the map of the results.
parent e00fe5c9
......@@ -14,9 +14,12 @@ class EventSetBuilder : FeatureVisitor {
override fun visitPAPICounter(c: PAPICounter) {
// If the counter is de-activated we skip it
if (c.isActive) {
counterSet.add(c)
if (!c.isSupported()) {
val msg = "Creating eventSet for single counter $c failed: is it available on this machine?"
throw RuntimeException(msg)
}
counterSet.add(c)
}
override fun visitConstant(constantFeature: ConstantFeature) {
......
......@@ -9,17 +9,11 @@ import se.lth.cs.util.FeatureVisitor
import java.lang.RuntimeException
class PAPICounter(val counter : String) : Feature() {
init {
check()
}
fun isValid(): Boolean {
return CounterSpecification.allCounters.contains(counter)
}
var isActive : Boolean = false
fun check() {
override fun isSupported(): Boolean {
Papi.init()
try {
val eventSet = EventSet.create(this.toPAPIConstant()!!)
......@@ -31,12 +25,9 @@ class PAPICounter(val counter : String) : Feature() {
// }
// eventSet.stop()
// eventSet.destroy()
isActive = true
return true
} catch (e : PapiException) {
val msg = "Creating eventSet for single counter $counter failed: is it available on this machine? Deactivating..."
System.err.println("[WARNING]: $msg")
isActive = false
return false
}
}
......
......@@ -12,9 +12,19 @@ class Experiment(val numberIterations : Int,
val features : FeatureSet,
val papiRunner : PapiTracerRunner) : FeatureVisitor {
data class Result(val iterationNumber : Int,
val benchmark : BCBenchmarkPackage<*>,
val values : Map<Feature, Double>)
inner class Result(val iterationNumber : Int,
val benchmark : BCBenchmarkPackage<*>,
val values : Map<Feature, Double>) {
/**
* Returns only the features we specified in the feature set
* If feature F1 requires F2, but F2 is not explicitly requested
* we omit it.
*/
fun strict() : Result {
return Result(iterationNumber, benchmark,
values.filterKeys { it in features } )
}
}
fun getIterations(): List<List<PapiTracerRunner.TraceRecord>> {
val eventSetBuilder = EventSetBuilder()
......@@ -59,9 +69,6 @@ class Experiment(val numberIterations : Int,
var currentIterationResults : MutableMap<Feature, Double> = mutableMapOf()
override fun visitPAPICounter(c: PAPICounter) {
if (!c.isActive) {
return
}
if (currentIterationResults.containsKey(c)) {
return
}
......
......@@ -42,6 +42,10 @@ abstract class Feature {
abstract fun featureType() : Feature.Type
abstract fun accept(visitor : FeatureVisitor)
open fun isSupported() : Boolean {
return true
}
}
/**
......@@ -108,6 +112,10 @@ open class FeatureRatio(val f1 : Feature, val f2 : Feature) : Feature() {
override fun toString(): String {
return "%s / %s".format(f1.toString(), f2.toString())
}
override fun isSupported(): Boolean {
return f1.isSupported() && f2.isSupported()
}
}
class MethodInvocations(val method : String, val methodPrintFormat : String) : Feature() {
......@@ -192,6 +200,14 @@ class FeatureSet(vararg features : Feature) : ArrayList<Feature>() {
}
}
/**
* Returns a subset of features which should be supported by the current machine!
*/
fun checked() : FeatureSet {
val featuresChecked = this.filter { it.isSupported() }
return FeatureSet(*featuresChecked.toTypedArray())
}
fun accept(visitor : FeatureVisitor) {
visitor.visitFeatureSet(this)
}
......
......@@ -103,7 +103,6 @@ class EventSetBuilderTest {
// Oh no! empty list of PAPI events!
val builder = EventSetBuilder()
spec.accept(builder)
// Assertions.assertThrows(RuntimeException::class.java, { spec.accept(builder) })
Assertions.assertThrows(RuntimeException::class.java) { spec.accept(builder) }
}
}
\ No newline at end of file
......@@ -96,7 +96,7 @@ class ExperimentTest {
fun testNormalizationBrainyFeatures() {
val bench = BCBenchmarkPackage.LIST(1234, 100, 0, ArrayList<Int>())
val features = normalize(brainyFeatures())
val features = normalize(brainyFeatures()).checked()
val exp = Experiment(10, bench, features,runner)
......@@ -104,12 +104,9 @@ class ExperimentTest {
for (iteration in results) {
Assertions.assertEquals(bench, iteration.benchmark)
Assertions.assertTrue(features.containsAll(iteration.strict().values.keys))
Assertions.assertTrue(iteration.values.values.all { it > 0 })
val normalizedFeatures = iteration.values.keys.filterIsInstance<NormalizedFeature>()
for (f in normalizedFeatures) {
val value = iteration.values[f]!!
Assertions.assertTrue(value <= 1.0)
}
Assertions.assertTrue(iteration.strict().values.values.all { it <= 1.0 })
}
}
}
\ 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