Brendan Jackman | e81fdcb | 2017-01-04 17:10:29 +0000 | [diff] [blame] | 1 | # Copyright 2015-2017 ARM Limited |
Javi Merino | 08f3c34 | 2015-12-21 17:20:12 +0000 | [diff] [blame] | 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 | |
| 16 | import re |
| 17 | |
| 18 | class 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 Schneider | 211eeb5 | 2017-09-18 11:49:11 +0100 | [diff] [blame] | 40 | max_durations = [] |
| 41 | min_durations = [] |
Javi Merino | 08f3c34 | 2015-12-21 17:20:12 +0000 | [diff] [blame] | 42 | |
| 43 | for trace_class in self.trace_classes: |
| 44 | try: |
Valentin Schneider | 211eeb5 | 2017-09-18 11:49:11 +0100 | [diff] [blame] | 45 | max_durations.append(trace_class.data_frame.index[-1]) |
| 46 | min_durations.append(trace_class.data_frame.index[0]) |
Javi Merino | 08f3c34 | 2015-12-21 17:20:12 +0000 | [diff] [blame] | 47 | except IndexError: |
| 48 | pass |
| 49 | |
Valentin Schneider | 211eeb5 | 2017-09-18 11:49:11 +0100 | [diff] [blame] | 50 | if len(min_durations) == 0 or len(max_durations) == 0: |
Javi Merino | 08f3c34 | 2015-12-21 17:20:12 +0000 | [diff] [blame] | 51 | return 0 |
| 52 | |
Valentin Schneider | 211eeb5 | 2017-09-18 11:49:11 +0100 | [diff] [blame] | 53 | return max(max_durations) - min(min_durations) |
Javi Merino | 08f3c34 | 2015-12-21 17:20:12 +0000 | [diff] [blame] | 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 | |
Chris Redpath | b01c848 | 2017-06-17 17:19:55 +0100 | [diff] [blame] | 69 | def _normalize_time(self, basetime=None): |
Javi Merino | 08f3c34 | 2015-12-21 17:20:12 +0000 | [diff] [blame] | 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: |
Joel Fernandes | cd7f2e0 | 2017-06-29 15:16:40 -0700 | [diff] [blame] | 136 | # If cached, don't need to do any other DF operation |
| 137 | if trace_class.cached: |
| 138 | continue |
Joel Fernandes | 02c452e | 2017-04-23 01:46:28 -0700 | [diff] [blame] | 139 | trace_class.tracer = self |
Javi Merino | 08f3c34 | 2015-12-21 17:20:12 +0000 | [diff] [blame] | 140 | trace_class.create_dataframe() |
| 141 | trace_class.finalize_object() |
Joel Fernandes | 02c452e | 2017-04-23 01:46:28 -0700 | [diff] [blame] | 142 | |
Michele Di Giorgio | 8a253f2 | 2017-08-07 11:48:35 +0100 | [diff] [blame] | 143 | def generate_data_dict(self, data_str): |
Joel Fernandes | 02c452e | 2017-04-23 01:46:28 -0700 | [diff] [blame] | 144 | return None |