mirror of
https://github.com/ARM-software/workload-automation.git
synced 2025-02-12 07:59:04 +00:00
Updating energy model instrument to be able to accumulate multiple power rails for each cluster.
This commit is contained in:
parent
c52d562411
commit
47ce9db383
@ -23,7 +23,7 @@ except ImportError as e:
|
|||||||
from wlauto import Instrument, Parameter, File
|
from wlauto import Instrument, Parameter, File
|
||||||
from wlauto.exceptions import ConfigError, InstrumentError, DeviceError
|
from wlauto.exceptions import ConfigError, InstrumentError, DeviceError
|
||||||
from wlauto.instrumentation import instrument_is_installed
|
from wlauto.instrumentation import instrument_is_installed
|
||||||
from wlauto.utils.types import caseless_string, list_of_ints
|
from wlauto.utils.types import caseless_string, list_or_caseless_string, list_of_ints
|
||||||
from wlauto.utils.misc import list_to_mask
|
from wlauto.utils.misc import list_to_mask
|
||||||
|
|
||||||
FREQ_TABLE_FILE = 'frequency_power_perf_data.csv'
|
FREQ_TABLE_FILE = 'frequency_power_perf_data.csv'
|
||||||
@ -319,7 +319,7 @@ class EnergyModelInstrument(Instrument):
|
|||||||
one of the values in ``device.core_names``. """),
|
one of the values in ``device.core_names``. """),
|
||||||
Parameter('performance_metric', kind=caseless_string, mandatory=True,
|
Parameter('performance_metric', kind=caseless_string, mandatory=True,
|
||||||
description="""Metric to be used as the performance indicator."""),
|
description="""Metric to be used as the performance indicator."""),
|
||||||
Parameter('power_metric', kind=caseless_string, mandatory=True,
|
Parameter('power_metric', kind=list_or_caseless_string, mandatory=True,
|
||||||
description="""Metric to be used as the power indicator. The value may contain a
|
description="""Metric to be used as the power indicator. The value may contain a
|
||||||
``{core}`` format specifier that will be replaced with names of big
|
``{core}`` format specifier that will be replaced with names of big
|
||||||
and little cores to drive the name of the metric for that cluster."""),
|
and little cores to drive the name of the metric for that cluster."""),
|
||||||
@ -393,46 +393,33 @@ class EnergyModelInstrument(Instrument):
|
|||||||
def slow_update_result(self, context):
|
def slow_update_result(self, context):
|
||||||
spec = context.result.spec
|
spec = context.result.spec
|
||||||
cluster = spec.cluster
|
cluster = spec.cluster
|
||||||
seen_perf = False
|
|
||||||
seen_power = False
|
|
||||||
is_freq_iteration = spec.label.startswith('freq_')
|
is_freq_iteration = spec.label.startswith('freq_')
|
||||||
|
perf_metric = 0
|
||||||
|
power_metric = 0
|
||||||
for metric in context.result.metrics:
|
for metric in context.result.metrics:
|
||||||
if metric.name == self.performance_metric:
|
if metric.name == self.performance_metric:
|
||||||
metric_name = 'performance'
|
perf_metric = metric.value
|
||||||
metric_value = metric.value
|
elif (cluster == 'big') and metric.name in self.big_power_metrics:
|
||||||
seen_perf = True
|
power_metric += metric.value * self.power_scaling_factor
|
||||||
elif ((cluster == 'big' and metric.name == self.big_power_metric) or
|
elif (cluster == 'little') and metric.name in self.little_power_metrics:
|
||||||
(cluster == 'little' and metric.name == self.little_power_metric)):
|
power_metric += metric.value * self.power_scaling_factor
|
||||||
metric_name = 'power'
|
|
||||||
metric_value = metric.value * self.power_scaling_factor
|
if not (power_metric and (perf_metric or not is_freq_iteration)):
|
||||||
seen_power = True
|
|
||||||
else:
|
|
||||||
metric_name = None
|
|
||||||
metric_value = None
|
|
||||||
if metric_name:
|
|
||||||
if is_freq_iteration:
|
|
||||||
self.freq_data.append([
|
|
||||||
cluster,
|
|
||||||
spec.num_cpus,
|
|
||||||
spec.frequency,
|
|
||||||
context.result.iteration,
|
|
||||||
metric_name,
|
|
||||||
metric_value,
|
|
||||||
])
|
|
||||||
else:
|
|
||||||
self.idle_data.append([
|
|
||||||
cluster,
|
|
||||||
spec.num_cpus,
|
|
||||||
spec.idle_state_id,
|
|
||||||
spec.idle_state_desc,
|
|
||||||
context.result.iteration,
|
|
||||||
metric_name,
|
|
||||||
metric_value,
|
|
||||||
])
|
|
||||||
if not (seen_power and (seen_perf or not is_freq_iteration)):
|
|
||||||
message = 'Incomplete results for {} iteration{}'
|
message = 'Incomplete results for {} iteration{}'
|
||||||
raise InstrumentError(message.format(context.result.spec.id, context.current_iteration))
|
raise InstrumentError(message.format(context.result.spec.id, context.current_iteration))
|
||||||
|
|
||||||
|
if is_freq_iteration:
|
||||||
|
index_matter = [cluster, spec.num_cpus,
|
||||||
|
spec.frequency, context.result.iteration]
|
||||||
|
data = self.freq_data
|
||||||
|
else:
|
||||||
|
index_matter = [cluster, spec.num_cpus,
|
||||||
|
spec.idle_state_id, spec.idle_state_desc, context.result.iteration]
|
||||||
|
data = self.idle_data
|
||||||
|
|
||||||
|
data.append(index_matter + ['performance', perf_metric])
|
||||||
|
data.append(index_matter + ['{}_power'.format(self.get_core_name(cluster)), power_metric])
|
||||||
|
|
||||||
def before_overall_results_processing(self, context):
|
def before_overall_results_processing(self, context):
|
||||||
# pylint: disable=too-many-locals
|
# pylint: disable=too-many-locals
|
||||||
if not self.idle_data or not self.freq_data:
|
if not self.idle_data or not self.freq_data:
|
||||||
@ -479,8 +466,12 @@ class EnergyModelInstrument(Instrument):
|
|||||||
def initialize_result_tracking(self):
|
def initialize_result_tracking(self):
|
||||||
self.freq_data = []
|
self.freq_data = []
|
||||||
self.idle_data = []
|
self.idle_data = []
|
||||||
self.big_power_metric = self.power_metric.format(core=self.big_core)
|
if isinstance(self.power_metric, basestring):
|
||||||
self.little_power_metric = self.power_metric.format(core=self.little_core)
|
self.big_power_metrics = [self.power_metric.format(core=self.big_core)]
|
||||||
|
self.little_power_metrics = [self.power_metric.format(core=self.little_core)]
|
||||||
|
else:
|
||||||
|
self.big_power_metrics = [pm.format(core=self.big_core) for pm in self.power_metric]
|
||||||
|
self.little_power_metrics = [pm.format(core=self.little_core) for pm in self.power_metric]
|
||||||
|
|
||||||
def configure_clusters(self):
|
def configure_clusters(self):
|
||||||
self.measured_cores = None
|
self.measured_cores = None
|
||||||
|
@ -96,6 +96,21 @@ def list_or_string(value):
|
|||||||
return str(value)
|
return str(value)
|
||||||
|
|
||||||
|
|
||||||
|
def list_or_caseless_string(value):
|
||||||
|
"""
|
||||||
|
If the value is a string, at will be kept as a string, otherwise it will be interpreted
|
||||||
|
as a list. If that is not possible, it will be interpreted as a string.
|
||||||
|
|
||||||
|
"""
|
||||||
|
if isinstance(value, basestring):
|
||||||
|
return caseless_string(value)
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
return map(caseless_string, value)
|
||||||
|
except ValueError:
|
||||||
|
return caseless_string(value)
|
||||||
|
|
||||||
|
|
||||||
def list_of_strs(value):
|
def list_of_strs(value):
|
||||||
"""
|
"""
|
||||||
Value must be iterable. All elements will be converted to strings.
|
Value must be iterable. All elements will be converted to strings.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user