23
23
# OF THE POSSIBILITY OF SUCH DAMAGE.
24
24
from __future__ import print_function
25
25
26
+ import itertools
26
27
import functools
27
28
import statistics
28
29
import sys
54
55
# constants
55
56
#
56
57
# ----------------------------------------------------------------------------------------------------------------------
57
- ENV_PYPY_HOME = "PYPY_HOME"
58
- ENV_PYTHON3_HOME = "PYTHON3_HOME"
59
- ENV_VIRTUAL_ENV = "VIRTUAL_ENV"
60
- ENV_JYTHON_JAR = "JYTHON_JAR"
61
58
VM_NAME_GRAALPYTHON = "graalpython"
62
- VM_NAME_CPYTHON = "cpython"
63
- VM_NAME_PYPY = "pypy"
64
- VM_NAME_JYTHON = "jython"
65
59
VM_NAME_GRAALPYTHON_SVM = "graalpython-svm"
66
60
GROUP_GRAAL = "Graal"
67
61
SUBGROUP_GRAAL_PYTHON = "graalpython"
@@ -129,12 +123,11 @@ def _handle_var(key_value):
129
123
#
130
124
# ----------------------------------------------------------------------------------------------------------------------
131
125
class AbstractPythonVm (OutputCapturingVm , ABC ):
132
- def __init__ (self , name , config_name , options = None , env = None ):
126
+ def __init__ (self , name , config_name , options = None ):
133
127
super ().__init__ ()
134
128
self ._name = name
135
129
self ._config_name = config_name
136
130
self ._options = options
137
- self ._env = env
138
131
139
132
@property
140
133
def options (self ):
@@ -153,21 +146,21 @@ def interpreter(self):
153
146
def post_process_command_line_args (self , args ):
154
147
return args
155
148
156
- def run_vm (self , args , out = None , err = None , cwd = None , nonZeroIsFatal = False ):
149
+ def run_vm (self , args , out = None , err = None , cwd = None , nonZeroIsFatal = False , env = None ):
157
150
mx .logv (shlex .join ([self .interpreter ] + args ))
158
151
return mx .run (
159
152
[self .interpreter ] + args ,
160
153
out = out ,
161
154
err = err ,
162
155
cwd = cwd ,
163
156
nonZeroIsFatal = nonZeroIsFatal ,
164
- env = self . _env
157
+ env = env ,
165
158
)
166
159
167
160
168
161
class AbstractPythonIterationsControlVm (AbstractPythonVm ):
169
- def __init__ (self , name , config_name , options = None , env = None , iterations = None ):
170
- super ().__init__ (name , config_name , options = options , env = env )
162
+ def __init__ (self , name , config_name , options = None , iterations = None ):
163
+ super ().__init__ (name , config_name , options = options )
171
164
try :
172
165
self ._iterations = int (iterations )
173
166
except :
@@ -194,10 +187,8 @@ def run_vm(self, args, *splat, **kwargs):
194
187
195
188
196
189
class CPythonVm (AbstractPythonIterationsControlVm ):
197
- PYTHON_INTERPRETER = "python3"
198
-
199
- def __init__ (self , config_name , options = None , env = None , virtualenv = None , iterations = 0 ):
200
- super ().__init__ (VM_NAME_CPYTHON , config_name , options = options , env = env , iterations = iterations )
190
+ def __init__ (self , config_name , options = None , virtualenv = None , iterations = 0 ):
191
+ super ().__init__ ("cpython" , config_name , options = options , iterations = iterations )
201
192
self ._virtualenv = virtualenv
202
193
203
194
def override_iterations (self , requested_iterations ):
@@ -206,41 +197,74 @@ def override_iterations(self, requested_iterations):
206
197
207
198
@property
208
199
def interpreter (self ):
209
- venv = self ._virtualenv if self ._virtualenv else mx .get_env (ENV_VIRTUAL_ENV )
210
- if venv :
211
- mx .log (f"CPythonVM virtualenv={ venv } " )
212
- return os .path .join (venv , 'bin' , CPythonVm .PYTHON_INTERPRETER )
213
- home = mx .get_env (ENV_PYTHON3_HOME )
214
- if home :
215
- mx .log (f"CPythonVM python3 home={ home } " )
216
- return os .path .join (home , CPythonVm .PYTHON_INTERPRETER )
217
- return CPythonVm .PYTHON_INTERPRETER
200
+ candidates_pre = [
201
+ self ._virtualenv ,
202
+ mx .get_env ("VIRTUAL_ENV" ),
203
+ mx .get_env ("PYTHON3_HOME" ),
204
+ ]
205
+ candidates_suf = [
206
+ join ("bin" , "python3" ),
207
+ join ("bin" , "python" ),
208
+ "python3" ,
209
+ "python" ,
210
+ sys .executable ,
211
+ ]
212
+ for p , s in itertools .product (candidates_pre , candidates_suf ):
213
+ if os .path .exists (exe := os .path .join (p or "" , s )):
214
+ mx .log (f"CPython VM { exe = } " )
215
+ return exe
216
+ assert False , "sys.executable should really exist"
218
217
218
+ def run_vm (self , args , * splat , ** kwargs ):
219
+ for idx , arg in enumerate (args ):
220
+ if "--vm.Xmx" in arg :
221
+ mx .warn (f"Ignoring { arg } , cannot restrict memory on CPython." )
222
+ args = args [:idx ] + args [idx + 1 :]
223
+ break
224
+ return super ().run_vm (args , * splat , ** kwargs )
219
225
220
- class PyPyVm (AbstractPythonIterationsControlVm ):
221
- PYPY_INTERPRETER = "pypy3"
222
226
223
- def __init__ (self , config_name , options = None , env = None , virtualenv = None , iterations = 0 ):
224
- super ().__init__ (VM_NAME_PYPY , config_name , options = options , env = env , iterations = iterations )
227
+ class PyPyVm (AbstractPythonIterationsControlVm ):
228
+ def __init__ (self , config_name , options = None , virtualenv = None , iterations = 0 ):
229
+ super ().__init__ ("pypy" , config_name , options = options , iterations = iterations )
225
230
226
231
def override_iterations (self , requested_iterations ):
227
232
# PyPy warms up much faster, half should be enough
228
233
return int (requested_iterations / 2 )
229
234
230
235
@property
231
236
def interpreter (self ):
232
- home = mx .get_env (ENV_PYPY_HOME )
233
- if not home :
237
+ if home := mx .get_env ("PYPY_HOME" ):
238
+ exe = join (home , "bin" , "pypy3" )
239
+ else :
234
240
try :
235
- return subprocess .check_output ("which %s" % PyPyVm . PYPY_INTERPRETER , shell = True ).decode ().strip ()
241
+ exe = subprocess .check_output ("which pypy3" , shell = True ).decode ().strip ()
236
242
except OSError :
237
- mx .abort ("{} is not set!" .format (ENV_PYPY_HOME ))
238
- return join (home , 'bin' , PyPyVm .PYPY_INTERPRETER )
243
+ mx .abort ("PYPY_HOME is not set!" )
244
+ mx .log (f"PyPy { exe = } " )
245
+ return exe
246
+
247
+ def run_vm (self , args , * splat , env = None , ** kwargs ):
248
+ env = env or os .environ .copy ()
249
+ xmxArg = re .compile ("--vm.Xmx([0-9]+)([kKgGmM])" )
250
+ pypyGcMax = "8GB"
251
+ for idx , arg in enumerate (args ):
252
+ if m := xmxArg .search (arg ):
253
+ args = args [:idx ] + args [idx + 1 :]
254
+ pypyGcMax = f"{ m .group (1 )} { m .group (2 ).upper ()} B"
255
+ mx .log (f"Setting PYPY_GC_MAX={ pypyGcMax } via { arg } " )
256
+ break
257
+ else :
258
+ mx .log (
259
+ f"Setting PYPY_GC_MAX={ pypyGcMax } , use --vm.Xmx argument to override it"
260
+ )
261
+ env ["PYPY_GC_MAX" ] = pypyGcMax
262
+ return super ().run_vm (args , * splat , env = env , ** kwargs )
239
263
240
264
241
265
class GraalPythonVm (AbstractPythonIterationsControlVm ):
242
- def __init__ (self , config_name , options = None , env = None , virtualenv = None , iterations = None , extra_polyglot_args = None ):
243
- super ().__init__ (VM_NAME_GRAALPYTHON , config_name , options = options , env = env , iterations = iterations )
266
+ def __init__ (self , config_name , options = None , virtualenv = None , iterations = None , extra_polyglot_args = None ):
267
+ super ().__init__ (VM_NAME_GRAALPYTHON , config_name , options = options , iterations = iterations )
244
268
self ._extra_polyglot_args = extra_polyglot_args or []
245
269
246
270
@property
@@ -273,7 +297,7 @@ def extract_vm_info(self, args=None):
273
297
out_version = subprocess .check_output ([self .interpreter , '--version' ], universal_newlines = True )
274
298
# The benchmark data goes back a ways, we modify the reported dims for
275
299
# continuity with the historical queries
276
- graalvm_version_match = re .search (r"\(([^\)]+ ((?:\d+\.?)+))\)" , out_version )
300
+ graalvm_version_match = re .search (r"\(([^\)]+ ((?:\d+\.?)+)).* \)" , out_version )
277
301
if not graalvm_version_match :
278
302
mx .log (f"Using { out_version } as platform version string input" )
279
303
graalvm_version_match = [out_version , out_version , out_version ]
@@ -311,15 +335,14 @@ def get_extra_polyglot_args(self):
311
335
312
336
class GraalPythonJavaDriverVm (GuestVm ):
313
337
def __init__ (self , config_name = CONFIGURATION_DEFAULT , cp_suffix = None , distributions = None , cp_prefix = None ,
314
- host_vm = None , extra_vm_args = None , extra_polyglot_args = None , env = None ):
338
+ host_vm = None , extra_vm_args = None , extra_polyglot_args = None ):
315
339
super ().__init__ (host_vm = host_vm )
316
340
self ._config_name = config_name
317
341
self ._distributions = distributions or ['GRAALPYTHON_BENCH' ]
318
342
self ._cp_suffix = cp_suffix
319
343
self ._cp_prefix = cp_prefix
320
344
self ._extra_vm_args = extra_vm_args
321
345
self ._extra_polyglot_args = extra_polyglot_args if isinstance (extra_polyglot_args , list ) else []
322
- self ._env = env
323
346
324
347
def name (self ):
325
348
return VM_NAME_GRAALPYTHON
@@ -341,30 +364,30 @@ def get_classpath(self):
341
364
def with_host_vm (self , host_vm ):
342
365
return self .__class__ (config_name = self ._config_name , distributions = self ._distributions ,
343
366
cp_suffix = self ._cp_suffix , cp_prefix = self ._cp_prefix , host_vm = host_vm ,
344
- extra_vm_args = self ._extra_vm_args , extra_polyglot_args = self ._extra_polyglot_args ,
345
- env = self ._env )
367
+ extra_vm_args = self ._extra_vm_args , extra_polyglot_args = self ._extra_polyglot_args )
346
368
347
369
def launcher_class (self ):
348
370
return 'com.oracle.graal.python.benchmarks.JavaBenchmarkDriver'
349
371
350
372
def run (self , cwd , args ):
351
373
extra_polyglot_args = self .get_extra_polyglot_args ()
352
374
host_vm = self .host_vm ()
353
- with environ (self ._env or {}):
354
- cp = self .get_classpath ()
355
- jhm = mx .dependency ("mx:JMH_1_21" )
356
- cp_deps = [
357
- mx .distribution ('GRAALPYTHON_BENCH' , fatalIfMissing = True ),
358
- jhm ,
359
- mx .dependency ("sdk:LAUNCHER_COMMON" )
360
- ] + jhm .deps
361
- cp += [x .classpath_repr () for x in cp_deps ]
362
- java_args = ['-cp' , ':' .join (cp )] + [self .launcher_class ()]
363
- out = mx .TeeOutputCapture (mx .OutputCapture ())
364
- code = host_vm .run_java (java_args + extra_polyglot_args + args , cwd = cwd , out = out , err = out )
365
- out = out .underlying .data
366
- dims = host_vm .dimensions (cwd , args , code , out )
367
- return code , out , dims
375
+ cp = self .get_classpath ()
376
+ jhm = mx .dependency ("mx:JMH_1_21" )
377
+ cp_deps = mx .classpath_entries (filter (None , [
378
+ mx .distribution ('GRAALPYTHON_BENCH' , fatalIfMissing = True ),
379
+ mx .distribution ('TRUFFLE_RUNTIME' , fatalIfMissing = True ),
380
+ mx .distribution ('TRUFFLE_ENTERPRISE' , fatalIfMissing = False ),
381
+ jhm ,
382
+ mx .dependency ("sdk:LAUNCHER_COMMON" )
383
+ ] + jhm .deps ))
384
+ cp += [x .classpath_repr () for x in cp_deps ]
385
+ java_args = ['-cp' , ':' .join (cp )] + [self .launcher_class ()]
386
+ out = mx .TeeOutputCapture (mx .OutputCapture ())
387
+ code = host_vm .run_java (java_args + extra_polyglot_args + args , cwd = cwd , out = out , err = out )
388
+ out = out .underlying .data
389
+ dims = host_vm .dimensions (cwd , args , code , out )
390
+ return code , out , dims
368
391
369
392
def get_extra_polyglot_args (self ):
370
393
return ["--experimental-options" , "--python.MaxNativeMemory=%s" % (2 ** 34 ), * self ._extra_polyglot_args ]
@@ -381,7 +404,7 @@ def get_extra_polyglot_args(self):
381
404
382
405
class PythonBaseBenchmarkSuite (VmBenchmarkSuite , AveragingBenchmarkMixin ):
383
406
def __init__ (self , name , benchmarks ):
384
- super (PythonBaseBenchmarkSuite , self ).__init__ ()
407
+ super ().__init__ ()
385
408
self ._checkup = 'GRAALPYTHON_BENCHMARKS_CHECKUP' in os .environ
386
409
self ._name = name
387
410
self ._benchmarks = benchmarks
@@ -578,14 +601,7 @@ def rules(self, output, benchmarks, bm_suite_args):
578
601
]
579
602
580
603
def runAndReturnStdOut (self , benchmarks , bmSuiteArgs ):
581
- ret_code , out , dims = super (PythonBaseBenchmarkSuite , self ).runAndReturnStdOut (benchmarks , bmSuiteArgs )
582
-
583
- # host-vm rewrite rules
584
- if dims ['host-vm' ] not in ('graalvm-ce' , 'graalvm-ee' ):
585
- if mx .suite ('graal-enterprise' , fatalIfMissing = False ):
586
- dims ['host-vm' ] = 'graalvm-ee'
587
- else :
588
- dims ['host-vm' ] = 'graalvm-ce'
604
+ ret_code , out , dims = super ().runAndReturnStdOut (benchmarks , bmSuiteArgs )
589
605
590
606
self .post_run_graph (benchmarks [0 ], dims ['host-vm-config' ], dims ['guest-vm-config' ])
591
607
@@ -598,7 +614,7 @@ def run(self, benchmarks, bm_suite_args):
598
614
if '--checkup' in bm_suite_args :
599
615
self ._checkup = True
600
616
bm_suite_args .remove ('--checkup' )
601
- results = super (PythonBaseBenchmarkSuite , self ).run (benchmarks , bm_suite_args )
617
+ results = super ().run (benchmarks , bm_suite_args )
602
618
self .addAverageAcrossLatestResults (results )
603
619
return results
604
620
@@ -710,7 +726,7 @@ def checkup(self, out):
710
726
711
727
class PythonBenchmarkSuite (PythonBaseBenchmarkSuite ):
712
728
def __init__ (self , name , bench_path , benchmarks , python_path = None ):
713
- super (PythonBenchmarkSuite , self ).__init__ (name , benchmarks )
729
+ super ().__init__ (name , benchmarks )
714
730
self ._python_path = python_path
715
731
self ._harness_path = HARNESS_PATH
716
732
self ._harness_path = join (SUITE .dir , self ._harness_path )
@@ -778,7 +794,7 @@ def get_benchmark_suites(cls, benchmarks):
778
794
779
795
class PythonJavaEmbeddingBenchmarkSuite (PythonBaseBenchmarkSuite ):
780
796
def __init__ (self , name , bench_path , benchmarks ):
781
- super (PythonJavaEmbeddingBenchmarkSuite , self ).__init__ (name , benchmarks )
797
+ super ().__init__ (name , benchmarks )
782
798
self ._bench_path = bench_path
783
799
784
800
def get_vm_registry (self ):
@@ -1001,6 +1017,9 @@ def register_vms(suite, sandboxed_options):
1001
1017
# Other Python VMs:
1002
1018
python_vm_registry .add_vm (CPythonVm (config_name = CONFIGURATION_DEFAULT ), suite )
1003
1019
python_vm_registry .add_vm (PyPyVm (config_name = CONFIGURATION_DEFAULT ), suite )
1020
+ # For continuity with old datapoints, provide CPython and PyPy with launcher config_name
1021
+ python_vm_registry .add_vm (CPythonVm (config_name = "launcher" ), suite )
1022
+ python_vm_registry .add_vm (PyPyVm (config_name = "launcher" ), suite )
1004
1023
1005
1024
graalpy_vms = []
1006
1025
0 commit comments