3737import random
3838import numpy as np
3939
40+ import pandas as pd
4041from pandas import DataFrame , Series
4142
43+ try :
44+ import git # gitpython
45+ except Exception :
46+ print ("Error: Please install the `gitpython` package\n " )
47+ sys .exit (1 )
48+
4249from suite import REPO_PATH
4350
51+ VB_DIR = os .path .dirname (os .path .abspath (__file__ ))
4452DEFAULT_MIN_DURATION = 0.01
4553HEAD_COL = "head[ms]"
4654BASE_COL = "base[ms]"
5765parser .add_argument ('-t' , '--target-commit' ,
5866 help = 'The commit to compare against the baseline (default: HEAD).' ,
5967 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 )
6076parser .add_argument ('-m' , '--min-duration' ,
6177 help = 'Minimum duration (in ms) of baseline test for inclusion in report (default: %.3f).' % DEFAULT_MIN_DURATION ,
6278 type = float ,
104120parser .add_argument ('-a' , '--affinity' ,
105121 metavar = "a" ,
106122 dest = 'affinity' ,
107- default = 1 ,
108- type = int ,
123+ default = None ,
109124 help = 'set processor affinity of processm by default bind to cpu/core #1 only'
110125 'requires the "affinity" python module , will raise Warning otherwise' )
111126
@@ -206,21 +221,34 @@ def profile_comparative(benchmarks):
206221
207222 head_res = get_results_df (db , h_head )
208223 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 , "" )
213224
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 )
216226
217- if args .outdf :
218- prprint ("The results DataFrame was written to '%s'\n " % args .outdf )
219- totals .save (args .outdf )
220227 finally :
221228 # print("Disposing of TMP_DIR: %s" % TMP_DIR)
222229 shutil .rmtree (TMP_DIR )
223230
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+
224252def prep_totals (head_res , baseline_res ):
225253 """
226254 Each argument should be a dataframe with 'timing' and 'name' columns
@@ -241,6 +269,27 @@ def prep_totals(head_res, baseline_res):
241269 ).sort ("ratio" ).set_index ('name' ) # sort in ascending order
242270 return totals
243271
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+
244293def profile_head_single (benchmark ):
245294 import gc
246295 results = []
@@ -398,18 +447,23 @@ def main():
398447 random .seed (args .seed )
399448 np .random .seed (args .seed )
400449
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 )
413467
414468 print ("\n " )
415469 prprint ("LOG_FILE = %s" % args .log_file )
@@ -489,10 +543,40 @@ def inner(repo_path):
489543
490544if __name__ == '__main__' :
491545 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 )):
493549 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