1
0
mirror of https://github.com/ARM-software/workload-automation.git synced 2024-10-06 19:01:15 +01:00
workload-automation/wlauto/result_processors/syeg.py

151 lines
5.2 KiB
Python
Raw Normal View History

# Copyright 2014-2015 ARM Limited
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
#pylint: disable=E1101,W0201
import os
import csv
import math
import re
from wlauto import ResultProcessor, Parameter, File
from wlauto.utils.misc import get_meansd
class SyegResultProcessor(ResultProcessor):
name = 'syeg_csv'
description = """
Generates a CSV results file in the format expected by SYEG toolchain.
Multiple iterations get parsed into columns, adds additional columns for mean
and standard deviation, append number of threads to metric names (where
applicable) and add some metadata based on external mapping files.
"""
parameters = [
Parameter('outfile', kind=str, default='syeg_out.csv',
description='The name of the output CSV file.'),
]
def initialize(self, context):
self.levelmap = self._read_map(context, 'final_sub.csv',
'Could not find metrics level mapping.')
self.typemap = self._read_map(context, 'types.csv',
'Could not find benchmark suite types mapping.')
def process_run_result(self, result, context):
syeg_results = {}
max_iterations = max(ir.iteration for ir in result.iteration_results)
for ir in result.iteration_results:
for metric in ir.metrics:
key = ir.spec.label + metric.name
if key not in syeg_results:
syeg_result = SyegResult(max_iterations)
syeg_result.suite = ir.spec.label
syeg_result.version = getattr(ir.workload, 'apk_version', None)
syeg_result.test = metric.name
if hasattr(ir.workload, 'number_of_threads'):
syeg_result.test += ' NT {} (Iterations/sec)'.format(ir.workload.number_of_threads)
syeg_result.final_sub = self.levelmap.get(metric.name)
syeg_result.lower_is_better = metric.lower_is_better
syeg_result.device = context.device.name
syeg_result.type = self._get_type(ir.workload.name, metric.name)
syeg_results[key] = syeg_result
syeg_results[key].runs[ir.iteration - 1] = metric.value
columns = ['device', 'suite', 'test', 'version', 'final_sub', 'best', 'average', 'deviation']
columns += ['run{}'.format(i + 1) for i in xrange(max_iterations)]
columns += ['type', 'suite_version']
outfile = os.path.join(context.output_directory, self.outfile)
with open(outfile, 'wb') as wfh:
writer = csv.writer(wfh)
writer.writerow(columns)
for syeg_result in syeg_results.values():
writer.writerow([getattr(syeg_result, c) for c in columns])
context.add_artifact('syeg_csv', outfile, 'export')
def _get_type(self, workload, metric):
metric = metric.lower()
type_ = self.typemap.get(workload)
if type_ == 'mixed':
if 'native' in metric:
type_ = 'native'
if ('java' in metric) or ('dalvik' in metric):
type_ = 'dalvik'
return type_
def _read_map(self, context, filename, errormsg):
mapfile = context.resolver.get(File(self, filename))
if mapfile:
with open(mapfile) as fh:
reader = csv.reader(fh)
return dict([c.strip() for c in r] for r in reader)
else:
self.logger.warning(errormsg)
return {}
class SyegResult(object):
@property
def average(self):
if not self._mean:
self._mean, self._sd = get_meansd(self.run_values)
return self._mean
@property
def deviation(self):
if not self._sd:
self._mean, self._sd = get_meansd(self.run_values)
return self._sd
@property
def run_values(self):
return [r for r in self.runs if not math.isnan(r)]
@property
def best(self):
if self.lower_is_better:
return min(self.run_values)
else:
return max(self.run_values)
@property
def suite_version(self):
return ' '.join(map(str, [self.suite, self.version]))
def __init__(self, max_iter):
self.runs = [float('nan') for _ in xrange(max_iter)]
self.device = None
self.suite = None
self.test = None
self.version = None
self.final_sub = None
self.lower_is_better = None
self.type = None
self._mean = None
self._sd = None
def __getattr__(self, name):
match = re.search(r'run(\d+)', name)
if not match:
raise AttributeError(name)
return self.runs[int(match.group(1)) - 1]