parse_systrace.py 2.5 KB

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