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