summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVincent Guittot <vincent.guittot@linaro.org>2018-02-27 09:44:41 +0100
committerVincent Guittot <vincent.guittot@linaro.org>2018-02-27 09:45:29 +0100
commit471e397f97a033d941e845e2e6d987a287965cff (patch)
treecb87395f04b675ecfbcabb0b42551cbd8b4c4fbf
parent6f8fffe6c42a6f9aa1a2e1fa13f447af586f69d6 (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__.py35
-rwxr-xr-xparse_aep.py179
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)