From 7a827e2b116c4fed24ec9076d7b0689cb1f55a96 Mon Sep 17 00:00:00 2001 From: Quentin Perret Date: Wed, 17 May 2017 18:17:29 +0100 Subject: [PATCH] instrument: Add power monitoring support on Gem5 platforms --- devlib/__init__.py | 1 + devlib/instrument/gem5power.py | 74 ++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+) create mode 100644 devlib/instrument/gem5power.py diff --git a/devlib/__init__.py b/devlib/__init__.py index 911c50d..2f50632 100644 --- a/devlib/__init__.py +++ b/devlib/__init__.py @@ -17,6 +17,7 @@ from devlib.instrument.frames import GfxInfoFramesInstrument from devlib.instrument.hwmon import HwmonInstrument from devlib.instrument.monsoon import MonsoonInstrument from devlib.instrument.netstats import NetstatsInstrument +from devlib.instrument.gem5power import Gem5PowerInstrument from devlib.trace.ftrace import FtraceCollector diff --git a/devlib/instrument/gem5power.py b/devlib/instrument/gem5power.py new file mode 100644 index 0000000..6411b3f --- /dev/null +++ b/devlib/instrument/gem5power.py @@ -0,0 +1,74 @@ +# Copyright 2017 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. + +from __future__ import division +import csv +import re + +from devlib.platform.gem5 import Gem5SimulationPlatform +from devlib.instrument import Instrument, CONTINUOUS, MeasurementsCsv +from devlib.exception import TargetError, HostError + + +class Gem5PowerInstrument(Instrument): + ''' + Instrument enabling power monitoring in gem5 + ''' + + mode = CONTINUOUS + roi_label = 'power_instrument' + + def __init__(self, target, power_sites): + ''' + Parameter power_sites is a list of gem5 identifiers for power values. + One example of such a field: + system.cluster0.cores0.power_model.static_power + ''' + if not isinstance(target.platform, Gem5SimulationPlatform): + raise TargetError('Gem5PowerInstrument requires a gem5 platform') + if not target.has('gem5stats'): + raise TargetError('Gem5StatsModule is not loaded') + super(Gem5PowerInstrument, self).__init__(target) + + # power_sites is assumed to be a list later + if isinstance(power_sites, list): + self.power_sites = power_sites + else: + self.power_sites = [power_sites] + self.add_channel('sim_seconds', 'time') + for field in self.power_sites: + self.add_channel(field, 'power') + self.target.gem5stats.book_roi(self.roi_label) + self.sample_period_ns = 10000000 + self.target.gem5stats.start_periodic_dump(0, self.sample_period_ns) + + def start(self): + self.target.gem5stats.roi_start(self.roi_label) + + def stop(self): + self.target.gem5stats.roi_end(self.roi_label) + + def get_data(self, outfile): + active_sites = [c.site for c in self.active_channels] + with open(outfile, 'wb') as wfh: + writer = csv.writer(wfh) + writer.writerow([c.label for c in self.active_channels]) # headers + for rec, rois in self.target.gem5stats.match_iter(active_sites, [self.roi_label]): + writer.writerow([float(rec[s]) for s in active_sites]) + return MeasurementsCsv(outfile, self.active_channels) + + def reset(self, sites=None, kinds=None, channels=None): + super(Gem5PowerInstrument, self).reset(sites, kinds, channels) + self.target.gem5stats.reset_origin() +