Quentin Perret | 7a827e2 | 2017-05-17 18:17:29 +0100 | [diff] [blame] | 1 | # Copyright 2017 ARM Limited |
| 2 | # |
| 3 | # Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 | # you may not use this file except in compliance with the License. |
| 5 | # You may obtain a copy of the License at |
| 6 | # |
| 7 | # http://www.apache.org/licenses/LICENSE-2.0 |
| 8 | # |
| 9 | # Unless required by applicable law or agreed to in writing, software |
| 10 | # distributed under the License is distributed on an "AS IS" BASIS, |
| 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 | # See the License for the specific language governing permissions and |
| 13 | # limitations under the License. |
| 14 | |
| 15 | from __future__ import division |
| 16 | import csv |
| 17 | import re |
| 18 | |
| 19 | from devlib.platform.gem5 import Gem5SimulationPlatform |
| 20 | from devlib.instrument import Instrument, CONTINUOUS, MeasurementsCsv |
| 21 | from devlib.exception import TargetError, HostError |
| 22 | |
| 23 | |
| 24 | class Gem5PowerInstrument(Instrument): |
| 25 | ''' |
| 26 | Instrument enabling power monitoring in gem5 |
| 27 | ''' |
| 28 | |
| 29 | mode = CONTINUOUS |
| 30 | roi_label = 'power_instrument' |
Marc Bonnici | 411719d | 2017-08-18 17:06:28 +0100 | [diff] [blame^] | 31 | site_mapping = {'timestamp': 'sim_seconds'} |
Marc Bonnici | 7dd934a | 2017-08-03 16:41:10 +0100 | [diff] [blame] | 32 | |
Quentin Perret | 7a827e2 | 2017-05-17 18:17:29 +0100 | [diff] [blame] | 33 | def __init__(self, target, power_sites): |
| 34 | ''' |
Marc Bonnici | 7dd934a | 2017-08-03 16:41:10 +0100 | [diff] [blame] | 35 | Parameter power_sites is a list of gem5 identifiers for power values. |
Quentin Perret | 7a827e2 | 2017-05-17 18:17:29 +0100 | [diff] [blame] | 36 | One example of such a field: |
| 37 | system.cluster0.cores0.power_model.static_power |
| 38 | ''' |
| 39 | if not isinstance(target.platform, Gem5SimulationPlatform): |
| 40 | raise TargetError('Gem5PowerInstrument requires a gem5 platform') |
| 41 | if not target.has('gem5stats'): |
| 42 | raise TargetError('Gem5StatsModule is not loaded') |
| 43 | super(Gem5PowerInstrument, self).__init__(target) |
| 44 | |
| 45 | # power_sites is assumed to be a list later |
| 46 | if isinstance(power_sites, list): |
| 47 | self.power_sites = power_sites |
| 48 | else: |
| 49 | self.power_sites = [power_sites] |
Marc Bonnici | 411719d | 2017-08-18 17:06:28 +0100 | [diff] [blame^] | 50 | self.add_channel('timestamp', 'time') |
Quentin Perret | 7a827e2 | 2017-05-17 18:17:29 +0100 | [diff] [blame] | 51 | for field in self.power_sites: |
| 52 | self.add_channel(field, 'power') |
| 53 | self.target.gem5stats.book_roi(self.roi_label) |
| 54 | self.sample_period_ns = 10000000 |
Marc Bonnici | 7dd934a | 2017-08-03 16:41:10 +0100 | [diff] [blame] | 55 | # Sample rate must remain unset as gem5 does not provide samples |
| 56 | # at regular intervals therefore the reported timestamp should be used. |
| 57 | self.sample_rate_hz = None |
Quentin Perret | 7a827e2 | 2017-05-17 18:17:29 +0100 | [diff] [blame] | 58 | self.target.gem5stats.start_periodic_dump(0, self.sample_period_ns) |
Quentin Perret | 38258eb | 2017-07-21 16:13:31 +0100 | [diff] [blame] | 59 | self._base_stats_dump = 0 |
Quentin Perret | 7a827e2 | 2017-05-17 18:17:29 +0100 | [diff] [blame] | 60 | |
| 61 | def start(self): |
| 62 | self.target.gem5stats.roi_start(self.roi_label) |
| 63 | |
| 64 | def stop(self): |
| 65 | self.target.gem5stats.roi_end(self.roi_label) |
Marc Bonnici | 7dd934a | 2017-08-03 16:41:10 +0100 | [diff] [blame] | 66 | |
Quentin Perret | 7a827e2 | 2017-05-17 18:17:29 +0100 | [diff] [blame] | 67 | def get_data(self, outfile): |
| 68 | active_sites = [c.site for c in self.active_channels] |
| 69 | with open(outfile, 'wb') as wfh: |
| 70 | writer = csv.writer(wfh) |
| 71 | writer.writerow([c.label for c in self.active_channels]) # headers |
Marc Bonnici | 411719d | 2017-08-18 17:06:28 +0100 | [diff] [blame^] | 72 | sites_to_match = [self.site_mapping.get(s, s) for s in active_sites] |
| 73 | for rec, rois in self.target.gem5stats.match_iter(sites_to_match, |
Quentin Perret | 38258eb | 2017-07-21 16:13:31 +0100 | [diff] [blame] | 74 | [self.roi_label], self._base_stats_dump): |
Quentin Perret | 7a827e2 | 2017-05-17 18:17:29 +0100 | [diff] [blame] | 75 | writer.writerow([float(rec[s]) for s in active_sites]) |
| 76 | return MeasurementsCsv(outfile, self.active_channels) |
Marc Bonnici | 7dd934a | 2017-08-03 16:41:10 +0100 | [diff] [blame] | 77 | |
Quentin Perret | 7a827e2 | 2017-05-17 18:17:29 +0100 | [diff] [blame] | 78 | def reset(self, sites=None, kinds=None, channels=None): |
| 79 | super(Gem5PowerInstrument, self).reset(sites, kinds, channels) |
Quentin Perret | 38258eb | 2017-07-21 16:13:31 +0100 | [diff] [blame] | 80 | self._base_stats_dump = self.target.gem5stats.next_dump_no() |
Quentin Perret | 7a827e2 | 2017-05-17 18:17:29 +0100 | [diff] [blame] | 81 | |