derived: DerivedMeasurments now return DerivedMetrics
DerivedMeasurments processors now return DerviedMetrics rather than
measurments. The notion of an InstrumentChannel doesn't really make
sense in the context of DerivedMeasurments, which are not directly
measured on the target. Since Measurement's require a channel, a simpler
DerviedMetric is added that only requires a name and a type.
diff --git a/devlib/__init__.py b/devlib/__init__.py
index 19232c7..42509f9 100644
--- a/devlib/__init__.py
+++ b/devlib/__init__.py
@@ -19,7 +19,7 @@
from devlib.instrument.netstats import NetstatsInstrument
from devlib.instrument.gem5power import Gem5PowerInstrument
-from devlib.derived import DerivedMeasurements
+from devlib.derived import DerivedMeasurements, DerivedMetric
from devlib.derived.energy import DerivedEnergyMeasurements
from devlib.trace.ftrace import FtraceCollector
diff --git a/devlib/derived/__init__.py b/devlib/derived/__init__.py
index 5689a58..5f7dc6e 100644
--- a/devlib/derived/__init__.py
+++ b/devlib/derived/__init__.py
@@ -12,6 +12,45 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
+
+from devlib.instrument import MeasurementType, MEASUREMENT_TYPES
+
+
+class DerivedMetric(object):
+
+ __slots__ = ['name', 'value', 'measurement_type']
+
+ @property
+ def units(self):
+ return self.measurement_type.units
+
+ def __init__(self, name, value, measurement_type):
+ self.name = name
+ self.value = value
+ if isinstance(measurement_type, MeasurementType):
+ self.measurement_type = measurement_type
+ else:
+ try:
+ self.measurement_type = MEASUREMENT_TYPES[measurement_type]
+ except KeyError:
+ msg = 'Unknown measurement type: {}'
+ raise ValueError(msg.format(measurement_type))
+
+ def __cmp__(self, other):
+ if hasattr(other, 'value'):
+ return cmp(self.value, other.value)
+ else:
+ return cmp(self.value, other)
+
+ def __str__(self):
+ if self.units:
+ return '{}: {} {}'.format(self.name, self.value, self.units)
+ else:
+ return '{}: {}'.format(self.name, self.value)
+
+ __repr__ = __str__
+
+
class DerivedMeasurements(object):
@staticmethod
diff --git a/devlib/derived/energy.py b/devlib/derived/energy.py
index b3f9c82..84d3d7c 100644
--- a/devlib/derived/energy.py
+++ b/devlib/derived/energy.py
@@ -15,8 +15,8 @@
from __future__ import division
from collections import defaultdict
-from devlib import DerivedMeasurements
-from devlib.instrument import Measurement, MEASUREMENT_TYPES, InstrumentChannel
+from devlib import DerivedMeasurements, DerivedMetric
+from devlib.instrument import MEASUREMENT_TYPES, InstrumentChannel
class DerivedEnergyMeasurements(DerivedMeasurements):
@@ -86,12 +86,12 @@
derived_measurements = []
for site in energy_results:
total_energy = energy_results[site]['end'] - energy_results[site]['start']
- instChannel = InstrumentChannel('cum_energy', site, MEASUREMENT_TYPES['energy'])
- derived_measurements.append(Measurement(total_energy, instChannel))
+ name = '{}_total_energy'.format(site)
+ derived_measurements.append(DerivedMetric(name, total_energy, MEASUREMENT_TYPES['energy']))
for site in power_results:
power = power_results[site] / (count + 1) #pylint: disable=undefined-loop-variable
- instChannel = InstrumentChannel('avg_power', site, MEASUREMENT_TYPES['power'])
- derived_measurements.append(Measurement(power, instChannel))
+ name = '{}_average_power'.format(site)
+ derived_measurements.append(DerivedMetric(name, power, MEASUREMENT_TYPES['power']))
return derived_measurements