diff options
author | Vincent Guittot <vincent.guittot@linaro.org> | 2018-02-27 09:44:41 +0100 |
---|---|---|
committer | Vincent Guittot <vincent.guittot@linaro.org> | 2018-02-27 09:45:29 +0100 |
commit | 471e397f97a033d941e845e2e6d987a287965cff (patch) | |
tree | cb87395f04b675ecfbcabb0b42551cbd8b4c4fbf | |
parent | 6f8fffe6c42a6f9aa1a2e1fa13f447af586f69d6 (diff) |
parse aep: clean up and align code with devlib
Clean up the code and align the script with devlib
Signed-off-by: Vincent Guittot <vincent.guittot@linaro.org>
-rw-r--r-- | __init__.py | 35 | ||||
-rwxr-xr-x | parse_aep.py | 179 |
2 files changed, 106 insertions, 108 deletions
diff --git a/__init__.py b/__init__.py index 2371e6b..c5c4b32 100644 --- a/__init__.py +++ b/__init__.py @@ -27,7 +27,7 @@ except ImportError: pandas = None sys.path.append(os.path.dirname(sys.modules[__name__].__file__)) -from parse_aep import AEP_parser +from parse_aep import AepParser from wlauto import Instrument, Parameter, Executable from wlauto.exceptions import InstrumentError, ConfigError @@ -37,18 +37,23 @@ from wlauto.utils.types import list_of_numbers class ArmEnergyProbe(Instrument): name = 'energy_probe_ext' - description = """Collects power traces using the ARM Energy Probe. - - This instrument requires ``arm-probe`` utility to be installed in the workload automation - host and be in the PATH. arm-probe is available here ``https://git.linaro.org/tools/arm-probe.git`` . - ARM energy probe device can simultaneously collect power from up to 3 power rails and - arm-probe utility can record data from several devices simultaneously. - - To connect the energy probe on a rail, connect the white wire to the pin that is closer to the - Voltage source and the black wire to the pin that is closer to the load (the SoC or the device - you are probing). Between the pins there should be a shunt resistor of known resistance in the - range of 5 to 500 mOhm but the voltage on the shunt resistor must stay smaller than 165mV. - The resistance of the shunt resistors is a mandatory parameter to be set in the ``config`` file. + description = """ Collects power traces using the ARM Energy Probe. + + This instrument requires ``arm-probe`` utility to be installed on the host and be in the PATH. + arm-probe is available here: + ``https://git.linaro.org/tools/arm-probe.git``. + + Details about how to build and use it is available here: + ``https://git.linaro.org/tools/arm-probe.git/tree/README`` + + ARM energy probe (AEP) device can simultaneously collect power from up to 3 power rails and + arm-probe utility can record data from several AEP devices simultaneously. + + To connect the energy probe on a rail, connect the white wire to the pin that is closer to the + Voltage source and the black wire to the pin that is closer to the load (the SoC or the device + you are probing). Between the pins there should be a shunt resistor of known resistance in the + range of 5 to 500 mOhm but the voltage on the shunt resistor must stay smaller than 165mV. + The resistance of the shunt resistors is a mandatory parameter to be set in the ``config`` file. """ parameters = [ @@ -90,9 +95,9 @@ class ArmEnergyProbe(Instrument): def update_result(self, context): # pylint: disable=too-many-locals self.logger.debug("Parse data and compute consumed energy") - self.parser = AEP_parser() + self.parser = AepParser() self.parser.prepare(self.output_file_raw, self.output_file, self.output_file_figure) - aep_table = self.parser.parse_AEP() + aep_table = self.parser.parse_aep() self.parser.unprepare() self.output_fd_error.close() diff --git a/parse_aep.py b/parse_aep.py index 84d4640..2b48d47 100755 --- a/parse_aep.py +++ b/parse_aep.py @@ -1,5 +1,5 @@ #!/usr/bin/env python -# Copyright 2013-2015 ARM Limited +# Copyright 2018 Linaro Limited # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -17,81 +17,34 @@ import os import sys import getopt import subprocess +import logging import signal import serial import time import math -class AEP_parser: - prepared = False - - def prepare(self, infile, outfile, summaryfile, verbose = False): - self.verbose = verbose - - try: - self.fi = open(infile, "r") - except IOError: - print "WARN: Unable to open input file %s" % (infile) - print "Usage: parse_arp.py -i <inputfile> [-o <outputfile>]" - sys.exit(2) - - self.parse = True - if len(outfile) > 0: - try: - self.fo = open(outfile, "w") - except IOError: - print "WARN: Unable to create %s" % (outfile) - self.parse = False - else: - self.parse = False - - self.summary = True - if len(summaryfile) > 0: - try: - self.fs = open(summaryfile, "w") - except IOError: - print "WARN: Unable to create %s" % (summaryfile) - self.fs = sys.stdout - else: - self.fs = sys.stdout - - self.prepared = True - - - def unprepare(self): - if not self.prepared: - # nothing has been prepared - return - - self.fi.close() - - if self.parse: - self.fo.close() - - self.prepared = False - - - def __del__(self): - self.unprepare() +logger = logging.getLogger('aep-parser') +class AepParser(object): + prepared = False @staticmethod def topology_from_data(array, topo): # Extract topology information for the data file - # The header of a data file looks like this: -# configuration: <file path> -# config_name: <file name> -# trigger: 0.400000V (hyst 0.200000V) 0.000000W (hyst 0.200000W) 400us -# date: Fri, 10 Jun 2016 11:25:07 +0200 -# host: <host name> -# -# CHN_0 Pretty_name_0 PARENT_0 Color0 Class0 -# CHN_1 Pretty_name_1 PARENT_1 Color1 Class1 -# CHN_2 Pretty_name_2 PARENT_2 Color2 Class2 -# CHN_3 Pretty_name_3 PARENT_3 Color3 Class3 -# .. -# CHN_N Pretty_name_N PARENT_N ColorN ClassN -# + # The header of a data file looks like this ('#' included): + # configuration: <file path> + # config_name: <file name> + # trigger: 0.400000V (hyst 0.200000V) 0.000000W (hyst 0.200000W) 400us + # date: Fri, 10 Jun 2016 11:25:07 +0200 + # host: <host name> + # + # CHN_0 Pretty_name_0 PARENT_0 Color0 Class0 + # CHN_1 Pretty_name_1 PARENT_1 Color1 Class1 + # CHN_2 Pretty_name_2 PARENT_2 Color2 Class2 + # CHN_3 Pretty_name_3 PARENT_3 Color3 Class3 + # .. + # CHN_N Pretty_name_N PARENT_N ColorN ClassN + # info = {} @@ -225,7 +178,7 @@ class AEP_parser: return data @staticmethod - def delta_nrj(array, delta, min=[], max=[], hide=[], virtual=[]): + def delta_nrj(array, delta, min, max, hide): # Compute the energy consumed in this time slice and add it # delta[0] is used to save the last time stamp @@ -280,7 +233,50 @@ class AEP_parser: self.fo.write("\n") - def parse_AEP(self, start=0, lenght=-1): + def prepare(self, infile, outfile, summaryfile): + + try: + self.fi = open(infile, "r") + except IOError: + logger.warn('Unable to open input file {}'.format(infile)) + logger.warn('Usage: parse_arp.py -i <inputfile> [-o <outputfile>]') + sys.exit(2) + + self.parse = True + if len(outfile) > 0: + try: + self.fo = open(outfile, "w") + except IOError: + logger.warn('Unable to create {}'.format(outfile)) + self.parse = False + else: + self.parse = False + + self.summary = True + if len(summaryfile) > 0: + try: + self.fs = open(summaryfile, "w") + except IOError: + logger.warn('Unable to create {}'.format(summaryfile)) + self.fs = sys.stdout + else: + self.fs = sys.stdout + + self.prepared = True + + def unprepare(self): + if not self.prepared: + # nothing has been prepared + return + + self.fi.close() + + if self.parse: + self.fo.close() + + self.prepared = False + + def parse_aep(self, start=0, lenght=-1): # Parse aep data and calculate the energy consumed begin = 0 @@ -311,19 +307,13 @@ class AEP_parser: if self.parse: self.output_label(label, hide) - if self.verbose: - print "Topology :" - print topo - print "Virtual power domain :" - print virtual - print "Duplicated power domain :" - print duplicate - print "Name of columns :" - print label - print "Hidden columns :" - print hide - print "Unit of columns :" - print unit + logger.debug('Topology : {}'.format(topo)) + logger.debug('Virtual power domain : {}'.format(virtual)) + logger.debug('Duplicated power domain : : {}'.format(duplicate)) + logger.debug('Name of columns : {}'.format(label)) + logger.debug('Hidden columns : {}'.format(hide)) + logger.debug('Unit of columns : {}'.format(unit)) + # Init arrays nrj = [0]*len(label) min = [100000000]*len(label) @@ -359,7 +349,7 @@ class AEP_parser: # if there is no data just return if label_line or len(nrj) == 1: - print "No data found in the data file. Please check the Arm Energy Probe" + raise ValueError('No data found in the data file. Please check the Arm Energy Probe') return # display energy consumption of each channel and total energy consumption @@ -404,7 +394,7 @@ class AEP_parser: try: ft = open(topofile, "r") except IOError: - print "WARN: Unable to open config file %s" % (topofile) + logger.warn('Unable to open config file {}'.format(topofile)) return lines = ft.readlines() @@ -471,10 +461,8 @@ class AEP_parser: topo_list = ['']*(1+len(topo)+len(virtual)) topo_list[0] = 'time' for chnl in topo.iterkeys(): - print chnl topo_list[topo[chnl]['index']] = chnl for chnl in virtual.iterkeys(): - print chnl index +=1 topo_list[index] = chnl @@ -482,6 +470,9 @@ class AEP_parser: return topo_list + def __del__(self): + self.unprepare() + if __name__ == '__main__': def handleSigTERM(signum, frame): @@ -490,8 +481,12 @@ if __name__ == '__main__': signal.signal(signal.SIGTERM, handleSigTERM) signal.signal(signal.SIGINT, handleSigTERM) + logger.setLevel(logging.WARN) + ch = logging.StreamHandler() + ch.setLevel(logging.DEBUG) + logger.addHandler(ch) + infile = "" - verbose = False outfile = "" figurefile = "" start = 0 @@ -507,22 +502,20 @@ if __name__ == '__main__': if o == "-i": infile = a if o == "-v": - verbose = True + logger.setLevel(logging.DEBUG) if o == "-o": parse = True outfile = a - if o == "-s": start = int(float(a)*1000000) if o == "-l": lenght = int(float(a)*1000000) if o == "-t": topofile = a - parser = AEP_parser() + parser = AepParser() print parser.topology_from_config(topofile) exit(0) - parser = AEP_parser() - parser.prepare(infile, outfile, figurefile, verbose, ) - parser.parse_AEP(start, lenght) - + parser = AepParser() + parser.prepare(infile, outfile, figurefile) + parser.parse_aep(start, lenght) |