Skip to content

Commit 4dc6019

Browse files
committed
[GR-68709] Various polybench fixes.
PullRequest: graal/21874
2 parents 2b5956d + 22494a2 commit 4dc6019

File tree

10 files changed

+304
-186
lines changed

10 files changed

+304
-186
lines changed

graal-common.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"README": "This file contains definitions that are useful for the jsonnet CI files of the graal and graal-enterprise repositories.",
33
"ci": {
4-
"overlay": "2f0084a8ab476f991f50132e1879a925efb0d596"
4+
"overlay": "0fe21f893386fb7e7c5afdcb6b088e596544faa6"
55
}
66
}

sdk/mx.sdk/mx_sdk_benchmark.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1118,8 +1118,8 @@ def supported_vm_arg_prefixes():
11181118
basis. In the future we can convert this from a failure into a warning.
11191119
:return: a list of args supported by native image.
11201120
"""
1121-
return ['-D', '-Xmx', '-Xmn', '-XX:-PrintGC', '-XX:+PrintGC', '--add-opens', '--add-modules', '--add-exports',
1122-
'--add-reads']
1121+
return ['-D', '-H', '-Xmx', '-Xmn', '-XX:-PrintGC', '-XX:+PrintGC', '--add-opens', '--add-modules', '--add-exports',
1122+
'--add-reads', '--enable-native-access']
11231123

11241124
_VM_OPTS_SPACE_SEPARATED_ARG = ['-mp', '-modulepath', '-limitmods', '-addmods', '-upgrademodulepath', '-m',
11251125
'--module-path', '--limit-modules', '--add-modules', '--upgrade-module-path',

truffle/mx.truffle/mx_polybench/README.md

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,44 +18,46 @@ details.
1818

1919

2020
```commandline
21-
# Use 'list' to list available benchmarks.
21+
# Use '--list' to list available benchmarks.
2222
$ cd graal/truffle
23-
$ mx polybench list
24-
Benchmark files (run using "mx polybench run <glob_pattern>"):
23+
$ mx polybench --list
24+
Listing all available polybench benchmarks.
25+
Benchmark files (run using "mx polybench <glob_pattern>"):
2526
interpreter/fibonacci.sl
26-
Suites (run using "mx polybench run --suite <suite_name>" or "mx polybench run --suite <suite_name>:<tag1>,<tag2>,..."):
27+
Suites (run using "mx polybench --suite <suite_name>" or "mx polybench --suite <suite_name>:<tag1>,<tag2>,..."):
2728
sl: {'benchmark', 'gate'}
2829
2930
# The list is populated based on the registrations of the loaded suites. When different suites are loaded, different benchmarks may become available.
3031
$ cd graal/sulong
31-
$ mx polybench list
32-
Benchmark files (run using "mx polybench run <glob_pattern>"):
32+
$ mx polybench --list
33+
Listing all available polybench benchmarks.
34+
Benchmark files (run using "mx polybench <glob_pattern>"):
3335
interpreter/deltablue.c.native.bc
3436
interpreter/sieve.c.native.bc
3537
interpreter/richards.c.native.bc
3638
interpreter/fibonacci.c.native.bc
3739
interpreter/fibonacci.sl
38-
Suites (run using "mx polybench run --suite <suite_name>" or "mx polybench run --suite <suite_name>:<tag1>,<tag2>,..."):
40+
Suites (run using "mx polybench --suite <suite_name>" or "mx polybench --suite <suite_name>:<tag1>,<tag2>,..."):
3941
sulong: {'gate', 'benchmark'}
4042
sl: {'gate', 'benchmark'}
4143
4244
# Use 'run' to run benchmarks. Below are some examples.
4345
4446
# Run fibonacci.sl on the JVM (default, but you can specify --jvm to be explicit)
45-
$ mx polybench run interpreter/fibonacci.sl
47+
$ mx polybench interpreter/fibonacci.sl
4648
4749
# Run all interpreter benchmarks in native mode.
48-
$ mx polybench run --native 'interpreter/*'
50+
$ mx polybench --native 'interpreter/*'
4951
5052
# Polybench always uses the mx Java home as its host VM. It is recommended to use '--java-home' to change the host VM.
51-
$ mx --java-home $CUSTOM_GRAALVM_HOME polybench run interpreter/fibonacci.sl
53+
$ mx --java-home $CUSTOM_GRAALVM_HOME polybench interpreter/fibonacci.sl
5254
5355
# Run the sl 'gate' suite (suite definitions are described below, in the "Registering benchmarks" section).
54-
$ mx polybench run --suite sl:gate
56+
$ mx polybench --suite sl:gate
5557
5658
# 'run' accepts any number of arguments after the benchmark/suite name.
5759
# These arguments are passed to the polybench launcher (default), mx benchmark, or the VM:
58-
$ mx polybench run interpreter/fibonacci.sl polybenchArg1 --mx-benchmark-args mxBenchmarkArg --vm-args vmArg --polybench-args polybenchArg2
60+
$ mx polybench interpreter/fibonacci.sl polybenchArg1 --mx-benchmark-args mxBenchmarkArg --vm-args vmArg --polybench-args polybenchArg2
5961
```
6062

6163
## Registering benchmarks

truffle/mx.truffle/mx_polybench/command.py

Lines changed: 119 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
#
4141
import argparse
4242
import contextlib
43-
import fnmatch
43+
import shlex
4444
from argparse import ArgumentParser
4545
from enum import Enum
4646
from typing import List, Set, Tuple, NamedTuple
@@ -69,9 +69,9 @@ def parser_help_message(cls):
6969
return (
7070
"additional benchmark arguments. By default, arguments are passed to the Polybench launcher, "
7171
f"but you may use flags to forward arguments to specific components: "
72-
f"{cls.MX_BENCHMARK_FLAG} for mx benchmark, "
73-
f"{cls.VM_FLAG} for the host VM or native-image, or "
74-
f"{cls.POLYBENCH_FLAG} for the Polybench launcher. "
72+
f'"{cls.MX_BENCHMARK_FLAG}" for mx benchmark, '
73+
f'"{cls.VM_FLAG}" for the host VM or native-image, or '
74+
f'"{cls.POLYBENCH_FLAG}" for the Polybench launcher (pass "--help" to see launcher help). '
7575
f'For example: "-i 2 {cls.MX_BENCHMARK_FLAG} --fail-fast {cls.VM_FLAG} -ea '
7676
f'{cls.POLYBENCH_FLAG} --engine.TraceCompilation=true".'
7777
)
@@ -124,57 +124,60 @@ def append(self, other: "PolybenchArgumentsSpecification") -> "PolybenchArgument
124124
)
125125

126126

127-
def polybench_list(args):
127+
def polybench_list():
128128
benchmarks = _resolve_all_benchmarks()
129-
print('Benchmark files (run using "mx polybench run <glob_pattern>"):')
129+
mx.log("Listing all available polybench benchmarks.")
130+
mx.log('Benchmark files (run using "mx polybench <glob_pattern>"):')
130131
file_found = False
131132
for benchmark_name, resolved_benchmark in benchmarks.items():
132-
if args.glob and not fnmatch.fnmatchcase(benchmark_name, f"*{args.glob}*"):
133-
continue
134133
file_found = True
135-
print(f"\t{benchmark_name}")
136-
if args.verbose:
137-
print(f"\t\tabsolute path: {resolved_benchmark.absolute_path}")
138-
print(f"\t\tdistribution: {resolved_benchmark.suite.benchmark_distribution}")
139-
print(f"\t\tdeclaring suite: {resolved_benchmark.suite.mx_suite.name}")
140-
print(f"\t\trequired languages: {resolved_benchmark.suite.languages}")
134+
mx.log(f"\t{benchmark_name}")
135+
mx.logv(f"\t\tabsolute path: {resolved_benchmark.absolute_path}")
136+
mx.logv(f"\t\tdistribution: {resolved_benchmark.suite.benchmark_distribution}")
137+
mx.logv(f"\t\tdeclaring suite: {resolved_benchmark.suite.mx_suite.name}")
138+
mx.logv(f"\t\trequired languages: {resolved_benchmark.suite.languages}")
141139
if not file_found:
142-
print("\tno benchmark files found")
140+
mx.log("\tno benchmark files found")
143141

144142
suites = _get_all_suites()
145-
print(
146-
'Suites (run using "mx polybench run --suite <suite_name>" or "mx polybench run --suite <suite_name>:<tag1>,<tag2>,..."):'
143+
mx.log(
144+
'Suites (run using "mx polybench --suite <suite_name>" or "mx polybench --suite <suite_name>:<tag1>,<tag2>,..."):'
147145
)
148146
suite_found = False
149147
for suite_name, suite in suites.items():
150-
if args.glob and not fnmatch.fnmatchcase(suite_name, f"*{args.glob}*"):
151-
continue
152148
suite_found = True
153-
print(f"\t{suite_name}: {suite.tags if suite.tags else '{}'}")
149+
mx.log(f"\t{suite_name}: {suite.tags if suite.tags else '{}'}")
154150
if not suite_found:
155-
print("\tno suites found")
151+
mx.log("\tno suites found")
156152

157153

158-
def polybench_run(args):
159-
if args.suite:
160-
_run_suite(args)
154+
def polybench_run(parsed_args, raw_args):
155+
if parsed_args.suite:
156+
_run_suite(parsed_args)
157+
elif parsed_args.dry_run_polybench:
158+
_dry_run_polybench(raw_args)
161159
else:
162-
_run_benchmark_pattern(args)
160+
_run_benchmark_pattern(parsed_args)
161+
162+
163+
def _dry_run_polybench(raw_args):
164+
raw_args.remove("--dry-run-polybench")
165+
mx.log(_mx_polybench_command_string(raw_args))
163166

164167

165168
def _run_suite(args):
166169
suite, tags = _get_suite_and_tags(args)
167170
if tags - suite.tags:
168171
mx.abort(
169-
f"Requested tag(s) not available for suite '{suite}': {tags - suite.tags}. Available tags: {suite.tags}"
172+
f'Requested tag(s) not available for suite "{suite}": {tags - suite.tags}. Available tags: {suite.tags}'
170173
)
171174

172175
mx.log(f"Running suite {suite.name} with tags {tags}.")
173176

174177
# Arguments passed in a suite run are appended after the arguments specified by the suite runner.
175-
if args.arguments:
178+
if args.benchmark_arguments:
176179
mx.warn(
177-
f"Arguments were supplied on the command line ({args.arguments}). "
180+
f"Arguments were supplied on the command line ({args.benchmark_arguments}). "
178181
"These arguments will be inserted after any arguments supplied by the suite runner."
179182
)
180183
features = _get_vm_features(args)
@@ -184,21 +187,24 @@ def _run_suite(args):
184187
"You can directly enable these features in the suite runner itself."
185188
)
186189
override_arguments = (
187-
PolybenchArgumentsSpecification.parse(args.arguments)
190+
PolybenchArgumentsSpecification.parse(args.benchmark_arguments)
188191
.append(
189192
# Ensure results are combined across multiple runs.
190193
PolybenchArgumentsSpecification(mx_benchmark_args=["--append-results"])
191194
)
192195
.to_normalized_command_line()
193196
)
194197

195-
base_args = ["run"]
198+
base_args = []
196199
if args.dry_run:
197200
base_args.append("--dry-run")
201+
elif args.dry_run_polybench:
202+
base_args.append("--dry-run-polybench")
198203

199204
def polybench_run_function(argument_list: List[str]) -> None:
200-
parsed_args = parser.parse_args(base_args + argument_list + override_arguments)
201-
polybench_run(parsed_args)
205+
raw_args = base_args + argument_list + override_arguments
206+
parsed_args = parser.parse_args(raw_args)
207+
polybench_run(parsed_args, raw_args)
202208

203209
with _run_suite_context(suite, tags):
204210
suite.runner(polybench_run_function, tags)
@@ -248,7 +254,7 @@ def require_native(feature_name):
248254

249255

250256
def _run_benchmark_pattern(args):
251-
arguments_spec = PolybenchArgumentsSpecification.parse(args.arguments)
257+
arguments_spec = PolybenchArgumentsSpecification.parse(args.benchmark_arguments)
252258
run_spec = PolybenchRunSpecification(args.benchmarks, _get_vm_features(args), arguments_spec)
253259
_validate_jdk(run_spec.is_native())
254260
mx.logv(f"Performing polybench run: {run_spec}")
@@ -282,7 +288,7 @@ def _parse_mx_benchmark_pattern(pattern: str, pattern_is_glob: bool) -> str:
282288
if pattern.count(":") == 1:
283289
message += ' This pattern looks like a suite. Did you forget "--suite"?'
284290
else:
285-
message += ' Use "mx polybench run -h" to view the expected format for benchmark patterns.'
291+
message += ' Use "mx polybench -h" to view the expected format for benchmark patterns.'
286292
mx.abort(message)
287293

288294
if pattern_is_glob:
@@ -374,79 +380,121 @@ def _run_specification(spec: PolybenchRunSpecification, pattern_is_glob: bool =
374380
mx_benchmark.benchmark(mx_benchmark_args)
375381

376382

377-
def _mx_benchmark_command_string(mx_benchmark_args: List[str]) -> str:
378-
command = f"mx --java-home {mx.get_jdk().home}"
383+
def _base_mx_command() -> List[str]:
384+
command = ["mx", "--java-home", mx.get_jdk().home]
379385
for dynamic_import, in_subdir in mx.get_dynamic_imports():
380386
if in_subdir:
381-
command += f" --dy /{dynamic_import}"
387+
command += ["--dy", f"/{dynamic_import}"]
382388
else:
383-
command += f" --dy {dynamic_import}"
384-
command += " benchmark "
385-
command += " ".join(mx_benchmark_args)
389+
command += ["--dy", dynamic_import]
386390
return command
387391

388392

393+
def _mx_polybench_command_string(mx_polybench_args: List[str]) -> str:
394+
return _build_command(_base_mx_command() + ["polybench"] + mx_polybench_args)
395+
396+
397+
def _mx_benchmark_command_string(mx_benchmark_args: List[str]) -> str:
398+
return _build_command(_base_mx_command() + ["benchmark"] + mx_benchmark_args)
399+
400+
401+
def _build_command(command: List[str]) -> str:
402+
return " ".join(shlex.quote(token) for token in command)
403+
404+
389405
def _create_parser() -> ArgumentParser:
390406
parser = ArgumentParser(
391407
prog="mx polybench",
392408
description=(
393409
"mx polybench is a simple command line interface for Polybench, the system used to benchmark Truffle languages. "
394-
"It is a thin wrapper around Polybench's mx benchmark integration that makes it easy to discover benchmarks "
395-
'(using "mx polybench list") and to run them (using "mx polybench run"). '
410+
"It is a thin wrapper around Polybench's mx benchmark integration that makes it easy to discover and run benchmarks. "
396411
"It also supports batch execution of the benchmarks in a suite, which is convenient for defining CI jobs."
397412
),
413+
usage="%(prog)s [options*] benchmarks [benchmark_arguments*]",
398414
)
399-
subparsers = parser.add_subparsers(dest="command", required=True, help="the polybench command to run")
400-
401-
list_parser = subparsers.add_parser("list", help="list the available benchmarks")
402-
list_parser.add_argument("glob", nargs="?", type=str, help="a glob pattern to filter benchmark output")
403-
list_parser.add_argument("--verbose", action="store_true", help="print a detailed view of the benchmarks")
404-
list_parser.set_defaults(func=polybench_list)
405415

406-
run_parser = subparsers.add_parser("run", help="run one or more benchmarks")
407-
run_parser.add_argument(
416+
parser.add_argument(
408417
"benchmarks",
418+
nargs="?",
409419
help='a glob pattern representing benchmarks to run (e.g., "interpreter/*"), '
410420
'or a suite specification if "--suite" is provided. '
411-
'Use "mx polybench list" to see a list of available benchmarks.',
421+
'Use "--list" to see a list of available benchmarks.',
412422
)
413-
run_parser.add_argument(
414-
"arguments", nargs=argparse.REMAINDER, help=PolybenchArgumentsSpecification.parser_help_message()
423+
parser.add_argument(
424+
"--list", action="store_true", help="list all available benchmarks (without actually executing them)."
415425
)
416-
run_parser.add_argument(
417-
"--dry-run",
426+
427+
run_flags = set()
428+
429+
def run_flag(run_arg):
430+
run_flags.add(run_arg)
431+
return run_arg
432+
433+
dry_run_group = parser.add_mutually_exclusive_group()
434+
dry_run_group.add_argument(
435+
run_flag("--dry-run"),
418436
action="store_true",
419437
help="log the mx benchmark commands that would be executed by this command (without actually executing them)",
420438
)
421-
mode_group = run_parser.add_mutually_exclusive_group()
439+
dry_run_group.add_argument(
440+
run_flag("--dry-run-polybench"),
441+
action="store_true",
442+
help="log the mx polybench commands that would be executed by this command (without actually executing them)",
443+
)
444+
445+
mode_group = parser.add_mutually_exclusive_group()
422446
mode_group.add_argument(
423-
"--jvm", action="store_false", dest="is_native", default=False, help="run the benchmark on the JVM (default)"
447+
run_flag("--jvm"),
448+
action="store_false",
449+
dest="is_native",
450+
default=False,
451+
help="run the benchmark on the JVM (default)",
424452
)
425453
mode_group.add_argument(
426-
"--native",
454+
run_flag("--native"),
427455
action="store_true",
428456
dest="is_native",
429457
help="run the benchmark with a native image of the Truffle interpreter",
430458
)
431-
run_parser.add_argument("--pgo", action="store_true", default=False, help="use PGO (only valid for native runs)")
432-
run_parser.add_argument("--g1gc", action="store_true", default=False, help="use G1GC (only valid for native runs)")
433-
benchmark_pattern_group = run_parser.add_mutually_exclusive_group()
459+
parser.add_argument(
460+
run_flag("--pgo"), action="store_true", default=False, help="use PGO (only valid for native runs)"
461+
)
462+
parser.add_argument(
463+
run_flag("--g1gc"), action="store_true", default=False, help="use G1GC (only valid for native runs)"
464+
)
465+
benchmark_pattern_group = parser.add_mutually_exclusive_group()
434466
benchmark_pattern_group.add_argument(
435-
"--suite",
467+
run_flag("--suite"),
436468
action="store_true",
437469
help='treat "benchmarks" as a suite specification (a suite name, optionally '
438470
"followed by a colon and a comma-separated list of tags, "
439471
'e.g., "sl:gate,daily")',
440472
)
441473
benchmark_pattern_group.add_argument(
442-
"--use-mx-benchmark-pattern",
474+
run_flag("--use-mx-benchmark-pattern"),
443475
action="store_false",
444476
dest="pattern_is_glob",
445477
default=True,
446478
help='treat "benchmarks" as an mx benchmark pattern instead of a glob '
447479
'(e.g., "r[interpreter/.*]"; see mx_benchmark.py for details)',
448480
)
449-
run_parser.set_defaults(func=polybench_run)
481+
482+
def benchmark_argument(arg):
483+
"""Prevents users from accidentally passing a run flag in the benchmark arguments section."""
484+
if arg in run_flags:
485+
mx.abort(
486+
f'Flag "{arg}" is an "mx polybench" flag, but it was specified in the extra benchmark arguments section.\n'
487+
f'Move it before the benchmark pattern/suite specification to fix this error (e.g., "mx polybench {arg} ... benchmark_or_suite ...").'
488+
)
489+
return arg
490+
491+
parser.add_argument(
492+
"benchmark_arguments",
493+
nargs=argparse.REMAINDER,
494+
type=benchmark_argument,
495+
help=PolybenchArgumentsSpecification.parser_help_message(),
496+
)
497+
450498
return parser
451499

452500

@@ -457,5 +505,10 @@ def _create_parser() -> ArgumentParser:
457505
def polybench_command(args):
458506
"""Run one or more benchmarks using polybench."""
459507
parsed_args = parser.parse_args(args)
460-
mx.logv(f"Running polybench command {parsed_args.command} with arguments {parsed_args}")
461-
parsed_args.func(parsed_args)
508+
mx.logv(f"Running polybench with arguments {parsed_args}")
509+
if parsed_args.list:
510+
polybench_list()
511+
elif parsed_args.benchmarks:
512+
polybench_run(parsed_args, args)
513+
else:
514+
mx.abort('A benchmark pattern or --list must be specified. Use "mx polybench -h" for more info.')

0 commit comments

Comments
 (0)