1# Copyright 2015-2016 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"""A thermal specific library to assert certain thermal 16behaviours 17""" 18 19from bart.common import Utils 20from bart.common.Analyzer import Analyzer 21import numpy as np 22 23 24# pylint: disable=invalid-name 25# pylint: disable=too-many-arguments 26class ThermalAssert(object): 27 28 """A class that accepts a TRAPpy FTrace object and 29 provides assertions for thermal behaviours 30 31 :param ftrace: A path to the trace file or a TRAPpy FTrace object 32 :type ftrace: str, :mod:`trappy.ftrace.FTrace` 33 """ 34 35 def __init__(self, ftrace, config=None): 36 37 self._ftrace = Utils.init_ftrace(ftrace) 38 self._analyzer = Analyzer(self._ftrace, config) 39 40 def getThermalResidency(self, temp_range, window, percent=False): 41 """Return the total time spent in a given temperature range 42 43 :param temp_range: A tuple of (low_temp, high_temp) 44 which specifies the range of temperature that 45 one intends to calculate the residency for. 46 :type temp_range: tuple 47 48 :param window: A (start, end) tuple to limit the scope of the 49 residency calculation. 50 :type window: tuple 51 52 :param percent: Returns the residency as a percentage of the total 53 duration of the trace 54 :type percent: bool 55 56 .. seealso: 57 58 :mod:`bart.thermal.ThermalAssert.ThermalAssert.assertThermalResidency` 59 """ 60 61 # Get a pivoted thermal temperature data using the grammar 62 data = self._analyzer.getStatement("trappy.thermal.Thermal:temp") 63 64 result = {} 65 for pivot, data_frame in data.groupby(axis=1, level=0): 66 67 series = data_frame[pivot] 68 series = Utils.select_window(series, window) 69 mask = (series >= temp_range[0]) & (series <= temp_range[1]) 70 index = series.index.values 71 # pylint fails to recognize numpy members. 72 # pylint: disable=no-member 73 shift_index = np.roll(index, 1) 74 # pylint: enable=no-member 75 shift_index[0] = 0 76 77 result[pivot] = sum((index - shift_index)[mask.values]) 78 79 if percent: 80 result[pivot] = ( 81 result[pivot] * 100.0) / self._ftrace.get_duration() 82 83 return result 84 85 def assertThermalResidency( 86 self, 87 expected_value, 88 operator, 89 temp_range, 90 window, 91 percent=False): 92 """ 93 :param expected_value: The expected value of the residency 94 :type expected_value: double 95 96 :param operator: A binary operator function that returns 97 a boolean. For example: 98 :: 99 100 import operator 101 op = operator.ge 102 assertThermalResidency(temp_range, expected_value, op) 103 104 Will do the following check: 105 :: 106 107 getThermalResidency(temp_range) >= expected_value 108 109 A custom function can also be passed: 110 :: 111 112 THRESHOLD=5 113 def between_threshold(a, expected): 114 return abs(a - expected) <= THRESHOLD 115 116 :param temp_range: A tuple of (low_temp, high_temp) 117 which specifies the range of temperature that 118 one intends to calculate the residency for. 119 :type temp_range: tuple 120 121 :param window: A (start, end) tuple to limit the scope of the 122 residency calculation. 123 :type window: tuple 124 125 :param percent: Returns the residency as a percentage of the total 126 duration of the trace 127 :type percent: bool 128 129 .. seealso: 130 131 :mod:`bart.thermal.ThermalAssert.ThermalAssert.assertThermalResidency` 132 """ 133 134 residency = self.getThermalResidency(temp_range, window, percent) 135 return operator(residency, expected_value) 136