mirror of
				https://github.com/ARM-software/workload-automation.git
				synced 2025-11-04 00:52:08 +00:00 
			
		
		
		
	Updating energy model instrument to be able to accumulate multiple power rails for each cluster.
This commit is contained in:
		@@ -23,7 +23,7 @@ except ImportError as e:
 | 
			
		||||
from wlauto import Instrument, Parameter, File
 | 
			
		||||
from wlauto.exceptions import ConfigError, InstrumentError, DeviceError
 | 
			
		||||
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
 | 
			
		||||
 | 
			
		||||
FREQ_TABLE_FILE = 'frequency_power_perf_data.csv'
 | 
			
		||||
@@ -319,7 +319,7 @@ class EnergyModelInstrument(Instrument):
 | 
			
		||||
                                 one of the values in ``device.core_names``. """),
 | 
			
		||||
        Parameter('performance_metric', kind=caseless_string, mandatory=True,
 | 
			
		||||
                  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
 | 
			
		||||
                                 ``{core}`` format specifier that will be replaced with names of big
 | 
			
		||||
                                 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):
 | 
			
		||||
        spec = context.result.spec
 | 
			
		||||
        cluster = spec.cluster
 | 
			
		||||
        seen_perf = False
 | 
			
		||||
        seen_power = False
 | 
			
		||||
        is_freq_iteration = spec.label.startswith('freq_')
 | 
			
		||||
        perf_metric = 0
 | 
			
		||||
        power_metric = 0
 | 
			
		||||
        for metric in context.result.metrics:
 | 
			
		||||
            if metric.name == self.performance_metric:
 | 
			
		||||
                metric_name = 'performance'
 | 
			
		||||
                metric_value = metric.value
 | 
			
		||||
                seen_perf = True
 | 
			
		||||
            elif ((cluster == 'big' and metric.name == self.big_power_metric) or
 | 
			
		||||
                  (cluster == 'little' and metric.name == self.little_power_metric)):
 | 
			
		||||
                metric_name = 'power'
 | 
			
		||||
                metric_value = metric.value * self.power_scaling_factor
 | 
			
		||||
                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)):
 | 
			
		||||
                perf_metric = metric.value
 | 
			
		||||
            elif (cluster == 'big') and metric.name in self.big_power_metrics:
 | 
			
		||||
                power_metric += metric.value * self.power_scaling_factor
 | 
			
		||||
            elif (cluster == 'little') and metric.name in self.little_power_metrics:
 | 
			
		||||
                power_metric += metric.value * self.power_scaling_factor
 | 
			
		||||
 | 
			
		||||
        if not (power_metric and (perf_metric or not is_freq_iteration)):
 | 
			
		||||
            message = 'Incomplete results for {} 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):
 | 
			
		||||
        # pylint: disable=too-many-locals
 | 
			
		||||
        if not self.idle_data or not self.freq_data:
 | 
			
		||||
@@ -479,8 +466,12 @@ class EnergyModelInstrument(Instrument):
 | 
			
		||||
    def initialize_result_tracking(self):
 | 
			
		||||
        self.freq_data = []
 | 
			
		||||
        self.idle_data = []
 | 
			
		||||
        self.big_power_metric = self.power_metric.format(core=self.big_core)
 | 
			
		||||
        self.little_power_metric = self.power_metric.format(core=self.little_core)
 | 
			
		||||
        if isinstance(self.power_metric, basestring):
 | 
			
		||||
            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):
 | 
			
		||||
        self.measured_cores = None
 | 
			
		||||
 
 | 
			
		||||
@@ -96,6 +96,21 @@ def list_or_string(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):
 | 
			
		||||
    """
 | 
			
		||||
    Value must be iterable. All elements will be converted to strings.
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user