1#!/usr/bin/env python
2
3# Copyright 2016 Google Inc.
4#
5# Use of this source code is governed by a BSD-style license that can be
6# found in the LICENSE file.
7
8from __future__ import print_function
9from _benchresult import BenchResult
10from argparse import ArgumentParser
11from collections import defaultdict
12import json
13import sys
14
15__argparse = ArgumentParser(description="""
16
17Formats skpbench.py outputs for Skia Perf.
18
19""")
20
21__argparse.add_argument('sources',
22  nargs='+', help="source files that contain skpbench results")
23__argparse.add_argument('--properties',
24  nargs='*', help="space-separated key/value pairs identifying the run")
25__argparse.add_argument('--key',
26  nargs='*', help="space-separated key/value pairs identifying the builder")
27__argparse.add_argument('-o', '--outfile',
28  default='-', help="output file ('-' for stdout)")
29
30FLAGS = __argparse.parse_args()
31
32
33class JSONDict(dict):
34  """Simple class for building a JSON dictionary
35
36  Returns another JSONDict upon accessing an undefined item. Does not allow an
37  item to change once it has been inserted.
38
39  """
40  def __init__(self, key_value_pairs=None):
41    dict.__init__(self)
42    if not key_value_pairs:
43      return
44    if len(key_value_pairs) % 2:
45      raise Exception("uneven number of key/value arguments.")
46    for k,v in zip(key_value_pairs[::2], key_value_pairs[1::2]):
47      self[k] = v
48
49  def __getitem__(self, key):
50    if not key in self:
51      dict.__setitem__(self, key, JSONDict())
52    return dict.__getitem__(self, key)
53
54  def __setitem__(self, key, val):
55    if key in self:
56      raise Exception("%s: tried to set already-defined JSONDict item\n"
57                      "  old value: '%s'\n"
58                      "  new value: '%s'" % (key, self[key], val))
59    dict.__setitem__(self, key, val)
60
61  def emit(self, outfile):
62    json.dump(self, outfile, indent=4, separators=(',', ' : '), sort_keys=True)
63    print('', file=outfile)
64
65def main():
66  data = JSONDict(
67    FLAGS.properties + \
68    ['key', JSONDict(FLAGS.key + \
69                     ['bench_type', 'playback', \
70                      'source_type', 'skp'])])
71
72  for src in FLAGS.sources:
73    with open(src, mode='r') as infile:
74      for line in infile:
75        match = BenchResult.match(line)
76        if not match:
77          continue
78        if match.sample_ms != 50:
79          raise Exception("%s: unexpected sample_ms != 50" % match.sample_ms)
80        for result in ('accum', 'median', 'min', 'max'):
81          data['results'][match.bench][match.config] \
82              ['%s_%s_%s' % (result, match.clock, match.metric)] = \
83              getattr(match, result)
84
85  if FLAGS.outfile != '-':
86    with open(FLAGS.outfile, 'w+') as outfile:
87      data.emit(outfile)
88  else:
89    data.emit(sys.stdout)
90
91if __name__ == '__main__':
92  main()
93