1# Copyright 2015-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 16import re 17 18class BareTrace(object): 19 """A wrapper class that holds dataframes for all the events in a trace. 20 21 BareTrace doesn't parse any file so it's a class that should 22 either be (a) subclassed to parse a particular trace (like FTrace) 23 or (b) be instantiated and the events added with add_parsed_event() 24 25 :param name: is a string describing the trace. 26 :type name: str 27 28 """ 29 30 def __init__(self, name=""): 31 self.name = name 32 self.normalized_time = False 33 self.class_definitions = {} 34 self.trace_classes = [] 35 self.basetime = 0 36 37 def get_duration(self): 38 """Returns the largest time value of all classes, 39 returns 0 if the data frames of all classes are empty""" 40 durations = [] 41 42 for trace_class in self.trace_classes: 43 try: 44 durations.append(trace_class.data_frame.index[-1]) 45 except IndexError: 46 pass 47 48 if len(durations) == 0: 49 return 0 50 51 if self.normalized_time: 52 return max(durations) 53 else: 54 return max(durations) - self.basetime 55 56 def get_filters(self, key=""): 57 """Returns an array with the available filters. 58 59 :param key: If specified, returns a subset of the available filters 60 that contain 'key' in their name (e.g., :code:`key="sched"` returns 61 only the :code:`"sched"` related filters).""" 62 filters = [] 63 64 for cls in self.class_definitions: 65 if re.search(key, cls): 66 filters.append(cls) 67 68 return filters 69 70 def _normalize_time(self, basetime=None): 71 """Normalize the time of all the trace classes 72 73 :param basetime: The offset which needs to be subtracted from 74 the time index 75 :type basetime: float 76 """ 77 78 if basetime is not None: 79 self.basetime = basetime 80 81 for trace_class in self.trace_classes: 82 trace_class.normalize_time(self.basetime) 83 84 self.normalized_time = True 85 86 def add_parsed_event(self, name, dfr, pivot=None): 87 """Add a dataframe to the events in this trace 88 89 This function lets you add other events that have been parsed 90 by other tools to the collection of events in this instance. For 91 example, assuming you have some events in a csv, you could add 92 them to a trace instance like this: 93 94 >>> trace = trappy.BareTrace() 95 >>> counters_dfr = pd.DataFrame.from_csv("counters.csv") 96 >>> trace.add_parsed_event("pmu_counters", counters_dfr) 97 98 Now you can access :code:`trace.pmu_counters` as you would with any 99 other trace event and other trappy classes can interact with 100 them. 101 102 :param name: The attribute name in this trace instance. As in the example above, if :code:`name` is "pmu_counters", the parsed event will be accessible using :code:`trace.pmu_counters`. 103 :type name: str 104 105 :param dfr: :mod:`pandas.DataFrame` containing the events. Its index should be time in seconds. Its columns are the events. 106 :type dfr: :mod:`pandas.DataFrame` 107 108 :param pivot: The data column about which the data can be grouped 109 :type pivot: str 110 111 """ 112 from trappy.base import Base 113 from trappy.dynamic import DynamicTypeFactory, default_init 114 115 if hasattr(self, name): 116 raise ValueError("event {} already present".format(name)) 117 118 kwords = { 119 "__init__": default_init, 120 "unique_word": name + ":", 121 "name": name, 122 } 123 124 trace_class = DynamicTypeFactory(name, (Base,), kwords) 125 self.class_definitions[name] = trace_class 126 127 event = trace_class() 128 self.trace_classes.append(event) 129 event.data_frame = dfr 130 if pivot: 131 event.pivot = pivot 132 133 setattr(self, name, event) 134 135 def finalize_objects(self): 136 for trace_class in self.trace_classes: 137 # If cached, don't need to do any other DF operation 138 if trace_class.cached: 139 continue 140 trace_class.tracer = self 141 trace_class.create_dataframe() 142 trace_class.finalize_object() 143 144 def generate_data_dict(self): 145 return None 146