1
0
mirror of https://github.com/ARM-software/workload-automation.git synced 2025-02-21 20:38:57 +00:00

Merge pull request #469 from marcbonnici/energy_measurement

Energy measurement
This commit is contained in:
setrofim 2017-08-21 08:50:28 +01:00 committed by GitHub
commit 0cc8ebbf69

View File

@ -17,11 +17,13 @@
# pylint: disable=W0613,E1101 # pylint: disable=W0613,E1101
from __future__ import division from __future__ import division
import os import os
from collections import defaultdict
from devlib.instrument import CONTINUOUS from devlib.instrument import CONTINUOUS
from devlib.instrument.energy_probe import EnergyProbeInstrument from devlib.instrument.energy_probe import EnergyProbeInstrument
from devlib.instrument.daq import DaqInstrument from devlib.instrument.daq import DaqInstrument
from devlib.instrument.acmecape import AcmeCapeInstrument
from devlib.utils.misc import which
from devlib.derived.derived_measurements import DerivedEnergyMeasurements
from wa import Instrument, Parameter from wa import Instrument, Parameter
from wa.framework import pluginloader from wa.framework import pluginloader
@ -140,6 +142,31 @@ class EnergyProbeBackend(EnergyInstrumentBackend):
msg = 'Number of Energy Probe port labels does not match the number of resistor values.' msg = 'Number of Energy Probe port labels does not match the number of resistor values.'
raise ConfigError(msg) raise ConfigError(msg)
class AcmeCapeBackend(EnergyInstrumentBackend):
name = 'acme_cape'
parameters = [
Parameter('iio-capture', default=which('iio-capture'),
description="""
Path to the iio-capture binary will be taken from the
environment, if not specfied.
"""),
Parameter('host', default='baylibre-acme.local',
description="""
Host name (or IP address) of the ACME cape board.
"""),
Parameter('iio-device', default='iio:device0',
description="""
"""),
Parameter('buffer-size', kind=int, default=256,
description="""
Size of the capture buffer (in KB).
"""),
]
instrument = AcmeCapeInstrument
class EnergyMeasurement(Instrument): class EnergyMeasurement(Instrument):
@ -152,7 +179,7 @@ class EnergyMeasurement(Instrument):
parameters = [ parameters = [
Parameter('instrument', kind=str, mandatory=True, Parameter('instrument', kind=str, mandatory=True,
allowed_values=['daq', 'energy_probe'], allowed_values=['daq', 'energy_probe', 'acme_cape'],
description=""" description="""
Specify the energy instrumentation to be enabled. Specify the energy instrumentation to be enabled.
"""), """),
@ -161,19 +188,19 @@ class EnergyMeasurement(Instrument):
Specify the parameters used to initialize the desired Specify the parameters used to initialize the desired
instrumentation. instrumentation.
"""), """),
Parameter('sites', kind=list_or_string, default=[], Parameter('sites', kind=list_or_string,
description=""" description="""
Specify which sites measurements should be collected Specify which sites measurements should be collected
from, if not specified the measurements will be from, if not specified the measurements will be
collected for all available sites. collected for all available sites.
"""), """),
Parameter('kinds', kind=list_or_string, default=[], Parameter('kinds', kind=list_or_string,
description=""" description="""
Specify the kinds of measurements should be collected, Specify the kinds of measurements should be collected,
if not specified measurements will be if not specified measurements will be
collected for all available kinds. collected for all available kinds.
"""), """),
Parameter('channels', kind=list_or_string, default=[], Parameter('channels', kind=list_or_string,
description=""" description="""
Specify the channels to be collected, Specify the channels to be collected,
if not specified the measurements will be if not specified the measurements will be
@ -204,7 +231,7 @@ class EnergyMeasurement(Instrument):
def initialize(self, context): def initialize(self, context):
self.instrumentation = self.backend.instrument(self.target, **self.params) self.instrumentation = self.backend.instrument(self.target, **self.params)
for channel in self.channels: for channel in self.channels or []:
if not self.instrumentation.get_channels(channel): if not self.instrumentation.get_channels(channel):
raise ConfigError('No channels found for "{}"'.format(channel)) raise ConfigError('No channels found for "{}"'.format(channel))
@ -226,24 +253,7 @@ class EnergyMeasurement(Instrument):
self.extract_metrics(context) self.extract_metrics(context)
def extract_metrics(self, context): def extract_metrics(self, context):
measurements = self.measurement_csv.itermeasurements() derived_measurements = DerivedEnergyMeasurements.process(self.measurement_csv)
energy_results = defaultdict(dict) for meas in derived_measurements:
power_results = defaultdict(int) name = '{}_{}'.format(meas.channel.site, meas.channel.name)
context.add_metric(name, meas.value, meas.units)
for count, row in enumerate(measurements):
for entry in row:
channel = entry.channel
if channel.kind == 'energy':
if count == 0:
energy_results[channel.site]['start'] = entry.value
else:
energy_results[channel.site]['end'] = entry.value
elif channel.kind == 'power':
power_results[channel.site] += entry.value
for site in energy_results:
total_energy = energy_results[site]['end'] - energy_results[site]['start']
context.add_metric('{}_energy'.format(site), total_energy, 'joules')
for site in power_results:
power = power_results[site] / count + 1 #pylint: disable=undefined-loop-variable
context.add_metric('{}_power'.format(site), power, 'watts')