Rico Wind | 9d70f61 | 2018-08-31 09:17:43 +0200 | [diff] [blame] | 1 | #!/usr/bin/env python |
| 2 | # Copyright (c) 2018, the R8 project authors. Please see the AUTHORS file |
| 3 | # for details. All rights reserved. Use of this source code is governed by a |
| 4 | # BSD-style license that can be found in the LICENSE file. |
| 5 | |
| 6 | # Script for running kotlin based benchmarks |
| 7 | |
| 8 | import optparse |
| 9 | import os |
| 10 | import subprocess |
| 11 | import sys |
| 12 | import toolhelper |
| 13 | import utils |
| 14 | |
| 15 | |
| 16 | BENCHMARK_ROOT = os.path.join(utils.REPO_ROOT, 'third_party', 'benchmarks', |
| 17 | 'kotlin-benches') |
| 18 | |
| 19 | BENCHMARK_PATTERN = '{benchmark}/kotlin/perf/build/libs/perf-1.0-BENCH.jar' |
| 20 | BENCHMARK_MAIN_CLASS = 'com.android.kt.bms.cli.Runner' |
| 21 | ART = os.path.join(utils.TOOLS_DIR, 'linux', 'art', 'bin', 'art') |
| 22 | |
| 23 | PROGUARD_CONF = """ |
| 24 | # From Android rules |
| 25 | -keepclasseswithmembers public class * { |
| 26 | public static void main(java.lang.String[]); |
| 27 | } |
| 28 | # Disable obfuscation to only focus on shrinking |
| 29 | -dontobfuscate |
| 30 | # Once we're ready for optimization, we might want to relax access modifiers. |
| 31 | -allowaccessmodification |
| 32 | """ |
| 33 | |
| 34 | DEVICE_TEMP='/data/local/temp/bench' |
| 35 | |
| 36 | |
| 37 | def parse_options(): |
| 38 | result = optparse.OptionParser() |
| 39 | result.add_option('--api', |
| 40 | help='Android api level', |
| 41 | default='26', |
| 42 | choices=['21', '22', '23', '24', '25', '26']) |
| 43 | result.add_option('--benchmark', |
| 44 | help='The benchmark to run', |
| 45 | default='rgx', |
| 46 | choices=['rgx', 'deltablue', 'sta', 'empty']) |
| 47 | result.add_option('--no-build', |
| 48 | help='Don\'t build r8', |
| 49 | default=False, action='store_true') |
| 50 | result.add_option('--use-device', |
| 51 | help='Run the benchmark on an attaced device', |
| 52 | default=False, action='store_true') |
| 53 | return result.parse_args() |
| 54 | |
| 55 | |
| 56 | def get_jar_for_benchmark(benchmark): |
| 57 | return os.path.join(BENCHMARK_ROOT, |
| 58 | BENCHMARK_PATTERN.format(benchmark=benchmark)) |
| 59 | |
| 60 | def run_art(dex): |
| 61 | command = ['bash', ART, '-cp', dex, BENCHMARK_MAIN_CLASS] |
| 62 | utils.PrintCmd(command) |
| 63 | benchmark_output = subprocess.check_output(command) |
| 64 | return get_result(benchmark_output) |
| 65 | |
| 66 | def adb(args): |
| 67 | command = ['adb'] + args |
| 68 | utils.PrintCmd(command) |
| 69 | return subprocess.check_output(['adb'] + args) |
| 70 | |
| 71 | def get_result(output): |
| 72 | # There is a lot of debug output, with the actual results being in the line with: |
| 73 | # RESULTS,KtBench,KtBench,15719 |
| 74 | # structure. |
| 75 | for result in [s for s in output.splitlines() if s.startswith('RESULTS')]: |
| 76 | return s.split('RESULTS,KtBench,KtBench,')[1] |
| 77 | |
| 78 | def run_art_device(dex): |
| 79 | adb(['wait-for-device', 'root']) |
| 80 | device_dst = os.path.join(DEVICE_TEMP, os.path.basename(dex)) |
| 81 | adb(['push', dex, device_dst]) |
| 82 | benchmark_output = adb(['shell', 'dalvikvm', '-cp', device_dst, BENCHMARK_MAIN_CLASS]) |
| 83 | return get_result(benchmark_output) |
| 84 | |
| 85 | def Main(): |
| 86 | (options, args) = parse_options() |
| 87 | temp = '/tmp/output' |
| 88 | dex_path = os.path.join(temp, "classes.jar") |
| 89 | proguard_conf = os.path.join(temp, 'proguard.conf') |
| 90 | with open(proguard_conf, 'w') as f: |
| 91 | f.write(PROGUARD_CONF) |
| 92 | benchmark_jar = get_jar_for_benchmark(options.benchmark) |
| 93 | r8_args = [ |
| 94 | '--lib', utils.get_android_jar(26), # Only works with api 26 |
| 95 | '--output', dex_path, |
| 96 | '--pg-conf', proguard_conf, |
| 97 | '--min-api', str(options.api), |
| 98 | benchmark_jar |
| 99 | ] |
| 100 | toolhelper.run('r8', r8_args, build=not options.no_build) |
| 101 | if options.use_device: |
| 102 | result = run_art_device(dex_path) |
| 103 | else: |
| 104 | result = run_art(dex_path) |
| 105 | print('Kotlin_{}(RunTimeRaw): {} ms'.format(options.benchmark, result)) |
| 106 | |
| 107 | if __name__ == '__main__': |
| 108 | sys.exit(Main()) |