Add benchmarks for lunch
Test: ./benchmarks --benchmark full_lunch Change-Id: Id6be3b41a518d4ca9cad882a913f1dcc59f0d01a
This commit is contained in:
@@ -29,6 +29,7 @@ import shutil
|
|||||||
import subprocess
|
import subprocess
|
||||||
import time
|
import time
|
||||||
import uuid
|
import uuid
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
import pretty
|
import pretty
|
||||||
import utils
|
import utils
|
||||||
@@ -80,6 +81,33 @@ class Change:
|
|||||||
undo: callable
|
undo: callable
|
||||||
"Function to revert the source tree to its previous condition in the most minimal way possible."
|
"Function to revert the source tree to its previous condition in the most minimal way possible."
|
||||||
|
|
||||||
|
_DUMPVARS_VARS=[
|
||||||
|
"COMMON_LUNCH_CHOICES",
|
||||||
|
"HOST_PREBUILT_TAG",
|
||||||
|
"print",
|
||||||
|
"PRODUCT_OUT",
|
||||||
|
"report_config",
|
||||||
|
"TARGET_ARCH",
|
||||||
|
"TARGET_BUILD_VARIANT",
|
||||||
|
"TARGET_DEVICE",
|
||||||
|
"TARGET_PRODUCT",
|
||||||
|
]
|
||||||
|
|
||||||
|
_DUMPVARS_ABS_VARS =[
|
||||||
|
"ANDROID_CLANG_PREBUILTS",
|
||||||
|
"ANDROID_JAVA_HOME",
|
||||||
|
"ANDROID_JAVA_TOOLCHAIN",
|
||||||
|
"ANDROID_PREBUILTS",
|
||||||
|
"HOST_OUT",
|
||||||
|
"HOST_OUT_EXECUTABLES",
|
||||||
|
"HOST_OUT_TESTCASES",
|
||||||
|
"OUT_DIR",
|
||||||
|
"print",
|
||||||
|
"PRODUCT_OUT",
|
||||||
|
"SOONG_HOST_OUT",
|
||||||
|
"SOONG_HOST_OUT_EXECUTABLES",
|
||||||
|
"TARGET_OUT_TESTCASES",
|
||||||
|
]
|
||||||
|
|
||||||
@dataclasses.dataclass(frozen=True)
|
@dataclasses.dataclass(frozen=True)
|
||||||
class Benchmark:
|
class Benchmark:
|
||||||
@@ -94,15 +122,47 @@ class Benchmark:
|
|||||||
change: Change
|
change: Change
|
||||||
"Source tree modification for the benchmark that will be measured"
|
"Source tree modification for the benchmark that will be measured"
|
||||||
|
|
||||||
modules: list[str]
|
dumpvars: Optional[bool] = False
|
||||||
|
"If specified, soong will run in dumpvars mode rather than build-mode."
|
||||||
|
|
||||||
|
modules: Optional[list[str]] = None
|
||||||
"Build modules to build on soong command line"
|
"Build modules to build on soong command line"
|
||||||
|
|
||||||
preroll: int
|
preroll: Optional[int] = 0
|
||||||
"Number of times to run the build command to stabilize"
|
"Number of times to run the build command to stabilize"
|
||||||
|
|
||||||
postroll: int
|
postroll: Optional[int] = 3
|
||||||
"Number of times to run the build command after reverting the action to stabilize"
|
"Number of times to run the build command after reverting the action to stabilize"
|
||||||
|
|
||||||
|
def build_description(self):
|
||||||
|
"Short description of the benchmark's Soong invocation."
|
||||||
|
if self.dumpvars:
|
||||||
|
return "dumpvars"
|
||||||
|
elif self.modules:
|
||||||
|
return " ".join(self.modules)
|
||||||
|
return ""
|
||||||
|
|
||||||
|
|
||||||
|
def soong_command(self, root):
|
||||||
|
"Command line args to soong_ui for this benchmark."
|
||||||
|
if self.dumpvars:
|
||||||
|
return [
|
||||||
|
"--dumpvars-mode",
|
||||||
|
f"--vars=\"{' '.join(_DUMPVARS_VARS)}\"",
|
||||||
|
f"--abs-vars=\"{' '.join(_DUMPVARS_ABS_VARS)}\"",
|
||||||
|
"--var-prefix=var_cache_",
|
||||||
|
"--abs-var-prefix=abs_var_cache_",
|
||||||
|
]
|
||||||
|
elif self.modules:
|
||||||
|
return [
|
||||||
|
"--build-mode",
|
||||||
|
"--all-modules",
|
||||||
|
f"--dir={root}",
|
||||||
|
"--skip-metrics-upload",
|
||||||
|
] + self.modules
|
||||||
|
else:
|
||||||
|
raise Exception("Benchmark must specify dumpvars or modules")
|
||||||
|
|
||||||
|
|
||||||
@dataclasses.dataclass(frozen=True)
|
@dataclasses.dataclass(frozen=True)
|
||||||
class FileSnapshot:
|
class FileSnapshot:
|
||||||
@@ -242,6 +302,7 @@ class BenchmarkReport():
|
|||||||
"id": self.benchmark.id,
|
"id": self.benchmark.id,
|
||||||
"title": self.benchmark.title,
|
"title": self.benchmark.title,
|
||||||
"modules": self.benchmark.modules,
|
"modules": self.benchmark.modules,
|
||||||
|
"dumpvars": self.benchmark.dumpvars,
|
||||||
"change": self.benchmark.change.label,
|
"change": self.benchmark.change.label,
|
||||||
"iteration": self.iteration,
|
"iteration": self.iteration,
|
||||||
"log_dir": self.log_dir,
|
"log_dir": self.log_dir,
|
||||||
@@ -290,7 +351,7 @@ class Runner():
|
|||||||
|
|
||||||
# Preroll builds
|
# Preroll builds
|
||||||
for i in range(benchmark.preroll):
|
for i in range(benchmark.preroll):
|
||||||
ns = self._run_build(lunch, benchmark_log_dir.joinpath(f"pre_{i}"), benchmark.modules)
|
ns = self._run_build(lunch, benchmark_log_dir.joinpath(f"pre_{i}"), benchmark)
|
||||||
report.preroll_duration_ns.append(ns)
|
report.preroll_duration_ns.append(ns)
|
||||||
|
|
||||||
sys.stderr.write(f"PERFORMING CHANGE: {benchmark.change.label}\n")
|
sys.stderr.write(f"PERFORMING CHANGE: {benchmark.change.label}\n")
|
||||||
@@ -299,18 +360,18 @@ class Runner():
|
|||||||
try:
|
try:
|
||||||
|
|
||||||
# Measured build
|
# Measured build
|
||||||
ns = self._run_build(lunch, benchmark_log_dir.joinpath("measured"), benchmark.modules)
|
ns = self._run_build(lunch, benchmark_log_dir.joinpath("measured"), benchmark)
|
||||||
report.duration_ns = ns
|
report.duration_ns = ns
|
||||||
|
|
||||||
dist_one = self._options.DistOne()
|
dist_one = self._options.DistOne()
|
||||||
if dist_one:
|
if dist_one:
|
||||||
# If we're disting just one benchmark, save the logs and we can stop here.
|
# If we're disting just one benchmark, save the logs and we can stop here.
|
||||||
self._dist(utils.get_dist_dir())
|
self._dist(utils.get_dist_dir(), benchmark.dumpvars)
|
||||||
else:
|
else:
|
||||||
# Postroll builds
|
# Postroll builds
|
||||||
for i in range(benchmark.postroll):
|
for i in range(benchmark.postroll):
|
||||||
ns = self._run_build(lunch, benchmark_log_dir.joinpath(f"post_{i}"),
|
ns = self._run_build(lunch, benchmark_log_dir.joinpath(f"post_{i}"),
|
||||||
benchmark.modules)
|
benchmark)
|
||||||
report.postroll_duration_ns.append(ns)
|
report.postroll_duration_ns.append(ns)
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
@@ -329,21 +390,17 @@ class Runner():
|
|||||||
path += ("/%0" + str(len(str(self._options.Iterations()))) + "d") % iteration
|
path += ("/%0" + str(len(str(self._options.Iterations()))) + "d") % iteration
|
||||||
return path
|
return path
|
||||||
|
|
||||||
def _run_build(self, lunch, build_log_dir, modules):
|
def _run_build(self, lunch, build_log_dir, benchmark):
|
||||||
"""Builds the modules. Saves interesting log files to log_dir. Raises FatalError
|
"""Builds the modules. Saves interesting log files to log_dir. Raises FatalError
|
||||||
if the build fails.
|
if the build fails.
|
||||||
"""
|
"""
|
||||||
sys.stderr.write(f"STARTING BUILD {modules}\n")
|
sys.stderr.write(f"STARTING BUILD {benchmark.build_description()}\n")
|
||||||
|
|
||||||
before_ns = time.perf_counter_ns()
|
before_ns = time.perf_counter_ns()
|
||||||
if not self._options.DryRun():
|
if not self._options.DryRun():
|
||||||
cmd = [
|
cmd = [
|
||||||
"build/soong/soong_ui.bash",
|
"build/soong/soong_ui.bash",
|
||||||
"--build-mode",
|
] + benchmark.soong_command(self._options.root)
|
||||||
"--all-modules",
|
|
||||||
f"--dir={self._options.root}",
|
|
||||||
"--skip-metrics-upload",
|
|
||||||
] + modules
|
|
||||||
env = dict(os.environ)
|
env = dict(os.environ)
|
||||||
env["TARGET_PRODUCT"] = lunch.target_product
|
env["TARGET_PRODUCT"] = lunch.target_product
|
||||||
env["TARGET_RELEASE"] = lunch.target_release
|
env["TARGET_RELEASE"] = lunch.target_release
|
||||||
@@ -357,11 +414,11 @@ class Runner():
|
|||||||
|
|
||||||
# TODO: Copy some log files.
|
# TODO: Copy some log files.
|
||||||
|
|
||||||
sys.stderr.write(f"FINISHED BUILD {modules}\n")
|
sys.stderr.write(f"FINISHED BUILD {benchmark.build_description()}\n")
|
||||||
|
|
||||||
return after_ns - before_ns
|
return after_ns - before_ns
|
||||||
|
|
||||||
def _dist(self, dist_dir):
|
def _dist(self, dist_dir, dumpvars):
|
||||||
out_dir = utils.get_out_dir()
|
out_dir = utils.get_out_dir()
|
||||||
dest_dir = dist_dir.joinpath("logs")
|
dest_dir = dist_dir.joinpath("logs")
|
||||||
os.makedirs(dest_dir, exist_ok=True)
|
os.makedirs(dest_dir, exist_ok=True)
|
||||||
@@ -371,6 +428,8 @@ class Runner():
|
|||||||
"soong_build_metrics.pb",
|
"soong_build_metrics.pb",
|
||||||
"soong_metrics",
|
"soong_metrics",
|
||||||
]
|
]
|
||||||
|
if dumpvars:
|
||||||
|
basenames = ['dumpvars-'+b for b in basenames]
|
||||||
for base in basenames:
|
for base in basenames:
|
||||||
src = out_dir.joinpath(base)
|
src = out_dir.joinpath(base)
|
||||||
if src.exists():
|
if src.exists():
|
||||||
@@ -393,7 +452,7 @@ class Runner():
|
|||||||
|
|
||||||
def benchmark_table(benchmarks):
|
def benchmark_table(benchmarks):
|
||||||
rows = [("ID", "DESCRIPTION", "REBUILD"),]
|
rows = [("ID", "DESCRIPTION", "REBUILD"),]
|
||||||
rows += [(benchmark.id, benchmark.title, " ".join(benchmark.modules)) for benchmark in
|
rows += [(benchmark.id, benchmark.title, benchmark.build_description()) for benchmark in
|
||||||
benchmarks]
|
benchmarks]
|
||||||
return rows
|
return rows
|
||||||
|
|
||||||
@@ -577,6 +636,22 @@ benchmarks:
|
|||||||
"""Initialize the list of benchmarks."""
|
"""Initialize the list of benchmarks."""
|
||||||
# Assumes that we've already chdired to the root of the tree.
|
# Assumes that we've already chdired to the root of the tree.
|
||||||
self._benchmarks = [
|
self._benchmarks = [
|
||||||
|
Benchmark(
|
||||||
|
id="full_lunch",
|
||||||
|
title="Lunch from clean out",
|
||||||
|
change=Clean(),
|
||||||
|
dumpvars=True,
|
||||||
|
preroll=0,
|
||||||
|
postroll=0,
|
||||||
|
),
|
||||||
|
Benchmark(
|
||||||
|
id="noop_lunch",
|
||||||
|
title="Lunch with no change",
|
||||||
|
change=NoChange(),
|
||||||
|
dumpvars=True,
|
||||||
|
preroll=1,
|
||||||
|
postroll=0,
|
||||||
|
),
|
||||||
Benchmark(id="full",
|
Benchmark(id="full",
|
||||||
title="Full build",
|
title="Full build",
|
||||||
change=Clean(),
|
change=Clean(),
|
||||||
|
Reference in New Issue
Block a user