From b2febc01ff399dc8633c6d2f0b06dcfd6ddad316 Mon Sep 17 00:00:00 2001 From: Joel Fernandes Date: Sat, 24 Jun 2017 18:45:10 -0700 Subject: [PATCH 1/3] utils/trace: make passing events as optional By default, all events should be parsed if none are specified. This patch makes it possible. Signed-off-by: Joel Fernandes --- libs/utils/trace.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/libs/utils/trace.py b/libs/utils/trace.py index 80b6133d7..1a7e82353 100644 --- a/libs/utils/trace.py +++ b/libs/utils/trace.py @@ -69,7 +69,7 @@ class Trace(object): :type plots_prefix: str """ - def __init__(self, platform, data_dir, events, + def __init__(self, platform, data_dir, events=None, window=(0, None), normalize_time=True, trace_format='FTrace', @@ -125,7 +125,7 @@ class Trace(object): self.plots_dir = self.data_dir self.plots_prefix = plots_prefix - self.__registerTraceEvents(events) + self.__registerTraceEvents(events) if events else None self.__parseTrace(data_dir, window, normalize_time, trace_format) self.__computeTimeSpan() @@ -219,7 +219,7 @@ class Trace(object): :type trace_format: str """ self._log.debug('Loading [sched] events from trace in [%s]...', path) - self._log.debug('Parsing events: %s', self.events) + self._log.debug('Parsing events: %s', self.events if self.events else 'ALL') if trace_format.upper() == 'SYSTRACE' or path.endswith('html'): self._log.debug('Parsing SysTrace format...') trace_class = trappy.SysTrace @@ -231,7 +231,8 @@ class Trace(object): else: raise ValueError("Unknown trace format {}".format(trace_format)) - self.ftrace = trace_class(path, scope="custom", events=self.events, + scope = 'custom' if self.events else 'all' + self.ftrace = trace_class(path, scope=scope, events=self.events, window=window, normalize_time=normalize_time) # Load Functions profiling data -- GitLab From 7fe5f23829f9bde7584de2a9b2b9fe3c73f2c30d Mon Sep 17 00:00:00 2001 From: Joel Fernandes Date: Thu, 15 Jun 2017 18:40:46 -0700 Subject: [PATCH 2/3] utils/analysis: add base class for command-line analysis tools This base class will be subclassed by specific analysis tools and will handle all generic analysis tasks (creation of trace object, presenting output, log setup, parsing common command line args etc). Signed-off-by: Joel Fernandes --- libs/utils/analysis_tool.py | 102 ++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 libs/utils/analysis_tool.py diff --git a/libs/utils/analysis_tool.py b/libs/utils/analysis_tool.py new file mode 100644 index 000000000..846c6a6c4 --- /dev/null +++ b/libs/utils/analysis_tool.py @@ -0,0 +1,102 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# Copyright (C) 2017, ARM Limited, Google and contributors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +import argparse +import logging +import os +import select +from trace import Trace +from conf import LisaLogging +from devlib.utils.misc import memoized + +class AnalysisTool(object): + """ + A base class for LISA analysis command-line tools. + + This class is intended to be subclassed in order to create a custom + analysis tool. + + :param options_parser: A parser object passed by the specific tool + to parse additional options if any (optional). + :type options_parser: ArgumentParser + """ + + def __init__(self, options_parser=None): + self.options_parser = options_parser + + def _setup_logging(self): + """ + Setup logging for the analysis tool. + + Analysis tools shouldn't output to standard output as their + output can be used by other tools. Configure the logger to + output only error messages. + """ + self._log = logging.getLogger('AnalysisTool') + level = logging.INFO if self.args.log_stdout else logging.ERROR + LisaLogging.setup(level=level) + + def _parse_args(self): + """ + Parse command line arguments given to the tool, also use the parser + object if one is passed by the more specific class so that the + tool specific options are also parsed. + """ + parser = self.options_parser + if not parser: + parser = argparse.ArgumentParser( + description='LISA Analysis tool configuration') + + # General options that all tools accept + parser.add_argument('--trace', type=str, + help='Path of the trace file or directory to be used', + required=True) + + parser.add_argument('--log-stdout', action='store_true', + help='Output logging to stdout', + required=False) + + self.args = parser.parse_args() + + def run_analysis(self): + """ + Run an analysis and store results + + The specific analysis tool should override this and perform + analysis and provide results in self.output. + """ + raise NotImplementedError('Analysis tool needs to define run_analysis') + + def run_main(self): + """ + The main function that sets up, runs the analysis and provides + output to the user. + + The specific analysis tool should call this function to start the analysis + which will perform analysis and report the result. The tool should also + override run_analysis to provide custom analysis and optionally override + run_output to provide custom output. + """ + + self._parse_args() + self._setup_logging() + + # Create trace object + self._log.info('Creating trace object...') + self.trace = Trace(None, self.args.trace) + + self.run_analysis() -- GitLab From e41f26537e67a4f63dd3f4fe93298eeee56ccce8 Mon Sep 17 00:00:00 2001 From: Joel Fernandes Date: Fri, 16 Jun 2017 11:55:30 -0700 Subject: [PATCH 3/3] analysis/gfx: add a tool to report frame drops This is just an example to build on. Change-Id: Ia8d44df71a2c943fde6766291ccca2f779ad1c26 Signed-off-by: Joel Fernandes --- tools/analysis/android_gfx.py | 36 +++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100755 tools/analysis/android_gfx.py diff --git a/tools/analysis/android_gfx.py b/tools/analysis/android_gfx.py new file mode 100755 index 000000000..71fa6fa88 --- /dev/null +++ b/tools/analysis/android_gfx.py @@ -0,0 +1,36 @@ +#!/usr/bin/env python +# Copyright 2017 ARM Limited, Google and contributors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +import os +import pandas as pd +from time import sleep +from devlib.exception import TargetError +from analysis_tool import AnalysisTool + +class AndroidGfx(AnalysisTool): + + def get_frame_drops(self, df): + if not 'func' in df.columns: + return 0 + return len(df[(df.func == 'FrameMissed') & (df.data == '1')]) + + def run_analysis(self): + df = self.trace.data_frame.trace_event('tracing_mark_write') + print {'frame_drops': self.get_frame_drops(df)} + +# Run the analysis and provide results +if __name__ == "__main__": + AndroidGfx().run_main() -- GitLab