trace.py revision a8fdc5fe3719b498318e0451f5b4cdfac1f5015e
1d95e98d88a6cf4347853427dc4ef6fd0222a3881Patrick Bellasi# SPDX-License-Identifier: Apache-2.0 2d95e98d88a6cf4347853427dc4ef6fd0222a3881Patrick Bellasi# 3d95e98d88a6cf4347853427dc4ef6fd0222a3881Patrick Bellasi# Copyright (C) 2015, ARM Limited and contributors. 4d95e98d88a6cf4347853427dc4ef6fd0222a3881Patrick Bellasi# 5d95e98d88a6cf4347853427dc4ef6fd0222a3881Patrick Bellasi# Licensed under the Apache License, Version 2.0 (the "License"); you may 6d95e98d88a6cf4347853427dc4ef6fd0222a3881Patrick Bellasi# not use this file except in compliance with the License. 7d95e98d88a6cf4347853427dc4ef6fd0222a3881Patrick Bellasi# You may obtain a copy of the License at 8d95e98d88a6cf4347853427dc4ef6fd0222a3881Patrick Bellasi# 9d95e98d88a6cf4347853427dc4ef6fd0222a3881Patrick Bellasi# http://www.apache.org/licenses/LICENSE-2.0 10d95e98d88a6cf4347853427dc4ef6fd0222a3881Patrick Bellasi# 11d95e98d88a6cf4347853427dc4ef6fd0222a3881Patrick Bellasi# Unless required by applicable law or agreed to in writing, software 12d95e98d88a6cf4347853427dc4ef6fd0222a3881Patrick Bellasi# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 13d95e98d88a6cf4347853427dc4ef6fd0222a3881Patrick Bellasi# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14d95e98d88a6cf4347853427dc4ef6fd0222a3881Patrick Bellasi# See the License for the specific language governing permissions and 15d95e98d88a6cf4347853427dc4ef6fd0222a3881Patrick Bellasi# limitations under the License. 16d95e98d88a6cf4347853427dc4ef6fd0222a3881Patrick Bellasi# 178e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi 188e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasiimport glob 198e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasiimport matplotlib.gridspec as gridspec 208e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasiimport matplotlib.pyplot as plt 218e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasiimport numpy as np 228e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasiimport os 238e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasiimport pandas as pd 248e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasiimport pylab as pl 258e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasiimport re 268e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasiimport sys 278e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasiimport trappy 288e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi 298e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi# Configure logging 308e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasiimport logging 318e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi 328e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasiclass Trace(object): 338e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi 34a8fdc5fe3719b498318e0451f5b4cdfac1f5015ePatrick Bellasi def __init__(self, platform, datadir, events, tasks=None, window=(0,None)): 358e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi 368e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi # The platform used to run the experiments 378e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi self.platform = None 388e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi 398e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi # Dataframe of all events data 408e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi self.trace_data = {} 418e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi 428e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi # Folder containing all perf data 438e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi self.datadir = None 448e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi 458e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi # TRAPpy run object 468e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi self.run = None 478e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi 48a8fdc5fe3719b498318e0451f5b4cdfac1f5015ePatrick Bellasi # The time window used to limit trace parsing to 49a8fdc5fe3719b498318e0451f5b4cdfac1f5015ePatrick Bellasi self.window = window 50a8fdc5fe3719b498318e0451f5b4cdfac1f5015ePatrick Bellasi 518e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi # Dynamically registered TRAPpy events 528e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi self.trappy_cls = {} 538e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi 548e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi # Maximum timespan for all collected events 558e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi self.time_range = 0 568e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi 578e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi # The dictionary of tasks descriptors available in the dataset 588e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi self.tasks = {} 598e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi 60e24e02a9565a8ca8f948e15b573eeb808b8ece86Patrick Bellasi # List of events required by user 61e24e02a9565a8ca8f948e15b573eeb808b8ece86Patrick Bellasi self.events = [] 62e24e02a9565a8ca8f948e15b573eeb808b8ece86Patrick Bellasi 638e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi # List of events available in the parsed trace 648e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi self.available_events = [] 658e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi 668e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi # Folder containing trace 678e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi self.datadir = datadir 688e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi 698e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi # Platform descriptor 708e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi self.platform = platform 718e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi 72e24e02a9565a8ca8f948e15b573eeb808b8ece86Patrick Bellasi self.__registerTraceEvents(events) 73a8fdc5fe3719b498318e0451f5b4cdfac1f5015ePatrick Bellasi self.__parseTrace(datadir, tasks, window) 748e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi self.__computeTimeSpan() 758e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi 76e24e02a9565a8ca8f948e15b573eeb808b8ece86Patrick Bellasi def __registerTraceEvents(self, events): 77e09821241ca9697b75c8a53fb0813212202d1c65Patrick Bellasi 78e24e02a9565a8ca8f948e15b573eeb808b8ece86Patrick Bellasi if isinstance(events, basestring): 79e24e02a9565a8ca8f948e15b573eeb808b8ece86Patrick Bellasi self.events = events.split(' ') 80e24e02a9565a8ca8f948e15b573eeb808b8ece86Patrick Bellasi elif isinstance(events, list): 81e24e02a9565a8ca8f948e15b573eeb808b8ece86Patrick Bellasi self.events = events 82e24e02a9565a8ca8f948e15b573eeb808b8ece86Patrick Bellasi else: 83e24e02a9565a8ca8f948e15b573eeb808b8ece86Patrick Bellasi raise ValueError('Events must be a string or a list of strings') 848e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi 858e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi 86a8fdc5fe3719b498318e0451f5b4cdfac1f5015ePatrick Bellasi def __parseTrace(self, datadir, tasks, window): 878e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi logging.debug('Loading [sched] events from trace in [%s]...', datadir) 88e24e02a9565a8ca8f948e15b573eeb808b8ece86Patrick Bellasi logging.debug("Parsing events: %s", self.events) 89a8fdc5fe3719b498318e0451f5b4cdfac1f5015ePatrick Bellasi self.run = trappy.Run(datadir, scope="custom", events=self.events, window=window) 908e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi 918e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi # Check for events available on the parsed trace 928e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi self.__checkAvailableEvents() 938e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi if len(self.available_events) == 0: 948e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi raise ValueError('The trace does not contain useful events') 958e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi 968e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi # Setup internal data reference to interesting events/dataframes 978e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi 988e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi if self.hasEvents('sched_switch'): 998e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi self.trace_data['sswitch'] = \ 1008e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi self.run.sched_switch.data_frame 1018e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi 102e09821241ca9697b75c8a53fb0813212202d1c65Patrick Bellasi if self.hasEvents('sched_wakeup'): 103e09821241ca9697b75c8a53fb0813212202d1c65Patrick Bellasi self.trace_data['swkp'] = \ 104e09821241ca9697b75c8a53fb0813212202d1c65Patrick Bellasi self.run.sched_wakeup.data_frame 105e09821241ca9697b75c8a53fb0813212202d1c65Patrick Bellasi 106e09821241ca9697b75c8a53fb0813212202d1c65Patrick Bellasi if self.hasEvents('sched_wakeup_new'): 107e09821241ca9697b75c8a53fb0813212202d1c65Patrick Bellasi self.trace_data['swkpn'] = \ 108e09821241ca9697b75c8a53fb0813212202d1c65Patrick Bellasi self.run.sched_wakeup_new.data_frame 109e09821241ca9697b75c8a53fb0813212202d1c65Patrick Bellasi 110f53f85ec314a6ef54caa6ca199205f604ab99b99Patrick Bellasi if self.hasEvents('cpu_frequency'): 1118e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi self.trace_data['pfreq'] = \ 112f53f85ec314a6ef54caa6ca199205f604ab99b99Patrick Bellasi self.run.cpu_frequency.data_frame 1138e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi 1148e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi if self.hasEvents('sched_load_avg_cpu'): 1158e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi self.trace_data['cload'] = \ 1168e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi self.run.sched_load_avg_cpu.data_frame 117997f0ca86a715c99bd1adce42c1812d650ea516cPatrick Bellasi self._sanitize_SchedLoadAvgCpu() 1188e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi 1198e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi if self.hasEvents('sched_load_avg_task'): 1208e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi self.trace_data['tload'] = \ 1218e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi self.run.sched_load_avg_task.data_frame 122c5d46e8caeb638b88b75557a30262a6912a86629Patrick Bellasi self._sanitize_SchedLoadAvgTask() 1238e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi 1248e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi if self.hasEvents('cpu_capacity'): 1258e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi self.trace_data['ccap'] = \ 1268e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi self.run.cpu_capacity.data_frame 127c5d46e8caeb638b88b75557a30262a6912a86629Patrick Bellasi self._sanitize_SchedCpuCapacity() 1288e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi 1298e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi if self.hasEvents('sched_boost_cpu'): 1308e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi self.trace_data['cboost'] = \ 1318e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi self.run.sched_boost_cpu.data_frame 132c5d46e8caeb638b88b75557a30262a6912a86629Patrick Bellasi self._sanitize_SchedBoostCpu() 1338e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi 1348e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi if self.hasEvents('sched_boost_task'): 1358e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi self.trace_data['tboost'] = \ 1368e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi self.run.sched_boost_task.data_frame 137c5d46e8caeb638b88b75557a30262a6912a86629Patrick Bellasi self._sanitize_SchedBoostTask() 1388e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi 1398e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi if self.hasEvents('sched_contrib_scale_f'): 1408e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi self.trace_data['scalef'] = \ 1418e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi self.run.sched_contrib_scale_f.data_frame 1428e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi 1438e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi if self.hasEvents('sched_energy_diff'): 1448e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi self.trace_data['ediff'] = \ 1458e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi self.run.sched_energy_diff.data_frame 146c5d46e8caeb638b88b75557a30262a6912a86629Patrick Bellasi self._sanitize_SchedEnergyDiff() 1478e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi 1488e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi if self.hasEvents('sched_tune_config'): 1498e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi self.trace_data['stune'] = \ 1508e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi self.run.sched_tune_config.data_frame 1518e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi 1528e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi if self.hasEvents('sched_tune_tasks_update'): 1538e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi self.trace_data['utask'] = \ 1548e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi self.run.sched_tune_tasks_update.data_frame 1558e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi 1568e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi self.__loadTasksNames(tasks) 1578e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi 1588e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi 1598e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi def __checkAvailableEvents(self): 1608e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi for val in trappy.Run.get_filters(self.run): 1618e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi obj = getattr(self.run, val) 1628e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi if len(obj.data_frame): 1638e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi self.available_events.append(val) 1648e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi logging.debug('Events found on trace:') 1658e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi for evt in self.available_events: 1668e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi logging.debug(' - %s', evt) 1678e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi 1688e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi 1698e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi def __loadTasksNames(self, tasks): 1708e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi # Try to load tasks names using one of the supported events 1718e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi if 'sched_switch' in self.available_events: 1728e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi self.getTasks(self.trace_data['sswitch'], tasks, 1738e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi name_key='next_comm', pid_key='next_pid') 1748e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi return 1758e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi if 'sched_load_avg_task' in self.available_events: 1768e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi self.getTasks(self.trace_data['tload'], tasks) 1778e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi return 1788e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi logging.warning('Failed to load tasks names from trace events') 1798e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi 1808e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi def hasEvents(self, dataset): 1818e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi if dataset in self.available_events: 1828e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi return True 1838e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi return False 1848e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi 1858e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi def __computeTimeSpan(self): 1868e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi # Compute time axis range, considering all the parsed events 1878e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi ts = sys.maxint 1888e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi te = 0 1898e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi 1908e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi for key in self.trace_data.keys(): 1918e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi df = self.trace_data[key] 1928e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi if len(df) == 0: 1938e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi continue 1948e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi if (df.index[0]) < ts: 1958e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi ts = df.index[0] 1968e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi if (df.index[-1]) > te: 1978e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi te = df.index[-1] 1988e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi self.time_range = te - ts 1998e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi 2008e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi logging.info('Collected events spans a %.3f [s] time interval', 2018e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi self.time_range) 2028e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi 2038e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi def getTasks(self, dataframe=None, 2048e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi task_names=None, name_key='comm', pid_key='pid'): 2058e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi # """ Helper function to get PIDs of specified tasks 2068e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi # 2078e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi # This method requires a Pandas dataset in input to be used to 2088e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi # fiter out the PIDs of all the specified tasks. 2098e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi # In a dataset is not provided, previouslt filtered PIDs are 2108e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi # returned. 2118e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi # If a list of task names is not provided, the workload defined 2128e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi # task names is used instead. 2138e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi # The specified dataframe must provide at least two columns 2148e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi # reporting the task name and the task PID. The default values of 2158e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi # this colums could be specified using the provided parameters. 2168e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi # 2178e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi # :param task_names: The list of tasks to get the PID of (by default 2188e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi # the workload defined tasks) 2198e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi # :param dataframe: A Pandas datafram containing at least 'pid' and 2208e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi # 'task name' columns. If None, the previously 2218e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi # filtered PIDs are returned 2228e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi # :param name_key: The name of the dataframe columns containing 2238e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi # task names 2248e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi # :param pid_key: The name of the dataframe columns containing 2258e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi # task PIDs 2268e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi # """ 2278e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi if dataframe is None: 2288e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi return self.tasks 2298e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi df = dataframe 2308e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi if task_names is None: 2318e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi task_names = self.tasks.keys() 2328e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi logging.debug("Lookup dataset for tasks...") 2338e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi for tname in task_names: 2348e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi logging.debug("Lookup for task [%s]...", tname) 2358e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi results = df[df[name_key] == tname][[name_key,pid_key]] 2368e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi if len(results)==0: 2378e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi logging.error(' task %16s NOT found', tname) 2388e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi continue 2398e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi (name, pid) = results.head(1).values[0] 2408e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi if name!=tname: 2418e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi logging.error(' task %16s NOT found', tname) 2428e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi continue 2438e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi if (tname not in self.tasks): 2448e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi self.tasks[tname] = {} 2458e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi pids = list(results[pid_key].unique()) 2468e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi self.tasks[tname]['pid'] = pids 2478e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi logging.info(' task %16s found, pid: %s', 2488e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi tname, self.tasks[tname]['pid']) 2498e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi return self.tasks 2508e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi 2518e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi def df(self, event): 2528e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi """ 2538e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi Return the PANDAS dataframe with the performance data for the specified 2548e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi event 2558e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi """ 2568e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi if self.datadir is None: 2578e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi raise ValueError("trace data not (yet) loaded") 2588e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi if event not in self.trace_data: 2598e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi raise ValueError('Event [{}] not supported. '\ 2608e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi 'Supported events are: {}'\ 2618e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi .format(event, self.trace_data.keys())) 2628e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi return self.trace_data[event] 2638e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi 264c5d46e8caeb638b88b75557a30262a6912a86629Patrick Bellasi def _sanitize_SchedCpuCapacity(self): 2658e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi df = self.df('ccap') 266680ad8b9c70754064b686e1fcea6db022bc5e152Patrick Bellasi 267680ad8b9c70754064b686e1fcea6db022bc5e152Patrick Bellasi # Add more columns if the energy model is available 268680ad8b9c70754064b686e1fcea6db022bc5e152Patrick Bellasi if 'nrg_model' not in self.platform: 269680ad8b9c70754064b686e1fcea6db022bc5e152Patrick Bellasi return 270680ad8b9c70754064b686e1fcea6db022bc5e152Patrick Bellasi 2718e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi # Add column with LITTLE and big CPUs max capacities 2728e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi nrg_model = self.platform['nrg_model'] 2738e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi max_lcap = nrg_model['little']['cpu']['cap_max'] 2748e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi max_bcap = nrg_model['big']['cpu']['cap_max'] 2758e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi df['max_capacity'] = np.select( 2768e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi [df.cpu.isin(self.platform['clusters']['little'])], 2778e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi [max_lcap], max_bcap) 2788e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi # Add LITTLE and big CPUs "tipping point" threshold 2798e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi tip_lcap = 0.8 * max_lcap 2808e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi tip_bcap = 0.8 * max_bcap 2818e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi df['tip_capacity'] = np.select( 2828e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi [df.cpu.isin(self.platform['clusters']['little'])], 2838e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi [tip_lcap], tip_bcap) 2848e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi 285997f0ca86a715c99bd1adce42c1812d650ea516cPatrick Bellasi def _sanitize_SchedLoadAvgCpu(self): 286997f0ca86a715c99bd1adce42c1812d650ea516cPatrick Bellasi df = self.df('cload') 287997f0ca86a715c99bd1adce42c1812d650ea516cPatrick Bellasi if 'utilization' in df: 288997f0ca86a715c99bd1adce42c1812d650ea516cPatrick Bellasi # Convert signals name from v5.0 to v5.1 format 289997f0ca86a715c99bd1adce42c1812d650ea516cPatrick Bellasi df.rename(columns={'utilization':'util_avg'}, inplace=True) 290997f0ca86a715c99bd1adce42c1812d650ea516cPatrick Bellasi df.rename(columns={'load':'load_avg'}, inplace=True) 291997f0ca86a715c99bd1adce42c1812d650ea516cPatrick Bellasi 292c5d46e8caeb638b88b75557a30262a6912a86629Patrick Bellasi def _sanitize_SchedLoadAvgTask(self): 2938e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi df = self.df('tload') 29417c7721066c57695ba43bac0c4170c324093d693Patrick Bellasi if 'utilization' in df: 29517c7721066c57695ba43bac0c4170c324093d693Patrick Bellasi # Convert signals name from v5.0 to v5.1 format 29617c7721066c57695ba43bac0c4170c324093d693Patrick Bellasi df.rename(columns={'utilization':'util_avg'}, inplace=True) 29717c7721066c57695ba43bac0c4170c324093d693Patrick Bellasi df.rename(columns={'load':'load_avg'}, inplace=True) 29817c7721066c57695ba43bac0c4170c324093d693Patrick Bellasi df.rename(columns={'avg_period':'period_contrib'}, inplace=True) 29917c7721066c57695ba43bac0c4170c324093d693Patrick Bellasi df.rename(columns={'runnable_avg_sum':'load_sum'}, inplace=True) 30017c7721066c57695ba43bac0c4170c324093d693Patrick Bellasi df.rename(columns={'running_avg_sum':'util_sum'}, inplace=True) 3018e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi df['cluster'] = np.select( 3028e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi [df.cpu.isin(self.platform['clusters']['little'])], 3038e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi ['LITTLE'], 'big') 3048e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi 305c5d46e8caeb638b88b75557a30262a6912a86629Patrick Bellasi def _sanitize_SchedBoostCpu(self): 3068e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi df = self.df('cboost') 30717c7721066c57695ba43bac0c4170c324093d693Patrick Bellasi if 'usage' in df: 30817c7721066c57695ba43bac0c4170c324093d693Patrick Bellasi # Convert signals name from to v5.1 format 30917c7721066c57695ba43bac0c4170c324093d693Patrick Bellasi df.rename(columns={'usage':'util'}, inplace=True) 31017c7721066c57695ba43bac0c4170c324093d693Patrick Bellasi df['boosted_util'] = df['util'] + df['margin'] 31117c7721066c57695ba43bac0c4170c324093d693Patrick Bellasi 3128e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi 313c5d46e8caeb638b88b75557a30262a6912a86629Patrick Bellasi def _sanitize_SchedBoostTask(self): 3148e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi df = self.df('tboost') 315418cfb6405256f744cc3023fd7a5fcbff1f757a7Patrick Bellasi if 'utilization' in df: 316418cfb6405256f744cc3023fd7a5fcbff1f757a7Patrick Bellasi # Convert signals name from to v5.1 format 317418cfb6405256f744cc3023fd7a5fcbff1f757a7Patrick Bellasi df.rename(columns={'utilization':'util'}, inplace=True) 318418cfb6405256f744cc3023fd7a5fcbff1f757a7Patrick Bellasi df['boosted_util'] = df['util'] + df['margin'] 3198e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi 320c5d46e8caeb638b88b75557a30262a6912a86629Patrick Bellasi def _sanitize_SchedEnergyDiff(self): 321680ad8b9c70754064b686e1fcea6db022bc5e152Patrick Bellasi if 'nrg_model' not in self.platform: 322680ad8b9c70754064b686e1fcea6db022bc5e152Patrick Bellasi return 3238e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi nrg_model = self.platform['nrg_model'] 3248e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi em_lcluster = nrg_model['little']['cluster'] 3258e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi em_bcluster = nrg_model['big']['cluster'] 3268e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi em_lcpu = nrg_model['little']['cpu'] 3278e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi em_bcpu = nrg_model['big']['cpu'] 3288e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi lcpus = len(self.platform['clusters']['little']) 3298e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi bcpus = len(self.platform['clusters']['big']) 3308e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi SCHED_LOAD_SCALE = 1024 3318e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi 3328e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi power_max = em_lcpu['nrg_max'] * lcpus + em_bcpu['nrg_max'] * bcpus + \ 3338e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi em_lcluster['nrg_max'] + em_bcluster['nrg_max'] 3348e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi print "Maximum estimated system energy: {0:d}".format(power_max) 3358e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi 3368e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi df = self.df('ediff') 3378e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi df['nrg_diff_pct'] = SCHED_LOAD_SCALE * df.nrg_diff / power_max 3388e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi 3398e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi # Tag columns by usage_delta 3408e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi ccol = df.usage_delta 3418e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi df['usage_delta_group'] = np.select( 3428e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi [ccol < 150, ccol < 400, ccol < 600], 3438e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi ['< 150', '< 400', '< 600'], '>= 600') 3448e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi 3458e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi # Tag columns by nrg_payoff 3468e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi ccol = df.nrg_payoff 3478e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi df['nrg_payoff_group'] = np.select( 3488e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi [ccol > 2e9, ccol > 0, ccol > -2e9], 3498e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi ['Optimal Accept', 'SchedTune Accept', 'SchedTune Reject'], 'Suboptimal Reject') 3508e6284e58870ec8b4e5fd02186668934287a22f5Patrick Bellasi 351