blob: 436c046819c155bf6fb098c818fefee7122b67e9 [file] [log] [blame]
#!/usr/bin/env python3
# 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.
import argparse
import os
import subprocess
import sys
import compiledump
import gradle
import jdk
import utils
GOLEM_BUILD_TARGETS_TESTS = [
utils.GRADLE_TASK_ALL_TESTS_WITH_APPLY_MAPPING_JAR,
utils.GRADLE_TASK_TESTBASE_WITH_APPLY_MAPPING_JAR,
utils.GRADLE_TASK_TEST_DEPS_JAR
]
GOLEM_BUILD_TARGETS = [
utils.GRADLE_TASK_R8LIB, utils.GRADLE_TASK_KEEP_ANNO_JAR
] + GOLEM_BUILD_TARGETS_TESTS
def get_golem_resource_path(benchmark):
return os.path.join('benchmarks', benchmark)
def get_jdk_home(options, benchmark):
if options.golem:
return os.path.join(get_golem_resource_path(benchmark), 'linux')
return None
def parse_options(argv):
result = argparse.ArgumentParser(description='Run test-based benchmarks.')
result.add_argument('--golem',
help='Indicate this as a run on golem',
default=False,
action='store_true')
result.add_argument('--benchmark',
help='The test benchmark to run',
required=True)
result.add_argument(
'--target',
help='The test target to run',
required=True,
# These should 1:1 with benchmarks/BenchmarkTarget.java
choices=['d8', 'r8-full', 'r8-force', 'r8-compat', 'retrace'])
result.add_argument(
'--debug-agent',
'--debug_agent',
help=
'Enable Java debug agent and suspend compilation (default disabled)',
default=False,
action='store_true')
result.add_argument('--nolib',
'--no-lib',
'--no-r8lib',
help='Run the non-lib R8 build (default false)',
default=False,
action='store_true')
result.add_argument('--no-build',
'--no_build',
help='Run without building first (default false)',
default=False,
action='store_true')
result.add_argument('--enable-assertions',
'--enable_assertions',
'-ea',
help='Enable assertions when running',
default=False,
action='store_true')
result.add_argument('--iterations',
'-i',
help='Number of iterations to run',
type=int)
result.add_argument('--output',
help='Output path where to write the result')
result.add_argument('--print-times',
help='Print timing information from r8',
default=False,
action='store_true')
result.add_argument(
'--version',
'-v',
help='Use R8 version/hash for the run (default local build)',
default=None)
result.add_argument(
'--version-jar',
help='The r8.jar corresponding to the version given at --version.',
default=None)
result.add_argument('--temp',
help='A directory to use for temporaries and outputs.',
default=None)
result.add_argument('--verbose',
help='To enable verbose logging.',
action='store_true',
default=False)
options, args = result.parse_known_args(argv)
options.quiet = not options.verbose
# We must download the non-lib distribution when running with a specific
# version, since BenchmarkMainEntryRunner is using R8 internals.
# TODO(b/346477461): Look into removing this limitation.
assert options.version is None or options.nolib
return options, args
def main(argv, temp):
options, args = parse_options(argv)
if options.output:
options.output = os.path.abspath(options.output)
if options.temp:
temp = options.temp
os.makedirs(temp, exist_ok=True)
if options.golem:
options.no_build = True
if options.nolib:
print("Error: golem should always run r8lib")
return 1
if options.nolib:
testBuildTargets = [
utils.GRADLE_TASK_TEST_JAR, utils.GRADLE_TASK_TEST_DEPS_JAR,
utils.GRADLE_TASK_TEST_UNZIP_TESTBASE
]
buildTargets = [utils.GRADLE_TASK_R8, utils.GRADLE_TASK_KEEP_ANNO_JAR
] + testBuildTargets
r8jar = utils.R8_JAR
testjars = [
utils.R8_TESTS_JAR, utils.R8_TESTS_DEPS_JAR, utils.R8_TESTBASE_JAR
]
else:
testBuildTargets = GOLEM_BUILD_TARGETS_TESTS
buildTargets = GOLEM_BUILD_TARGETS
r8jar = utils.R8LIB_JAR
testjars = [
os.path.join(utils.R8LIB_TESTS_JAR),
os.path.join(utils.R8LIB_TESTS_DEPS_JAR),
os.path.join(utils.R8LIB_TESTBASE_JAR)
]
if options.version or options.version_jar:
# r8 is downloaded so only test jar needs to be built.
buildTargets = testBuildTargets
r8jar = options.version_jar or compiledump.download_distribution(
options.version, options, temp)
if not options.no_build:
gradle.RunGradle(buildTargets + ['-Pno_internal'])
if not options.golem:
# When running locally, change the working directory to be in 'temp'.
# This is hard to do properly within the JVM so we do it here.
with utils.ChangedWorkingDirectory(temp):
return run(options, r8jar, testjars)
else:
return run(options, r8jar, testjars)
def run(options, r8jar, testjars):
jdkhome = get_jdk_home(options, options.benchmark)
cmd = [
jdk.GetJavaExecutable(jdkhome),
'-Xms8g',
'-Xmx8g',
'-XX:+TieredCompilation',
'-XX:TieredStopAtLevel=4',
'-DBENCHMARK_IGNORE_CODE_SIZE_DIFFERENCES',
f'-DBUILD_PROP_KEEPANNO_RUNTIME_PATH={utils.REPO_ROOT}/d8_r8/keepanno/build/classes/java/main',
# Since we change the working directory to a temp folder.
f'-DREPO_ROOT={utils.REPO_ROOT}'
]
if options.enable_assertions:
cmd.append('-ea')
if options.print_times:
cmd.append('-Dcom.android.tools.r8.printtimes=1')
if not options.golem:
cmd.extend([
f'-DTEST_DATA_LOCATION={utils.REPO_ROOT}/d8_r8/test_modules/tests_java_8/build/classes/java/test',
f'-DTESTBASE_DATA_LOCATION={utils.REPO_ROOT}/d8_r8/test_modules/testbase/build/classes/java/main',
])
if options.iterations is not None:
if options.iterations == 0:
return
cmd.append(f'-DBENCHMARK_ITERATIONS={options.iterations}')
if options.output:
cmd.append(f'-DBENCHMARK_OUTPUT={options.output}')
cmd.extend(['-cp', ':'.join([r8jar] + testjars)])
if options.debug_agent:
cmd.append(
'-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=*:5005'
)
cmd.extend([
'com.android.tools.r8.benchmarks.BenchmarkMainEntryRunner',
options.benchmark,
options.target,
# When running locally the working directory is moved and we pass the
# repository root as an argument. The runner can then setup dependencies.
'golem' if options.golem else utils.REPO_ROOT,
])
utils.PrintCmd(cmd, quiet=options.quiet)
return subprocess.check_call(cmd)
if __name__ == '__main__':
with utils.TempDir() as temp:
sys.exit(main(sys.argv[1:], temp))