@@ -476,6 +476,7 @@ def get_extra_polyglot_args(self):
476
476
class PythonBaseBenchmarkSuite (VmBenchmarkSuite , AveragingBenchmarkMixin ):
477
477
def __init__ (self , name , benchmarks ):
478
478
super (PythonBaseBenchmarkSuite , self ).__init__ ()
479
+ self ._checkup = 'GRAALPYTHON_BENCHMARKS_CHECKUP' in os .environ
479
480
self ._name = name
480
481
self ._benchmarks = benchmarks
481
482
self ._graph_dump_time = None
@@ -680,9 +681,15 @@ def _replace_host_vm(key):
680
681
_replace_host_vm ('graalvm-ee' )
681
682
self .post_run_graph (benchmarks [0 ], dims ['host-vm-config' ], dims ['guest-vm-config' ])
682
683
684
+ if self ._checkup :
685
+ self .checkup (out )
686
+
683
687
return ret_code , out , dims
684
688
685
689
def run (self , benchmarks , bm_suite_args ):
690
+ if '--checkup' in bm_suite_args :
691
+ self ._checkup = True
692
+ bm_suite_args .remove ('--checkup' )
686
693
results = super (PythonBaseBenchmarkSuite , self ).run (benchmarks , bm_suite_args )
687
694
self .addAverageAcrossLatestResults (results )
688
695
return results
@@ -708,6 +715,10 @@ def postprocess_run_args(self, run_args):
708
715
if arg .startswith ("-i" ):
709
716
if len (run_args ) >= i and run_args [i + 1 ] == "-1" :
710
717
pass
718
+ elif self ._checkup and len (run_args ) >= i :
719
+ iterations = int (run_args [i + 1 ]) * 2
720
+ remaining = ["-i" , str (iterations )] + run_args [i + 2 :]
721
+ break
711
722
else :
712
723
remaining = run_args [i :]
713
724
break
@@ -717,13 +728,78 @@ def postprocess_run_args(self, run_args):
717
728
718
729
if not (remaining and "-i" in remaining ):
719
730
iterations = DEFAULT_ITERATIONS + self .getExtraIterationCount (DEFAULT_ITERATIONS )
731
+ if self ._checkup :
732
+ iterations *= 2
720
733
remaining = ["-i" , str (iterations )] + (remaining if remaining else [])
721
734
735
+ if self ._checkup :
736
+ vm_options += ['--engine.TraceCompilation' , '-XX:+PrintGC' ]
737
+
722
738
return vm_options , remaining
723
739
724
740
def createCommandLineArgs (self , benchmarks , bmSuiteArgs ):
725
741
return self .createVmCommandLineArgs (benchmarks , bmSuiteArgs )
726
742
743
+ def checkup (self , out ):
744
+ lines = out .split ('\n ' )
745
+ benchmark_name = None
746
+ current_iteration = - 1
747
+ iterations_count = - 1
748
+ iteration_times = []
749
+ gc_times = []
750
+ late_compilation = False
751
+ for i in range (len (lines )):
752
+ line = lines [i ]
753
+
754
+ # this marks the beginning of an output of a benchmark
755
+ benchmark_info = re .search ("### (.*), \\ d+ warmup iterations, (\\ d+) bench iterations" , line )
756
+ if benchmark_name is None and benchmark_info :
757
+ benchmark_name = benchmark_info .group (1 )
758
+ iterations_count = int (benchmark_info .group (2 ))
759
+ mx .log (f"Checking benchmark { benchmark_name } with { iterations_count } iterations" )
760
+ continue
761
+
762
+ if benchmark_name is None :
763
+ continue
764
+
765
+ # this marks the end of the processing of a single benchmark
766
+ warmup_match = re .search ("### WARMUP detected at iteration: (\\ d+)" , line )
767
+ if warmup_match :
768
+ warmup = int (warmup_match .group (1 ))
769
+ for i in range (warmup , len (iteration_times )):
770
+ if gc_times [i ] > iteration_times [i ] / 10 :
771
+ mx .warn (
772
+ f"Benchmark checkup: { benchmark_name } : excessive GC pause of { gc_times [i ]} (on { i } iteration)" )
773
+ if warmup > iterations_count / 2 :
774
+ mx .warn (f"Benchmark checkup: { benchmark_name } : warmup detected too late (on { warmup } iteration)" )
775
+ if late_compilation :
776
+ mx .warn (
777
+ f"Benchmark checkup: { benchmark_name } : compilation detected too late (on { late_compilation } iteration)" )
778
+ iteration_times = []
779
+ gc_times = []
780
+ current_iteration = - 1
781
+ benchmark_name = None
782
+ late_compilation = False
783
+ continue
784
+
785
+ # following is done only when we are inside benchmark output:
786
+ iteration_info = re .search ("### iteration=(\\ d+), name=.*, duration=([0-9.]*)" , line )
787
+ if iteration_info :
788
+ current_iteration += 1
789
+ iteration_times += [float (iteration_info .group (2 ))]
790
+ gc_times += [0.0 ]
791
+ continue
792
+
793
+ if current_iteration == - 1 :
794
+ continue
795
+
796
+ gc_log = re .search ("\\ [GC .* ([0-9,]*) secs]" , line )
797
+ if gc_log :
798
+ gc_times [len (gc_times ) - 1 ] += float (gc_log .group (1 ).replace (',' , '.' ))
799
+
800
+ if current_iteration >= iterations_count / 2 and "[engine] opt done" in line :
801
+ late_compilation = current_iteration
802
+
727
803
728
804
class PythonBenchmarkSuite (PythonBaseBenchmarkSuite ):
729
805
def __init__ (self , name , bench_path , benchmarks , python_path = None ):
0 commit comments