Skip to content

Commit aaa73f3

Browse files
committed
Update PGO build to also save lcov file
1 parent 1bc8a67 commit aaa73f3

File tree

3 files changed

+50
-10
lines changed

3 files changed

+50
-10
lines changed

ci.jsonnet

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,10 @@
233233
"python-pgo-profile": gpgate_ee + platform_spec(no_jobs) + platform_spec({
234234
"linux:amd64:jdk-latest" : weekly + t("01:30:00") + task_spec({
235235
run: [["mx", "python-native-pgo"]],
236-
logs+: ["default.iprof"],
236+
logs+: [
237+
"default.iprof",
238+
"default.lcov",
239+
],
237240
}),
238241
}),
239242
"python-svm-unittest": gpgate + platform_spec(no_jobs) + platform_spec({

mx.graalpython/mx_graalpython.py

Lines changed: 42 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,7 @@ def libpythonvm_build_args():
277277
return build_args
278278

279279

280-
def graalpy_native_pgo_build_and_test(args):
280+
def graalpy_native_pgo_build_and_test(_):
281281
"""
282282
Builds a PGO-instrumented GraalPy native standalone, runs the unittests to generate a profile,
283283
then builds a PGO-optimized GraalPy native standalone with the collected profile.
@@ -287,20 +287,31 @@ def graalpy_native_pgo_build_and_test(args):
287287

288288
with set_env(GRAALPY_PGO_PROFILE=""):
289289
mx.log(mx.colorize("[PGO] Building PGO-instrumented native image", color="yellow"))
290-
native_bin = graalpy_standalone('native', enterprise=True, build=True)
290+
build_home = graalpy_standalone_home('native', enterprise=True, build=True)
291+
instrumented_home = build_home + "_PGO_INSTRUMENTED"
292+
shutil.rmtree(instrumented_home, ignore_errors=True)
293+
shutil.copytree(build_home, instrumented_home, symlinks=True, ignore_dangling_symlinks=True)
294+
instrumented_launcher = os.path.join(instrumented_home, 'bin', _graalpy_launcher())
291295

292-
mx.log(mx.colorize("[PGO] Instrumented build complete.", color="yellow"))
296+
mx.log(mx.colorize(f"[PGO] Instrumented build complete: {instrumented_home}", color="yellow"))
293297

294-
mx.log(mx.colorize(f"[PGO] Running graalpytest with instrumented binary: {native_bin}", color="yellow"))
298+
mx.log(mx.colorize(f"[PGO] Running graalpytest with instrumented binary: {instrumented_launcher}", color="yellow"))
295299
with tempfile.TemporaryDirectory() as d:
296300
with set_env(
297301
GRAALPYTEST_ALLOW_NO_JAVA_ASSERTIONS="true",
298-
GRAAL_PYTHON_VM_ARGS=f"--vm.XX:ProfilesDumpFile={os.path.join(d, '$UUID$.iprof')}"
302+
GRAAL_PYTHON_VM_ARGS="\v".join([
303+
f"--vm.XX:ProfilesDumpFile={os.path.join(d, '$UUID$.iprof')}",
304+
f"--vm.XX:ProfilesLCOVFile={os.path.join(d, '$UUID$.info')}",
305+
]),
306+
GRAALPY_HOME=instrumented_home,
299307
):
300-
graalpytest(["--python", native_bin, "."])
301-
iprof_path = os.path.join(SUITE.dir, 'default.iprof')
308+
graalpytest(["--python", instrumented_launcher, "test_venv.py"])
309+
mx.command_function('benchmark')(["meso-small:*"])
302310

303-
mx.run([
311+
iprof_path = Path(SUITE.dir) / 'default.iprof'
312+
lcov_path = Path(SUITE.dir) / 'default.lcov'
313+
314+
run([
304315
os.path.join(
305316
graalvm_jdk(enterprise=True),
306317
"bin",
@@ -310,11 +321,30 @@ def graalpy_native_pgo_build_and_test(args):
310321
f"--input-dir={d}",
311322
f"--output-file={iprof_path}"
312323
])
324+
run([
325+
"/usr/bin/env",
326+
"lcov",
327+
"-o", str(lcov_path),
328+
*itertools.chain.from_iterable([
329+
["-a", f.absolute().as_posix()] for f in Path(d).glob("*.info")
330+
])
331+
], nonZeroIsFatal=False)
332+
run([
333+
"/usr/bin/env",
334+
"genhtml",
335+
"--source-directory", str(Path(SUITE.dir) / "com.oracle.graal.python" / "src"),
336+
"--source-directory", str(Path(SUITE.dir) / "com.oracle.graal.python.pegparser" / "src"),
337+
"--source-directory", str(Path(SUITE.get_output_root()) / "com.oracle.graal.python" / "src_gen"),
338+
"--include", "com/oracle/graal/python",
339+
"--keep-going",
340+
"-o", "lcov_html",
341+
str(lcov_path),
342+
], nonZeroIsFatal=False)
313343

314344
if not os.path.isfile(iprof_path):
315345
mx.abort(f"[PGO] Could not find profile file at expected location: {iprof_path}")
316346

317-
with set_env(GRAALPY_PGO_PROFILE=iprof_path):
347+
with set_env(GRAALPY_PGO_PROFILE=str(iprof_path)):
318348
mx.log(mx.colorize("[PGO] Building optimized native image with collected profile", color="yellow"))
319349
native_bin = graalpy_standalone('native', enterprise=True, build=True)
320350

@@ -717,9 +747,12 @@ def graalpy_standalone_home(standalone_type, enterprise=False, dev=False, build=
717747
mx.abort("PGO is only supported on enterprise NI")
718748
if pgo_profile:
719749
mx_args.append(f"--extra-image-builder-argument=--pgo={pgo_profile}")
750+
mx_args.append(f"--extra-image-builder-argument=-H:+UnlockExperimentalVMOptions")
720751
mx_args.append(f"--extra-image-builder-argument=-H:+PGOPrintProfileQuality")
721752
else:
722753
mx_args.append(f"--extra-image-builder-argument=--pgo-instrument")
754+
mx_args.append(f"--extra-image-builder-argument=-H:+UnlockExperimentalVMOptions")
755+
mx_args.append(f"--extra-image-builder-argument=-H:+ProfilingLCOV")
723756

724757
if mx_gate.get_jacoco_agent_args() or (build and not DISABLE_REBUILD):
725758
mx_build_args = mx_args

mx.graalpython/mx_graalpython_benchmark.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,10 @@ def launcher_type(self):
279279
@property
280280
@functools.lru_cache
281281
def interpreter(self):
282+
if home := mx.get_env("GRAALPY_HOME"):
283+
launcher = join(home, "bin", "graalpy")
284+
mx.log(f"Using {launcher} based on GRAALPY_HOME environment variable.")
285+
return launcher
282286
from mx_graalpython import graalpy_standalone
283287
launcher = graalpy_standalone(self.launcher_type, build=False)
284288
mx.log(f"Using {launcher} based on enabled/excluded GraalPy standalone build targets.")

0 commit comments

Comments
 (0)