2018-07-04 15:39:44 +01:00
|
|
|
# Copyright 2018 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.
|
|
|
|
#
|
|
|
|
|
2018-05-30 13:58:49 +01:00
|
|
|
from devlib.utils.csvutil import csvwriter
|
2017-03-20 16:24:22 +00:00
|
|
|
|
2018-01-12 15:22:11 +00:00
|
|
|
from wa import OutputProcessor, Parameter
|
2017-03-20 16:24:22 +00:00
|
|
|
from wa.framework.exception import ConfigError
|
|
|
|
from wa.utils.types import list_of_strings
|
|
|
|
|
|
|
|
|
2018-01-12 15:22:11 +00:00
|
|
|
class CsvReportProcessor(OutputProcessor):
|
2017-03-20 16:24:22 +00:00
|
|
|
|
|
|
|
name = 'csv'
|
|
|
|
description = """
|
|
|
|
Creates a ``results.csv`` in the output directory containing results for
|
|
|
|
all iterations in CSV format, each line containing a single metric.
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
parameters = [
|
|
|
|
Parameter('use_all_classifiers', kind=bool, default=False,
|
|
|
|
global_alias='use_all_classifiers',
|
|
|
|
description="""
|
|
|
|
If set to ``True``, this will add a column for every classifier
|
|
|
|
that features in at least one collected metric.
|
|
|
|
|
|
|
|
.. note:: This cannot be ``True`` if ``extra_columns`` is set.
|
|
|
|
|
|
|
|
"""),
|
|
|
|
Parameter('extra_columns', kind=list_of_strings,
|
|
|
|
description="""
|
|
|
|
List of classifiers to use as columns.
|
|
|
|
|
|
|
|
.. note:: This cannot be set if ``use_all_classifiers`` is
|
|
|
|
``True``.
|
|
|
|
|
|
|
|
"""),
|
|
|
|
]
|
|
|
|
|
2018-09-20 17:04:55 +01:00
|
|
|
def __init__(self, *args, **kwargs):
|
|
|
|
super(CsvReportProcessor, self).__init__(*args, **kwargs)
|
|
|
|
self.outputs_so_far = []
|
|
|
|
self.artifact_added = False
|
|
|
|
|
2017-03-20 16:24:22 +00:00
|
|
|
def validate(self):
|
|
|
|
super(CsvReportProcessor, self).validate()
|
|
|
|
if self.use_all_classifiers and self.extra_columns:
|
|
|
|
msg = 'extra_columns cannot be specified when '\
|
|
|
|
'use_all_classifiers is True'
|
|
|
|
raise ConfigError(msg)
|
|
|
|
|
2018-07-04 17:44:55 +01:00
|
|
|
# pylint: disable=unused-argument
|
2017-03-20 16:24:22 +00:00
|
|
|
def process_job_output(self, output, target_info, run_output):
|
2017-11-06 17:04:40 +00:00
|
|
|
self.outputs_so_far.append(output)
|
|
|
|
self._write_outputs(self.outputs_so_far, run_output)
|
2017-03-20 16:24:22 +00:00
|
|
|
if not self.artifact_added:
|
|
|
|
run_output.add_artifact('run_result_csv', 'results.csv', 'export')
|
2018-07-09 15:28:22 +01:00
|
|
|
self.artifact_added = True # pylint: disable=attribute-defined-outside-init
|
2017-03-20 16:24:22 +00:00
|
|
|
|
2018-07-04 17:44:55 +01:00
|
|
|
def process_run_output(self, output, target_info): # pylint: disable=unused-argument
|
2017-11-06 17:04:40 +00:00
|
|
|
self.outputs_so_far.append(output)
|
|
|
|
self._write_outputs(self.outputs_so_far, output)
|
2017-03-20 16:24:22 +00:00
|
|
|
if not self.artifact_added:
|
|
|
|
output.add_artifact('run_result_csv', 'results.csv', 'export')
|
2018-07-09 15:28:22 +01:00
|
|
|
self.artifact_added = True # pylint: disable=attribute-defined-outside-init
|
2017-03-20 16:24:22 +00:00
|
|
|
|
2017-11-06 17:04:40 +00:00
|
|
|
def _write_outputs(self, outputs, output):
|
2017-03-20 16:24:22 +00:00
|
|
|
if self.use_all_classifiers:
|
|
|
|
classifiers = set([])
|
2017-11-24 16:26:38 +00:00
|
|
|
for out in outputs:
|
|
|
|
for metric in out.metrics:
|
2018-05-30 13:58:49 +01:00
|
|
|
classifiers.update(list(metric.classifiers.keys()))
|
2017-03-20 16:24:22 +00:00
|
|
|
extra_columns = list(classifiers)
|
|
|
|
elif self.extra_columns:
|
|
|
|
extra_columns = self.extra_columns
|
|
|
|
else:
|
|
|
|
extra_columns = []
|
|
|
|
|
|
|
|
outfile = output.get_path('results.csv')
|
2018-05-30 13:58:49 +01:00
|
|
|
with csvwriter(outfile) as writer:
|
2020-10-19 18:09:04 +01:00
|
|
|
writer.writerow(['id', 'workload', 'iteration', 'metric', ]
|
|
|
|
+ extra_columns + ['value', 'units'])
|
2017-03-20 16:24:22 +00:00
|
|
|
|
2017-11-06 17:04:40 +00:00
|
|
|
for o in outputs:
|
|
|
|
if o.kind == 'job':
|
|
|
|
header = [o.id, o.label, o.iteration]
|
|
|
|
elif o.kind == 'run':
|
|
|
|
# Should be a RunOutput. Run-level metrics aren't attached
|
|
|
|
# to any job so we leave 'id' and 'iteration' blank, and use
|
|
|
|
# the run name for the 'label' field.
|
|
|
|
header = [None, o.info.run_name, None]
|
|
|
|
else:
|
|
|
|
raise RuntimeError(
|
|
|
|
'Output of kind "{}" unrecognised by csvproc'.format(o.kind))
|
|
|
|
|
2017-03-20 16:24:22 +00:00
|
|
|
for metric in o.result.metrics:
|
2020-10-19 18:09:04 +01:00
|
|
|
row = (header + [metric.name]
|
|
|
|
+ [str(metric.classifiers.get(c, ''))
|
|
|
|
for c in extra_columns]
|
|
|
|
+ [str(metric.value), metric.units or ''])
|
2017-03-20 16:24:22 +00:00
|
|
|
writer.writerow(row)
|