bare_trace.py revision 4ec4aee55dbd4045cfb6a2fe099615a569ce7ff7
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
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            trace_class.create_dataframe()
138            trace_class.finalize_object()
139