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