Skip to content

Commit 31dacac

Browse files
author
Andrija Kolic
committed
Implement staging the main harness loop of PolyBenchLauncher into Python.
1 parent 9cd6174 commit 31dacac

21 files changed

+2055
-76
lines changed

sdk/mx.sdk/mx_sdk_benchmark.py

Lines changed: 239 additions & 54 deletions
Large diffs are not rendered by default.

truffle/mx.truffle/mx_polybench/model.py

Lines changed: 40 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -492,7 +492,7 @@ def __init__(
492492
else:
493493
self._native_mode: bool = suite.is_native_mode(bmSuiteArgs)
494494
self._post_processors: List[DataPointsPostProcessor] = suite._get_post_processors(
495-
self.benchmark, self._native_mode
495+
self.benchmark, self._native_mode, self.bmSuiteArgs
496496
)
497497

498498
@property
@@ -526,6 +526,11 @@ def run(self, benchmarks, bmSuiteArgs) -> DataPoints:
526526
self._image_cache.add(self._current_image)
527527
return datapoints
528528

529+
def use_stage_aware_benchmark_mixin_intercept_run(self):
530+
if self.jvm(self.execution_context.bmSuiteArgs) == "cpython":
531+
return True
532+
return False
533+
529534
def _resolve_current_benchmark(self, benchmarks) -> ResolvedPolybenchBenchmark:
530535
if benchmarks is None or len(benchmarks) != 1:
531536
mx.abort(f"Must specify one benchmark at a time (given: {benchmarks})")
@@ -575,6 +580,9 @@ def _set_image_context(self, resolved_benchmark: ResolvedPolybenchBenchmark, bm_
575580

576581
def _base_image_name(self) -> Optional[str]:
577582
"""Overrides the image name used to build/run the image."""
583+
if self.jvm(self.execution_context.bmSuiteArgs) == "cpython":
584+
benchmark_sanitized = self.execution_context.benchmark.replace("/", "-").replace(".", "-")
585+
return f"{benchmark_sanitized}-staged-benchmark"
578586
assert self._current_image, "Image should have been set already"
579587
return self._current_image.full_executable_name()
580588

@@ -659,6 +667,9 @@ def _infer_host_vm_config(self, bm_suite_args, dims):
659667
return existing_config
660668
return dims["host-vm-config"] + "-" + edition
661669
else:
670+
non_graal_vms = ["cpython"]
671+
if self.jvm(bm_suite_args) in non_graal_vms:
672+
return self.jvmConfig(bm_suite_args)
662673
# assume config used when building a GraalVM distribution
663674
return "graal-enterprise-libgraal-pgo" if edition == "ee" else "graal-core-libgraal"
664675

@@ -847,11 +858,11 @@ def process_datapoints(self, datapoints: DataPoints) -> DataPoints:
847858
fork_info = self._suite.execution_context.fork_info
848859
# When running non-native benchmarks there is no concept of stages, there is only a single bench suite run.
849860
# So we store a pretend "run" stage to indicate that all datapoints (for this fork) have already been produced.
850-
current_stage = (
851-
Stage.from_string("run")
852-
if not self._suite.execution_context.native_mode
853-
else self._suite.stages_info.current_stage
854-
)
861+
current_stage = Stage.from_string("run")
862+
try:
863+
current_stage = self._suite.stages_info.current_stage
864+
except AttributeError:
865+
pass
855866
# Preserve this fork-stage's datapoints for eventual post-processing.
856867
self._fork_stage_datapoints[(fork_info.current_fork_index, current_stage)] = datapoints
857868
if (
@@ -959,20 +970,40 @@ def update_fn(dp):
959970
)
960971
super().__init__(suite, selector_fn, key_fn, field, update_fn, lower_percentile, upper_percentile)
961972

973+
class GraalSpecificFieldsRemoverPostProcessor(DataPointsPostProcessor):
974+
"""
975+
Removes all platform Graal specific fields from all the datapoints.
976+
Used for cleaning up the bench results of a benchmark that runs on
977+
a different platform (e.g. CPython).
978+
The removed fields include:
979+
* The "guest-vm" and "guest-vm-config" fields.
980+
* All the "platform.*" fields.
981+
"""
982+
983+
def process_datapoints(self, datapoints: DataPoints) -> DataPoints:
984+
return [{k: v for k, v in dp.items() if self._should_be_kept(k)} for dp in datapoints]
985+
986+
def _should_be_kept(self, key) -> bool:
987+
return key not in ["guest-vm", "guest-vm-config"] and not key.startswith("platform.")
988+
962989
def post_processors(self) -> List[DataPointsPostProcessor]:
963990
return self.execution_context.post_processors
964991

965-
def _get_post_processors(self, benchmark: str, native_mode: bool):
992+
def _get_post_processors(self, benchmark: str, native_mode: bool, bm_suite_args: List[str]):
993+
post_processors = []
994+
if self.jvm(bm_suite_args) == "cpython":
995+
post_processors += [PolybenchBenchmarkSuite.GraalSpecificFieldsRemoverPostProcessor()]
966996
if native_mode:
967-
return [
997+
post_processors += [
968998
PolybenchBenchmarkSuite.NativeModeBenchmarkRenamingPostProcessor(self),
969999
PolybenchBenchmarkSuite.NativeModeBuildSummaryPostProcessor(self, benchmark),
9701000
PolybenchBenchmarkSuite.NativeModeBenchmarkSummaryPostProcessor(self, benchmark),
9711001
]
9721002
else:
973-
return [
1003+
post_processors += [
9741004
PolybenchBenchmarkSuite.ServerModeBenchmarkSummaryPostProcessor(self, benchmark),
9751005
]
1006+
return post_processors
9761007

9771008
@staticmethod
9781009
def _get_metric_name(bench_output) -> Optional[str]:

truffle/src/org.graalvm.polybench/src/org/graalvm/polybench/AverageSummary.java

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,29 @@
2424
*/
2525
package org.graalvm.polybench;
2626

27+
import org.graalvm.polybench.ast.Decl.Compound;
28+
import org.graalvm.polybench.ast.Decl.Subroutine;
29+
import org.graalvm.polybench.ast.Decl.Variable;
30+
import org.graalvm.polybench.ast.Expr.Atom.Int;
31+
import org.graalvm.polybench.ast.Expr.Atom.Null;
32+
import org.graalvm.polybench.ast.Expr.BinaryOp;
33+
import org.graalvm.polybench.ast.Expr.ConstructorCall;
34+
import org.graalvm.polybench.ast.Expr.ListLengthCall;
35+
import org.graalvm.polybench.ast.Expr.Reference.Ident;
36+
import org.graalvm.polybench.ast.Operator;
37+
import org.graalvm.polybench.ast.Stat;
38+
import org.graalvm.polybench.ast.Stat.Assign;
39+
import org.graalvm.polybench.ast.Stat.Block;
40+
import org.graalvm.polybench.ast.Stat.Return;
41+
import org.graalvm.polybench.ast.Tree.Program.Builder;
42+
2743
import java.util.Optional;
2844

2945
/**
3046
* Summarizes the results of a polybench benchmark with an average value computed from iteration
3147
* datapoints.
3248
*/
33-
class AverageSummary implements Summary {
49+
class AverageSummary implements Summary, StageableClass {
3450
@Override
3551
public Optional<Double> postprocess(double[] results) {
3652
double sum = 0;
@@ -44,4 +60,43 @@ public Optional<Double> postprocess(double[] results) {
4460
public String toString() {
4561
return "AverageSummary{}";
4662
}
63+
64+
@Override
65+
public boolean stageClass(Builder programBuilder) {
66+
Stat thenBranch;
67+
Stat elseBranch;
68+
try (Compound.Builder classBuilder = new Compound.Builder(programBuilder, "AverageSummary", null)) {
69+
try (Subroutine.Builder methodBuilder = new Subroutine.Builder(classBuilder, "postprocess", new Variable[]{Variable.of("results")})) {
70+
methodBuilder.append(Variable.of("sum", new Int(0)));
71+
try (Stat.Foreach.Builder foreachBuilder = new Stat.Foreach.Builder(methodBuilder, Variable.of("result"), new Ident("results"))) {
72+
foreachBuilder.append(new Assign(new Ident("sum"),
73+
new BinaryOp(new Ident("sum"), new Ident("result"), Operator.PLUS)));
74+
}
75+
methodBuilder.append(Variable.of("resultsLength", new ListLengthCall(new Ident("results"))));
76+
// if (resultsLength > 0)
77+
try (Block.Builder thenBranchBuilder = new Block.Builder(null)) {
78+
thenBranchBuilder.append(new Return(new BinaryOp(new Ident("sum"), new Ident("resultsLength"), Operator.DIV)));
79+
thenBranch = thenBranchBuilder.build();
80+
}
81+
try (Block.Builder elseBranchBuilder = new Block.Builder(null)) {
82+
elseBranchBuilder.append(new Return(new Null()));
83+
elseBranch = elseBranchBuilder.build();
84+
}
85+
methodBuilder.append(new Stat.If(new BinaryOp(new Ident("resultsLength"), new Int(0), Operator.GREATER_THAN), thenBranch, elseBranch));
86+
}
87+
return true;
88+
} catch (UnsupportedOperationException e) {
89+
return false;
90+
}
91+
}
92+
93+
@Override
94+
public boolean stageSingletonInitialization(Builder programBuilder, String singleton) {
95+
try {
96+
programBuilder.append(Variable.of(singleton, ConstructorCall.of(new Ident("AverageSummary"))));
97+
return true;
98+
} catch (UnsupportedOperationException e) {
99+
return false;
100+
}
101+
}
47102
}

truffle/src/org.graalvm.polybench/src/org/graalvm/polybench/Config.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -46,12 +46,16 @@ public class Config {
4646
Metric metric;
4747
boolean evalSourceOnlyDefault;
4848
Summary summary;
49+
Language stagingLanguage;
50+
String stagingFilePath;
51+
boolean logStagedProgram;
52+
String stagedProgramLauncher;
4953

5054
final List<String> unrecognizedArguments = new ArrayList<>();
5155

5256
private static final int UNINITIALIZED_ITERATIONS = -1;
53-
private static final int DEFAULT_WARMUP = 20;
54-
private static final int DEFAULT_ITERATIONS = 30;
57+
public static final int DEFAULT_WARMUP = 20;
58+
public static final int DEFAULT_ITERATIONS = 30;
5559

5660
/**
5761
* Multi-context runs related configuration.
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation. Oracle designates this
8+
* particular file as subject to the "Classpath" exception as provided
9+
* by Oracle in the LICENSE file that accompanied this code.
10+
*
11+
* This code is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* version 2 for more details (a copy is included in the LICENSE file that
15+
* accompanied this code).
16+
*
17+
* You should have received a copy of the GNU General Public License version
18+
* 2 along with this work; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
24+
*/
25+
package org.graalvm.polybench;
26+
27+
enum Language {
28+
PYTHON
29+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation. Oracle designates this
8+
* particular file as subject to the "Classpath" exception as provided
9+
* by Oracle in the LICENSE file that accompanied this code.
10+
*
11+
* This code is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* version 2 for more details (a copy is included in the LICENSE file that
15+
* accompanied this code).
16+
*
17+
* You should have received a copy of the GNU General Public License version
18+
* 2 along with this work; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
24+
*/
25+
package org.graalvm.polybench;
26+
27+
import org.graalvm.polybench.ast.Tree.Program;
28+
29+
import java.io.IOException;
30+
31+
/**
32+
* Generates a program in the target language from an AST.
33+
*/
34+
public interface LanguageGenerator {
35+
byte[] generate(Program program) throws IOException;
36+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*
2+
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation. Oracle designates this
8+
* particular file as subject to the "Classpath" exception as provided
9+
* by Oracle in the LICENSE file that accompanied this code.
10+
*
11+
* This code is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* version 2 for more details (a copy is included in the LICENSE file that
15+
* accompanied this code).
16+
*
17+
* You should have received a copy of the GNU General Public License version
18+
* 2 along with this work; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
24+
*/
25+
package org.graalvm.polybench;
26+
27+
class LanguageGeneratorFactory {
28+
public static LanguageGenerator getLanguageGenerator(Language language) {
29+
return switch (language) {
30+
case PYTHON -> new PythonGenerator();
31+
};
32+
}
33+
}

truffle/src/org.graalvm.polybench/src/org/graalvm/polybench/Metric.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,5 +132,4 @@ public Optional<Double> reportAfterAll() {
132132

133133
public void reset() {
134134
}
135-
136135
}

0 commit comments

Comments
 (0)