37
37
import random
38
38
import numpy as np
39
39
40
+ import pandas as pd
40
41
from pandas import DataFrame , Series
41
42
43
+ try :
44
+ import git # gitpython
45
+ except Exception :
46
+ print ("Error: Please install the `gitpython` package\n " )
47
+ sys .exit (1 )
48
+
42
49
from suite import REPO_PATH
43
50
51
+ VB_DIR = os .path .dirname (os .path .abspath (__file__ ))
44
52
DEFAULT_MIN_DURATION = 0.01
45
53
HEAD_COL = "head[ms]"
46
54
BASE_COL = "base[ms]"
57
65
parser .add_argument ('-t' , '--target-commit' ,
58
66
help = 'The commit to compare against the baseline (default: HEAD).' ,
59
67
type = str )
68
+ parser .add_argument ('--base-pickle' ,
69
+ help = 'name of pickle file with timings data generated by a former `-H -d FILE` run. ' \
70
+ 'filename must be of the form <hash>-*.* or specify --base-commit seperately' ,
71
+ type = str )
72
+ parser .add_argument ('--target-pickle' ,
73
+ help = 'name of pickle file with timings data generated by a former `-H -d FILE` run ' \
74
+ 'filename must be of the form <hash>-*.* or specify --target-commit seperately' ,
75
+ type = str )
60
76
parser .add_argument ('-m' , '--min-duration' ,
61
77
help = 'Minimum duration (in ms) of baseline test for inclusion in report (default: %.3f).' % DEFAULT_MIN_DURATION ,
62
78
type = float ,
104
120
parser .add_argument ('-a' , '--affinity' ,
105
121
metavar = "a" ,
106
122
dest = 'affinity' ,
107
- default = 1 ,
108
- type = int ,
123
+ default = None ,
109
124
help = 'set processor affinity of processm by default bind to cpu/core #1 only'
110
125
'requires the "affinity" python module , will raise Warning otherwise' )
111
126
@@ -206,21 +221,34 @@ def profile_comparative(benchmarks):
206
221
207
222
head_res = get_results_df (db , h_head )
208
223
baseline_res = get_results_df (db , h_baseline )
209
- totals = prep_totals (baseline_res , head_res )
210
-
211
- h_msg = repo .messages .get (h_head , "" )
212
- b_msg = repo .messages .get (h_baseline , "" )
213
224
214
- print_report (totals ,h_head = h_head ,h_msg = h_msg ,
215
- h_baseline = h_baseline ,b_msg = b_msg )
225
+ report_comparative (head_res ,baseline_res )
216
226
217
- if args .outdf :
218
- prprint ("The results DataFrame was written to '%s'\n " % args .outdf )
219
- totals .save (args .outdf )
220
227
finally :
221
228
# print("Disposing of TMP_DIR: %s" % TMP_DIR)
222
229
shutil .rmtree (TMP_DIR )
223
230
231
+ def prep_pickle_for_total (df , agg_name = 'median' ):
232
+ """
233
+ accepts a datafram resulting from invocation with -H -d o.pickle
234
+ If multiple data columns are present (-N was used), the
235
+ `agg_name` attr of the datafram will be used to reduce
236
+ them to a single value per vbench, df.median is used by defa
237
+ ult.
238
+
239
+ Returns a datadrame of the form expected by prep_totals
240
+ """
241
+ def prep (df ):
242
+ agg = getattr (df ,agg_name )
243
+ df = DataFrame (agg (1 ))
244
+ cols = list (df .columns )
245
+ cols [0 ]= 'timing'
246
+ df .columns = cols
247
+ df ['name' ] = list (df .index )
248
+ return df
249
+
250
+ return prep (df )
251
+
224
252
def prep_totals (head_res , baseline_res ):
225
253
"""
226
254
Each argument should be a dataframe with 'timing' and 'name' columns
@@ -241,6 +269,27 @@ def prep_totals(head_res, baseline_res):
241
269
).sort ("ratio" ).set_index ('name' ) # sort in ascending order
242
270
return totals
243
271
272
+ def report_comparative (head_res ,baseline_res ):
273
+ try :
274
+ r = git .Repo (VB_DIR )
275
+ except :
276
+ import pdb
277
+ pdb .set_trace ()
278
+
279
+ totals = prep_totals (head_res ,baseline_res )
280
+
281
+ h_head = args .target_commit
282
+ h_baseline = args .base_commit
283
+ h_msg = r .commit (h_head ).message .strip ()
284
+ b_msg = r .commit (h_baseline ).message .strip ()
285
+
286
+ print_report (totals ,h_head = h_head ,h_msg = h_msg ,
287
+ h_baseline = h_baseline ,b_msg = b_msg )
288
+
289
+ if args .outdf :
290
+ prprint ("The results DataFrame was written to '%s'\n " % args .outdf )
291
+ totals .save (args .outdf )
292
+
244
293
def profile_head_single (benchmark ):
245
294
import gc
246
295
results = []
@@ -398,18 +447,23 @@ def main():
398
447
random .seed (args .seed )
399
448
np .random .seed (args .seed )
400
449
401
- try :
402
- import affinity
403
- affinity .set_process_affinity_mask (0 ,args .affinity )
404
- assert affinity .get_process_affinity_mask (0 ) == args .affinity
405
- print ("CPU affinity set to %d" % args .affinity )
406
- except ImportError :
407
- import warnings
408
- print ("\n \n !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n " +
409
- "The 'affinity' module is not available, results may be unreliable\n " +
410
- "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n \n "
411
- )
412
- time .sleep (2 )
450
+ if args .base_pickle and args .target_pickle :
451
+ baseline_res = prep_pickle_for_total (pd .load (args .base_pickle ))
452
+ target_res = prep_pickle_for_total (pd .load (args .target_pickle ))
453
+
454
+ report_comparative (target_res , baseline_res )
455
+ sys .exit (0 )
456
+
457
+ if args .affinity is not None :
458
+ try :
459
+ import affinity
460
+
461
+ affinity .set_process_affinity_mask (0 ,args .affinity )
462
+ assert affinity .get_process_affinity_mask (0 ) == args .affinity
463
+ print ("CPU affinity set to %d" % args .affinity )
464
+ except ImportError :
465
+ print ("-a/--afinity specified, but the 'affinity' module is not available, aborting.\n " )
466
+ sys .exit (1 )
413
467
414
468
print ("\n " )
415
469
prprint ("LOG_FILE = %s" % args .log_file )
@@ -489,10 +543,40 @@ def inner(repo_path):
489
543
490
544
if __name__ == '__main__' :
491
545
args = parser .parse_args ()
492
- if not args .head and (not args .base_commit and not args .target_commit ):
546
+ if (not args .head
547
+ and not (args .base_commit and args .target_commit )
548
+ and not (args .base_pickle and args .target_pickle )):
493
549
parser .print_help ()
494
- else :
495
- import warnings
496
- warnings .filterwarnings ('ignore' ,category = FutureWarning )
497
- warnings .filterwarnings ('ignore' ,category = DeprecationWarning )
498
- main ()
550
+ sys .exit (1 )
551
+ elif ((args .base_pickle or args .target_pickle ) and not
552
+ (args .base_pickle and args .target_pickle )):
553
+ print ("Must specify Both --base-pickle and --target-pickle." )
554
+ sys .exit (1 )
555
+
556
+ if ((args .base_pickle or args .target_pickle ) and not
557
+ (args .base_commit and args .target_commit )):
558
+ if not args .base_commit :
559
+ print ("base_commit not specified, Assuming base_pickle is named <commit>-foo.*" )
560
+ args .base_commit = args .base_pickle .split ('-' )[0 ]
561
+ if not args .target_commit :
562
+ print ("target_commit not specified, Assuming target_pickle is named <commit>-foo.*" )
563
+ print (args .target_pickle .split ('-' )[0 ])
564
+ args .target_commit = args .target_pickle .split ('-' )[0 ]
565
+
566
+ import warnings
567
+ warnings .filterwarnings ('ignore' ,category = FutureWarning )
568
+ warnings .filterwarnings ('ignore' ,category = DeprecationWarning )
569
+
570
+ if args .base_commit and args .target_commit :
571
+ print ("Verifying specified commits exist in repo..." )
572
+ r = git .Repo (VB_DIR )
573
+ for c in [ args .base_commit , args .target_commit ]:
574
+ try :
575
+ msg = r .commit (c ).message .strip ()
576
+ except git .BadObject :
577
+ print ("The commit '%s' was not found, aborting" % c )
578
+ sys .exit (1 )
579
+ else :
580
+ print ("%s: %s" % (c ,msg ))
581
+
582
+ main ()
0 commit comments