blob: c2f4b04e2a0664a04bc8cfbf4c6b07216bf12f59 [file] [log] [blame]
Brendan Jackmane81fdcb2017-01-04 17:10:29 +00001# Copyright 2015-2017 ARM Limited
Javi Merino08f3c342015-12-21 17:20:12 +00002#
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"""
Valentin Schneider211eeb52017-09-18 11:49:11 +010040 max_durations = []
41 min_durations = []
Javi Merino08f3c342015-12-21 17:20:12 +000042
43 for trace_class in self.trace_classes:
44 try:
Valentin Schneider211eeb52017-09-18 11:49:11 +010045 max_durations.append(trace_class.data_frame.index[-1])
46 min_durations.append(trace_class.data_frame.index[0])
Javi Merino08f3c342015-12-21 17:20:12 +000047 except IndexError:
48 pass
49
Valentin Schneider211eeb52017-09-18 11:49:11 +010050 if len(min_durations) == 0 or len(max_durations) == 0:
Javi Merino08f3c342015-12-21 17:20:12 +000051 return 0
52
Valentin Schneider211eeb52017-09-18 11:49:11 +010053 return max(max_durations) - min(min_durations)
Javi Merino08f3c342015-12-21 17:20:12 +000054
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
Chris Redpathb01c8482017-06-17 17:19:55 +010069 def _normalize_time(self, basetime=None):
Javi Merino08f3c342015-12-21 17:20:12 +000070 """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:
Joel Fernandescd7f2e02017-06-29 15:16:40 -0700136 # If cached, don't need to do any other DF operation
137 if trace_class.cached:
138 continue
Joel Fernandes02c452e2017-04-23 01:46:28 -0700139 trace_class.tracer = self
Javi Merino08f3c342015-12-21 17:20:12 +0000140 trace_class.create_dataframe()
141 trace_class.finalize_object()
Joel Fernandes02c452e2017-04-23 01:46:28 -0700142
Michele Di Giorgio8a253f22017-08-07 11:48:35 +0100143 def generate_data_dict(self, data_str):
Joel Fernandes02c452e2017-04-23 01:46:28 -0700144 return None