Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(344)

Side by Side Diff: bench/bench_graph_svg.py

Issue 12381088: Codes for writing bench data to appengine datastore. (Closed) Base URL: http://skia.googlecode.com/svn/trunk/
Patch Set: Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 ''' 1 '''
2 Created on May 16, 2011 2 Created on May 16, 2011
3 3
4 @author: bungeman 4 @author: bungeman
5 ''' 5 '''
6 import sys 6 import sys
7 import getopt 7 import getopt
8 import re 8 import re
9 import os 9 import os
10 import bench_util 10 import bench_util
11 import json 11 import json
12 import httplib
epoger 2013/03/05 18:38:52 Please put imports in alpha order
benchen 2013/03/05 20:52:53 Done. Didn't do so since it conflicted with the pr
13 import urllib
14 import urllib2
12 import xml.sax.saxutils 15 import xml.sax.saxutils
13 16
14 # We throw out any measurement outside this range, and log a warning. 17 # We throw out any measurement outside this range, and log a warning.
15 MIN_REASONABLE_TIME = 0 18 MIN_REASONABLE_TIME = 0
16 MAX_REASONABLE_TIME = 99999 19 MAX_REASONABLE_TIME = 99999
17 20
18 # Constants for prefixes in output title used in buildbot. 21 # Constants for prefixes in output title used in buildbot.
19 TITLE_PREAMBLE = 'Bench_Performance_for_Skia_' 22 TITLE_PREAMBLE = 'Bench_Performance_for_Skia_'
20 TITLE_PREAMBLE_LENGTH = len(TITLE_PREAMBLE) 23 TITLE_PREAMBLE_LENGTH = len(TITLE_PREAMBLE)
21 24
25 # Number of data points to send to appengine at once.
26 DATA_POINTS_TO_SEND = 100
epoger 2013/03/05 18:38:52 Maybe DATA_POINT_BATCHSIZE instead, because you're
benchen 2013/03/05 20:52:53 Yeah that's better. Done. On 2013/03/05 18:38:52,
27
22 def usage(): 28 def usage():
23 """Prints simple usage information.""" 29 """Prints simple usage information."""
24 30
31 print '-a <url> the url to use for adding bench values to app engine app.'
32 print ' Example: "https://skiadash.appspot.com/add_point".'
33 print ' If not set, will skip this step.'
25 print '-b <bench> the bench to show.' 34 print '-b <bench> the bench to show.'
26 print '-c <config> the config to show (GPU, 8888, 565, etc).' 35 print '-c <config> the config to show (GPU, 8888, 565, etc).'
27 print '-d <dir> a directory containing bench_r<revision>_<scalar> files.' 36 print '-d <dir> a directory containing bench_r<revision>_<scalar> files.'
28 print '-e <file> file containing expected bench values/ranges.' 37 print '-e <file> file containing expected bench values/ranges.'
29 print ' Will raise exception if actual bench values are out of range.' 38 print ' Will raise exception if actual bench values are out of range.'
30 print ' See bench_expectations.txt for data format and examples.' 39 print ' See bench_expectations.txt for data format and examples.'
31 print '-f <revision>[:<revision>] the revisions to use for fitting.' 40 print '-f <revision>[:<revision>] the revisions to use for fitting.'
32 print ' Negative <revision> is taken as offset from most recent revision.' 41 print ' Negative <revision> is taken as offset from most recent revision.'
33 print '-i <time> the time to ignore (w, c, g, etc).' 42 print '-i <time> the time to ignore (w, c, g, etc).'
34 print ' The flag is ignored when -t is set; otherwise we plot all the' 43 print ' The flag is ignored when -t is set; otherwise we plot all the'
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
184 On Windows, we need to generate the absolute path within Python to avoid 193 On Windows, we need to generate the absolute path within Python to avoid
185 the operating system's 260-character pathname limit, including chdirs.""" 194 the operating system's 260-character pathname limit, including chdirs."""
186 abs_path = get_abs_path(output_path) 195 abs_path = get_abs_path(output_path)
187 sys.stdout = open(abs_path, 'w') 196 sys.stdout = open(abs_path, 'w')
188 197
189 def create_lines(revision_data_points, settings 198 def create_lines(revision_data_points, settings
190 , bench_of_interest, config_of_interest, time_of_interest 199 , bench_of_interest, config_of_interest, time_of_interest
191 , time_to_ignore): 200 , time_to_ignore):
192 """Convert revision data into a dictionary of line data. 201 """Convert revision data into a dictionary of line data.
193 202
194 ({int:[BenchDataPoints]}, {str:str}, str?, str?, str?) 203 ({int:[BenchDataPoints]}, {str:str}, str?, str?, str?)
epoger 2013/03/06 17:17:22 What this means: INPUT parameters of the function
benchen 2013/03/06 18:52:37 I've added your explanations assuming that bungyma
195 -> {Label:[(x,y)] | [n].x <= [n+1].x}""" 204 -> {Label:[(x,y)] | [n].x <= [n+1].x}"""
196 revisions = revision_data_points.keys() 205 revisions = revision_data_points.keys()
197 revisions.sort() 206 revisions.sort()
198 lines = {} # {Label:[(x,y)] | x[n] <= x[n+1]} 207 lines = {} # {Label:[(x,y)] | x[n] <= x[n+1]}
199 for revision in revisions: 208 for revision in revisions:
200 for point in revision_data_points[revision]: 209 for point in revision_data_points[revision]:
201 if (bench_of_interest is not None and 210 if (bench_of_interest is not None and
202 not bench_of_interest == point.bench): 211 not bench_of_interest == point.bench):
203 continue 212 continue
204 213
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
279 max_up_slope = max(max_up_slope, min_slope) 288 max_up_slope = max(max_up_slope, min_slope)
280 min_down_slope = min(min_down_slope, min_slope) 289 min_down_slope = min(min_down_slope, min_slope)
281 290
282 return (max_up_slope, min_down_slope) 291 return (max_up_slope, min_down_slope)
283 292
284 def main(): 293 def main():
285 """Parses command line and writes output.""" 294 """Parses command line and writes output."""
286 295
287 try: 296 try:
288 opts, _ = getopt.getopt(sys.argv[1:] 297 opts, _ = getopt.getopt(sys.argv[1:]
289 , "b:c:d:e:f:i:l:m:o:r:s:t:x:y:" 298 , "a:b:c:d:e:f:i:l:m:o:r:s:t:x:y:"
290 , "default-setting=") 299 , "default-setting=")
291 except getopt.GetoptError, err: 300 except getopt.GetoptError, err:
292 print str(err) 301 print str(err)
293 usage() 302 usage()
294 sys.exit(2) 303 sys.exit(2)
295 304
296 directory = None 305 directory = None
297 config_of_interest = None 306 config_of_interest = None
298 bench_of_interest = None 307 bench_of_interest = None
299 time_of_interest = None 308 time_of_interest = None
300 time_to_ignore = None 309 time_to_ignore = None
301 bench_expectations = {} 310 bench_expectations = {}
311 appengine_url = None # used for adding data to appengine datastore
302 rep = None # bench representation algorithm 312 rep = None # bench representation algorithm
303 revision_range = '0:' 313 revision_range = '0:'
304 regression_range = '0:' 314 regression_range = '0:'
305 latest_revision = None 315 latest_revision = None
306 requested_height = None 316 requested_height = None
307 requested_width = None 317 requested_width = None
308 title = 'Bench graph' 318 title = 'Bench graph'
309 settings = {} 319 settings = {}
310 default_settings = {} 320 default_settings = {}
311 321
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
362 bench_platform_key not in expectations): 372 bench_platform_key not in expectations):
363 # Skip benches without value for latest revision. 373 # Skip benches without value for latest revision.
364 continue 374 continue
365 this_min, this_max = expectations[bench_platform_key] 375 this_min, this_max = expectations[bench_platform_key]
366 if this_bench_value < this_min or this_bench_value > this_max: 376 if this_bench_value < this_min or this_bench_value > this_max:
367 exceptions.append('Bench %s value %s out of range [%s, %s].' % 377 exceptions.append('Bench %s value %s out of range [%s, %s].' %
368 (bench_platform_key, this_bench_value, this_min, this_max)) 378 (bench_platform_key, this_bench_value, this_min, this_max))
369 if exceptions: 379 if exceptions:
370 raise Exception('Bench values out of range:\n' + 380 raise Exception('Bench values out of range:\n' +
371 '\n'.join(exceptions)) 381 '\n'.join(exceptions))
382 def write_to_appengine(lines, url, newest_revision, platform_and_alg):
epoger 2013/03/05 18:38:52 please add newline before this function
benchen 2013/03/05 20:52:53 Done.
383 """Writes latest bench values to appengine datastore."""
epoger 2013/03/05 18:38:52 please document the parameters
benchen 2013/03/05 20:52:53 Done.
384 data = []
385 for line in lines:
386 bot = platform_and_alg[ : platform_and_alg.rfind('-')]
epoger 2013/03/05 18:38:52 Why are we assembling platform_and_alg in line 470
benchen 2013/03/05 20:52:53 I did not separate platform and alg because there
387 line_str = str(line)[ : str(line).find('_{')]
epoger 2013/03/05 18:38:52 So, is this just trying to extract the portion of
benchen 2013/03/05 20:52:53 create_lines() will make sure there is _{ in the l
epoger 2013/03/06 17:17:22 I don't see any mention of "_{" in create_lines.
benchen 2013/03/06 18:52:37 According to Class Label's __str__ method, there's
388 if line_str.find('.skp') < 0 or not line_str.endswith('_'):
389 # filter out non-picture and non-walltime benches
390 continue
391 bench, config = line_str.split('.skp', 1)
392 config = config.strip('_') # remove leading and trailing '_'
393 rev, val = lines[line][-1]
epoger 2013/03/05 18:38:52 Is line a string or an index?
benchen 2013/03/05 20:52:53 It's an object with Label class. Please see create
394 if rev != newest_revision:
395 continue
396 data.append({'master': 'Skia', 'bot': bot,
397 'test': config + '/' + bench,
398 'revision': rev, 'value': val, 'error': 0})
399 while data:
400 curr_data = data[ : DATA_POINTS_TO_SEND]
epoger 2013/03/05 18:38:52 This seems like a really inefficient way to work o
benchen 2013/03/05 20:52:53 Nice suggestion. Done. On 2013/03/05 18:38:52, epo
401 data = data[DATA_POINTS_TO_SEND : ]
402 req = urllib2.Request(
403 appengine_url, urllib.urlencode({'data': json.dumps(curr_data)}))
404 try:
405 urllib2.urlopen(req)
406 except urllib2.HTTPError, e:
407 sys.stderr.write("HTTPError: %d for JSON %s\n" % (e.code, data))
epoger 2013/03/05 18:38:52 Why do you display the details of the exception di
benchen 2013/03/05 20:52:53 I was just copying from https://codereview.chromiu
408 except urllib2.URLError, e:
409 sys.stderr.write("URLError: %s for JSON %s\n" % (
410 str(e.reason), data))
411 except httplib.HTTPException, e:
412 sys.stderr.write("HTTPException for JSON %s\n" % lines)
372 413
373 try: 414 try:
374 for option, value in opts: 415 for option, value in opts:
375 if option == "-b": 416 if option == "-a":
417 appengine_url = value
418 elif option == "-b":
376 bench_of_interest = value 419 bench_of_interest = value
377 elif option == "-c": 420 elif option == "-c":
378 config_of_interest = value 421 config_of_interest = value
379 elif option == "-d": 422 elif option == "-d":
380 directory = value 423 directory = value
381 elif option == "-e": 424 elif option == "-e":
382 read_expectations(bench_expectations, value) 425 read_expectations(bench_expectations, value)
383 elif option == "-f": 426 elif option == "-f":
384 regression_range = value 427 regression_range = value
385 elif option == "-i": 428 elif option == "-i":
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
454 , time_of_interest 497 , time_of_interest
455 , time_to_ignore) 498 , time_to_ignore)
456 499
457 regressions = create_regressions(lines 500 regressions = create_regressions(lines
458 , oldest_regression 501 , oldest_regression
459 , newest_regression) 502 , newest_regression)
460 503
461 output_xhtml(lines, oldest_revision, newest_revision, ignored_revision_data_ points, 504 output_xhtml(lines, oldest_revision, newest_revision, ignored_revision_data_ points,
462 regressions, requested_width, requested_height, title) 505 regressions, requested_width, requested_height, title)
463 506
507 if appengine_url:
508 write_to_appengine(lines, appengine_url, newest_revision,
509 platform_and_alg)
510
464 check_expectations(lines, bench_expectations, newest_revision, 511 check_expectations(lines, bench_expectations, newest_revision,
465 platform_and_alg) 512 platform_and_alg)
466 513
467 def qa(out): 514 def qa(out):
468 """Stringify input and quote as an xml attribute.""" 515 """Stringify input and quote as an xml attribute."""
469 return xml.sax.saxutils.quoteattr(str(out)) 516 return xml.sax.saxutils.quoteattr(str(out))
470 def qe(out): 517 def qe(out):
471 """Stringify input and escape as xml data.""" 518 """Stringify input and escape as xml data."""
472 return xml.sax.saxutils.escape(str(out)) 519 return xml.sax.saxutils.escape(str(out))
473 520
(...skipping 481 matching lines...) Expand 10 before | Expand all | Expand 10 after
955 print '<a id="rev_link" xlink:href="" target="_top">' 1002 print '<a id="rev_link" xlink:href="" target="_top">'
956 print '<text id="revision" x="0" y=%s style="' % qa(font_size*2) 1003 print '<text id="revision" x="0" y=%s style="' % qa(font_size*2)
957 print 'font-size: %s; ' % qe(font_size) 1004 print 'font-size: %s; ' % qe(font_size)
958 print 'stroke: #0000dd; text-decoration: underline; ' 1005 print 'stroke: #0000dd; text-decoration: underline; '
959 print '"> </text></a>' 1006 print '"> </text></a>'
960 1007
961 print '</svg>' 1008 print '</svg>'
962 1009
963 if __name__ == "__main__": 1010 if __name__ == "__main__":
964 main() 1011 main()
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698