1#!/usr/bin/python3
2
3""" Parse a systrace file with NNAPI traces to calculate timing statistics
4
5This is script to be run from the command line.
6
7Usage:
8  $ cd <location of script>
9  $ ./parse_systrace.py <systrace html file>
10  $ ./parse_systrace.py --help
11
12For the parsing logic, see contract-between-code-and-parser.txt
13
14"""
15
16import argparse
17import sys
18
19from parser.input import get_trace_part, parse_trace_part
20from parser.output import print_stats, reset_trackers
21from parser.tracker import Tracker, AppPhase
22
23
24def produce_stats(trace, print_detail=False, total_times=False, per_execution=False, json=False):
25  """ Take a string with the systrace html file's trace part,
26      possibly containing multiple application runs, feed the trace to
27      Tracker objects and print stats for each run."""
28  tracked_pids, driver_tgids, parsed = parse_trace_part(trace)
29  tracker_map = {}
30  app_phase = AppPhase()
31  for pid in tracked_pids:
32    tgid = tracked_pids[pid]
33    tracker_map[pid] = Tracker(pid, driver_tgids.get(tgid, False), app_phase)
34
35  first = True
36  starting_mark = ''
37  printed_one = False
38  if json:
39    sep = "["
40  else:
41    sep = ""
42  for [task, pid, tgid, time, mark, line, lineno] in parsed:
43    if ("HIDL::IDevice" in mark) or ("[NN_" in mark):
44        assert tracker_map.get(pid), "Cannot find PID %s in tracker_map" % pid
45    if tracker_map.get(pid):
46        if "[NN_LA_PO]" in mark:
47          # Next run
48          if not first:
49            if json and printed_one:
50              sep = ","
51            printed_one = True
52            print_stats(tracker_map, print_detail, total_times, per_execution, json,
53                        starting_mark, sep)
54            reset_trackers(tracker_map)
55            app_phase.reset()
56          starting_mark = mark
57          first = False
58        try:
59          tracker_map[pid].handle_mark(time, mark)
60        except Exception as e:
61          print("failed on line", lineno, line)
62          raise
63  if json and printed_one:
64    sep = ","
65  print_stats(tracker_map, print_detail, total_times, per_execution, json, starting_mark, sep)
66  if json:
67    print("]")
68
69if __name__ == "__main__":
70  parser = argparse.ArgumentParser()
71  parser.add_argument('--print-detail', action='store_true')
72  parser.add_argument('--total-times', action='store_true')
73  parser.add_argument('--per-execution', action='store_true')
74  parser.add_argument('--json', action='store_true')
75  parser.add_argument('filename')
76  args = parser.parse_args()
77  trace = get_trace_part(args.filename)
78  produce_stats(trace, args.print_detail, args.total_times, args.per_execution, args.json)
79