Skip to content

Commit 7493c61

Browse files
committed
Benchmark bisect: 'rerun with commands' feature
1 parent 80a1060 commit 7493c61

File tree

2 files changed

+54
-2
lines changed

2 files changed

+54
-2
lines changed

bisect-benchmark.ini

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,23 @@ build_command = mx --dy /compiler build
2727
# "-XX ..." list is not part of the command, that's already part of the output
2828
benchmark_command = mx --dy /compiler benchmark micro:try-except-simple
2929

30+
# Once the good and bad commits are identified, the tool will run all the
31+
# following benchmark commands on both the good and bad revisions. One can
32+
# run the benchmarks again with some extra logging, IGV dumping, ...
33+
# The example commands below are good default that should provide good insight
34+
# into the regression at hand:
35+
# * "--checkup" runs the benchmark with extra iterations, and extra compilation
36+
# and GC logging
37+
# * "--cpusampler" with delay of 10000ms (adjust if the whole benchmark command
38+
# runs for less than that)
39+
# * "--cputracer" and IGV dumping: they filter the roots with name "*measure*",
40+
# adjust that to the benchmark main function(s)
41+
rerun_with_commands =
42+
mx --dy /compiler benchmark micro:try-except-simple -- --checkup |
43+
mx --dy /compiler benchmark micro:try-except-simple -- --cpusampler --cpusampler.Delay=10000 |
44+
mx --dy /compiler benchmark micro:try-except-simple -- --cputracer --cputracer.TraceStatements --cputracer.FilterRootName=measure |
45+
mx --dy /compiler benchmark micro:try-except-simple -- --vm.Dgraal.Dump=Truffle:2 --vm.Dgraal.MethodFilter="*measure*"
46+
3047
# The first known "bad" merge commit for bisection. Try to use long commit
3148
# SHAs, the CI cache has higher probability of short SHAs being ambiguous
3249
bad = 1234deadbeef

mx.graalpython/mx_graalpython_bisect.py

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@
4747
import mx
4848

4949

50+
def hr(l):
51+
print('=' * l)
52+
5053
def get_suite(name):
5154
suite_name = name.lstrip('/')
5255
suite = mx.suite(suite_name, fatalIfMissing=False)
@@ -186,13 +189,17 @@ def _bisect_benchmark(argv, bisect_id, email_to):
186189
args.benchmark_criterion = sec.get('benchmark_criterion', 'BEST')
187190
args.enterprise = sec.getboolean('enterprise', False)
188191
args.no_clean = sec.getboolean('no_clean', False)
192+
args.rerun_with_commands = sec['rerun_with_commands']
189193
else:
190194
parser = argparse.ArgumentParser()
191195
parser.add_argument('bad', help="Bad commit for bisection")
192196
parser.add_argument('good', help="Good commit for bisection")
193197
parser.add_argument('build_command', help="Command to run in order to build the configuration")
194198
parser.add_argument('benchmark_command',
195199
help="Command to run in order to run the benchmark. Output needs to be in mx's format")
200+
parser.add_argument('--rerun-with-commands',
201+
help="Re-run the bad and good commits with this benchmark command(s) "
202+
"(multiple commands separated by '|')")
196203
parser.add_argument('--benchmark-criterion', default='BEST',
197204
help="Which result parameter should be used for comparisons")
198205
parser.add_argument('--enterprise', action='store_true', help="Whether to checkout graal-enterprise")
@@ -203,7 +210,7 @@ def _bisect_benchmark(argv, bisect_id, email_to):
203210

204211
fetched_enterprise = [False]
205212

206-
def benchmark_callback(suite, commit):
213+
def checkout_suite(suite, commit):
207214
suite.vc.update_to_branch(suite.vc_dir, commit)
208215
mx.run_mx(['sforceimports'], suite=suite)
209216
mx.run_mx(['--env', 'ce', 'sforceimports'], suite=get_suite('/vm'))
@@ -223,6 +230,9 @@ def benchmark_callback(suite, commit):
223230
if args.enterprise:
224231
debug_str += " graal-enterprise={}".format(get_commit(get_suite('/vm-enterprise')))
225232
print(debug_str)
233+
234+
def checkout_and_build_suite(suite, commit):
235+
checkout_suite(suite, commit)
226236
build_command = shlex.split(args.build_command)
227237
if not args.no_clean:
228238
try:
@@ -235,8 +245,11 @@ def benchmark_callback(suite, commit):
235245
retcode = mx.run(build_command, nonZeroIsFatal=False)
236246
if retcode:
237247
raise RuntimeError("Failed to execute the build command for {}".format(commit))
248+
249+
def benchmark_callback(suite, commit, bench_command=args.benchmark_command):
250+
checkout_and_build_suite(suite, commit)
238251
output = mx.OutputCapture()
239-
retcode = mx.run(shlex.split(args.benchmark_command), out=mx.TeeOutputCapture(output), nonZeroIsFatal=False)
252+
retcode = mx.run(shlex.split(bench_command), out=mx.TeeOutputCapture(output), nonZeroIsFatal=False)
240253
if retcode:
241254
raise RuntimeError("Failed to execute benchmark for {}".format(commit))
242255
match = re.search(r'{}.*duration: ([\d.]+)'.format(re.escape(args.benchmark_criterion)), output.data)
@@ -255,6 +268,28 @@ def benchmark_callback(suite, commit):
255268
print()
256269
print(summary)
257270

271+
if args.rerun_with_commands:
272+
print('\n\nRerunning the good and bad commits with extra benchmark commands:')
273+
current_result = result
274+
current_suite = primary_suite
275+
while current_result.subresults and current_result.bad_index in current_result.subresults:
276+
downstream_suite = get_downstream_suite(current_suite)
277+
next_result = current_result.subresults[current_result.bad_index]
278+
if not next_result.good_commit or not next_result.bad_commit:
279+
print("Next downstream suite {} does not have both good and bad commits".format(downstream_suite.name))
280+
break
281+
print("Recursing to downstream suite: {}, commit: {}".format(downstream_suite.name, current_result.bad_commit))
282+
checkout_suite(current_suite, current_result.bad_commit)
283+
current_result = next_result
284+
current_suite = downstream_suite
285+
for commit in [current_result.good_commit, current_result.bad_commit]:
286+
hr(80)
287+
print("Commit: {}".format(commit))
288+
checkout_and_build_suite(current_suite, commit)
289+
for cmd in args.rerun_with_commands.split("|"):
290+
hr(40)
291+
mx.run(shlex.split(cmd.strip()), nonZeroIsFatal=False)
292+
258293
send_email(
259294
bisect_id,
260295
email_to,

0 commit comments

Comments
 (0)