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