Add support for benchmark timeout.
Bug: b/221813759
Change-Id: I2dcf113bcbe61e9b6efac98cf64bfbc7cb5815a0
diff --git a/src/test/java/com/android/tools/r8/benchmarks/BenchmarkCollectionPrinter.java b/src/test/java/com/android/tools/r8/benchmarks/BenchmarkCollectionPrinter.java
index 6111c7e..c7336f7 100644
--- a/src/test/java/com/android/tools/r8/benchmarks/BenchmarkCollectionPrinter.java
+++ b/src/test/java/com/android/tools/r8/benchmarks/BenchmarkCollectionPrinter.java
@@ -118,6 +118,11 @@
printSemi("final name = " + quote(benchmarkName));
printSemi("final metrics = " + StringUtils.join(", ", metrics, BraceType.SQUARE));
printSemi("final benchmark = StandardBenchmark(name, metrics)");
+ BenchmarkTimeout timeout = BenchmarkConfig.getCommonTimeout(benchmarkVariants);
+ if (timeout != null) {
+ printSemi("final timeout = const Duration(seconds: " + timeout.asSeconds() + ")");
+ printSemi("ExecutionManagement.addTimeoutConstraint(timeout, benchmark: benchmark)");
+ }
for (BenchmarkConfig benchmark : benchmarkVariants) {
scopeBraces(
() -> {
@@ -141,8 +146,9 @@
for (BenchmarkDependency dependency : benchmark.getDependencies()) {
scopeBraces(
() -> {
- addGolemResource(dependency.getName(), dependency.getTarball());
- printSemi("options.resources.add(dependency)");
+ String dependencyName = dependency.getName();
+ addGolemResource(dependencyName, dependency.getTarball());
+ printSemi("options.resources.add(" + dependencyName + ")");
});
}
});
diff --git a/src/test/java/com/android/tools/r8/benchmarks/BenchmarkConfig.java b/src/test/java/com/android/tools/r8/benchmarks/BenchmarkConfig.java
index 596fc05..56ea759 100644
--- a/src/test/java/com/android/tools/r8/benchmarks/BenchmarkConfig.java
+++ b/src/test/java/com/android/tools/r8/benchmarks/BenchmarkConfig.java
@@ -10,6 +10,7 @@
import java.util.HashSet;
import java.util.List;
import java.util.Set;
+import java.util.concurrent.TimeUnit;
public class BenchmarkConfig {
@@ -39,6 +40,20 @@
return getConsistentRepresentative(variants).getSuite();
}
+ // Use the largest configured timeout as the timeout for the full group.
+ public static BenchmarkTimeout getCommonTimeout(List<BenchmarkConfig> variants) {
+ BenchmarkTimeout timeout = null;
+ for (BenchmarkConfig variant : variants) {
+ BenchmarkTimeout variantTimeout = variant.getTimeout();
+ if (timeout == null) {
+ timeout = variantTimeout;
+ } else if (variantTimeout != null && timeout.asSeconds() < variantTimeout.asSeconds()) {
+ timeout = variantTimeout;
+ }
+ }
+ return timeout;
+ }
+
private static BenchmarkConfig getConsistentRepresentative(List<BenchmarkConfig> variants) {
if (variants.isEmpty()) {
throw new BenchmarkConfigError("Unexpected attempt to check consistency of empty collection");
@@ -59,6 +74,7 @@
private BenchmarkSuite suite = BenchmarkSuite.getDefault();
private Collection<BenchmarkDependency> dependencies = new ArrayList<>();
private int fromRevision = -1;
+ private BenchmarkTimeout timeout = null;
private Builder() {}
@@ -88,7 +104,8 @@
ImmutableSet.copyOf(metrics),
suite,
fromRevision,
- dependencies);
+ dependencies,
+ timeout);
}
public Builder setName(String name) {
@@ -135,6 +152,11 @@
dependencies.add(dependency);
return this;
}
+
+ public Builder setTimeout(long duration, TimeUnit unit) {
+ timeout = new BenchmarkTimeout(duration, unit);
+ return this;
+ }
}
public static Builder builder() {
@@ -147,6 +169,7 @@
private final BenchmarkSuite suite;
private final Collection<BenchmarkDependency> dependencies;
private final int fromRevision;
+ private final BenchmarkTimeout timeout;
private BenchmarkConfig(
String name,
@@ -155,13 +178,15 @@
ImmutableSet<BenchmarkMetric> metrics,
BenchmarkSuite suite,
int fromRevision,
- Collection<BenchmarkDependency> dependencies) {
+ Collection<BenchmarkDependency> dependencies,
+ BenchmarkTimeout timeout) {
this.id = new BenchmarkIdentifier(name, target);
this.method = benchmarkMethod;
this.metrics = metrics;
this.suite = suite;
this.fromRevision = fromRevision;
this.dependencies = dependencies;
+ this.timeout = timeout;
}
public BenchmarkIdentifier getIdentifier() {
@@ -204,6 +229,10 @@
return dependencies;
}
+ public BenchmarkTimeout getTimeout() {
+ return timeout;
+ }
+
public void run(BenchmarkEnvironment environment) throws Exception {
method.run(environment);
}
diff --git a/src/test/java/com/android/tools/r8/benchmarks/BenchmarkTimeout.java b/src/test/java/com/android/tools/r8/benchmarks/BenchmarkTimeout.java
new file mode 100644
index 0000000..37ad175
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/benchmarks/BenchmarkTimeout.java
@@ -0,0 +1,24 @@
+// Copyright (c) 2022, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+package com.android.tools.r8.benchmarks;
+
+import java.util.concurrent.TimeUnit;
+
+public class BenchmarkTimeout {
+
+ public final long duration;
+ public final TimeUnit unit;
+
+ public BenchmarkTimeout(long duration, TimeUnit unit) {
+ this.duration = duration;
+ this.unit = unit;
+ if (asSeconds() == 0) {
+ throw new BenchmarkConfigError("Benchmark timeout must be at least one second.");
+ }
+ }
+
+ public long asSeconds() {
+ return TimeUnit.SECONDS.convert(duration, unit);
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/benchmarks/appdumps/AppDumpBenchmarkBuilder.java b/src/test/java/com/android/tools/r8/benchmarks/appdumps/AppDumpBenchmarkBuilder.java
index b2a6fe0..683d4f5 100644
--- a/src/test/java/com/android/tools/r8/benchmarks/appdumps/AppDumpBenchmarkBuilder.java
+++ b/src/test/java/com/android/tools/r8/benchmarks/appdumps/AppDumpBenchmarkBuilder.java
@@ -17,6 +17,7 @@
import com.android.tools.r8.dump.DumpOptions;
import java.io.IOException;
import java.nio.file.Path;
+import java.util.concurrent.TimeUnit;
public class AppDumpBenchmarkBuilder {
@@ -74,6 +75,7 @@
.addDependency(dumpDependency)
.measureRunTime()
.measureCodeSize()
+ .setTimeout(10, TimeUnit.MINUTES)
.build();
}