aboutsummaryrefslogtreecommitdiff
path: root/android_bench_suite/run.py
diff options
context:
space:
mode:
Diffstat (limited to 'android_bench_suite/run.py')
-rwxr-xr-xandroid_bench_suite/run.py481
1 files changed, 0 insertions, 481 deletions
diff --git a/android_bench_suite/run.py b/android_bench_suite/run.py
deleted file mode 100755
index 19d9b36f..00000000
--- a/android_bench_suite/run.py
+++ /dev/null
@@ -1,481 +0,0 @@
-#!/usr/bin/env python2
-#
-# Copyright 2017 The Chromium OS Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-#
-# pylint: disable=cros-logging-import
-
-# This is the script to run specified benchmark with different toolchain
-# settings. It includes the process of building benchmark locally and running
-# benchmark on DUT.
-
-"""Main script to run the benchmark suite from building to testing."""
-from __future__ import print_function
-
-import argparse
-import config
-import ConfigParser
-import logging
-import os
-import subprocess
-import sys
-
-logging.basicConfig(level=logging.INFO)
-
-def _parse_arguments(argv):
- parser = argparse.ArgumentParser(description='Build and run specific '
- 'benchamrk')
- parser.add_argument(
- '-b',
- '--bench',
- action='append',
- default=[],
- help='Select which benchmark to run')
-
- # Only one of compiler directory and llvm prebuilts version can be indicated
- # at the beginning, so set -c and -l into a exclusive group.
- group = parser.add_mutually_exclusive_group()
-
- # The toolchain setting arguments has action of 'append', so that users
- # could compare performance with several toolchain settings together.
- group.add_argument(
- '-c',
- '--compiler_dir',
- metavar='DIR',
- action='append',
- default=[],
- help='Specify path to the compiler\'s bin directory. '
- 'You shall give several paths, each with a -c, to '
- 'compare performance differences in '
- 'each compiler.')
-
- parser.add_argument(
- '-o',
- '--build_os',
- action='append',
- default=[],
- help='Specify the host OS to build the benchmark.')
-
- group.add_argument(
- '-l',
- '--llvm_prebuilts_version',
- action='append',
- default=[],
- help='Specify the version of prebuilt LLVM. When '
- 'specific prebuilt version of LLVM already '
- 'exists, no need to pass the path to compiler '
- 'directory.')
-
- parser.add_argument(
- '-f',
- '--cflags',
- action='append',
- default=[],
- help='Specify the cflags options for the toolchain. '
- 'Be sure to quote all the cflags with quotation '
- 'mark("") or use equal(=).')
- parser.add_argument(
- '--ldflags',
- action='append',
- default=[],
- help='Specify linker flags for the toolchain.')
-
- parser.add_argument(
- '-i',
- '--iterations',
- type=int,
- default=1,
- help='Specify how many iterations does the test '
- 'take.')
-
- # Arguments -s and -r are for connecting to DUT.
- parser.add_argument(
- '-s',
- '--serials',
- help='Comma separate list of device serials under '
- 'test.')
-
- parser.add_argument(
- '-r',
- '--remote',
- default='localhost',
- help='hostname[:port] if the ADB device is connected '
- 'to a remote machine. Ensure this workstation '
- 'is configured for passwordless ssh access as '
- 'users "root" or "adb"')
-
- # Arguments -frequency and -m are for device settings
- parser.add_argument(
- '--frequency',
- type=int,
- default=960000,
- help='Specify the CPU frequency of the device. The '
- 'unit is KHZ. The available value is defined in'
- 'cpufreq/scaling_available_frequency file in '
- 'device\'s each core directory. '
- 'The default value is 960000, which shows a '
- 'balance in noise and performance. Lower '
- 'frequency will slow down the performance but '
- 'reduce noise.')
-
- parser.add_argument(
- '-m',
- '--mode',
- default='little',
- help='User can specify whether \'little\' or \'big\' '
- 'mode to use. The default one is little mode. '
- 'The little mode runs on a single core of '
- 'Cortex-A53, while big mode runs on single core '
- 'of Cortex-A57.')
-
- # Configure file for benchmark test
- parser.add_argument(
- '-t',
- '--test',
- help='Specify the test settings with configuration '
- 'file.')
-
- # Whether to keep old json result or not
- parser.add_argument(
- '-k',
- '--keep',
- default='False',
- help='User can specify whether to keep the old json '
- 'results from last run. This can be useful if you '
- 'want to compare performance differences in two or '
- 'more different runs. Default is False(off).')
-
- return parser.parse_args(argv)
-
-
-# Clear old log files in bench suite directory
-def clear_logs():
- logging.info('Removing old logfiles...')
- for f in ['build_log', 'device_log', 'test_log']:
- logfile = os.path.join(config.bench_suite_dir, f)
- try:
- os.remove(logfile)
- except OSError:
- logging.info('No logfile %s need to be removed. Ignored.', f)
- logging.info('Old logfiles been removed.')
-
-
-# Clear old json files in bench suite directory
-def clear_results():
- logging.info('Clearing old json results...')
- for bench in config.bench_list:
- result = os.path.join(config.bench_suite_dir, bench + '.json')
- try:
- os.remove(result)
- except OSError:
- logging.info('no %s json file need to be removed. Ignored.', bench)
- logging.info('Old json results been removed.')
-
-
-# Use subprocess.check_call to run other script, and put logs to files
-def check_call_with_log(cmd, log_file):
- log_file = os.path.join(config.bench_suite_dir, log_file)
- with open(log_file, 'a') as logfile:
- log_header = 'Log for command: %s\n' % (cmd)
- logfile.write(log_header)
- try:
- subprocess.check_call(cmd, stdout=logfile)
- except subprocess.CalledProcessError:
- logging.error('Error running %s, please check %s for more info.', cmd,
- log_file)
- raise
- logging.info('Logs for %s are written to %s.', cmd, log_file)
-
-
-def set_device(serials, remote, frequency):
- setting_cmd = [
- os.path.join(
- os.path.join(config.android_home, config.autotest_dir),
- 'site_utils/set_device.py')
- ]
- setting_cmd.append('-r=' + remote)
- setting_cmd.append('-q=' + str(frequency))
-
- # Deal with serials.
- # If there is no serails specified, try to run test on the only device.
- # If specified, split the serials into a list and run test on each device.
- if serials:
- for serial in serials.split(','):
- setting_cmd.append('-s=' + serial)
- check_call_with_log(setting_cmd, 'device_log')
- setting_cmd.pop()
- else:
- check_call_with_log(setting_cmd, 'device_log')
-
- logging.info('CPU mode and frequency set successfully!')
-
-
-def log_ambiguous_args():
- logging.error('The count of arguments does not match!')
- raise ValueError('The count of arguments does not match.')
-
-
-# Check if the count of building arguments are log_ambiguous or not. The
-# number of -c/-l, -f, and -os should be either all 0s or all the same.
-def check_count(compiler, llvm_version, build_os, cflags, ldflags):
- # Count will be set to 0 if no compiler or llvm_version specified.
- # Otherwise, one of these two args length should be 0 and count will be
- # the other one.
- count = max(len(compiler), len(llvm_version))
-
- # Check if number of cflags is 0 or the same with before.
- if len(cflags) != 0:
- if count != 0 and len(cflags) != count:
- log_ambiguous_args()
- count = len(cflags)
-
- if len(ldflags) != 0:
- if count != 0 and len(ldflags) != count:
- log_ambiguous_args()
- count = len(ldflags)
-
- if len(build_os) != 0:
- if count != 0 and len(build_os) != count:
- log_ambiguous_args()
- count = len(build_os)
-
- # If no settings are passed, only run default once.
- return max(1, count)
-
-
-# Build benchmark binary with toolchain settings
-def build_bench(setting_no, bench, compiler, llvm_version, build_os, cflags,
- ldflags):
- # Build benchmark locally
- build_cmd = ['./build_bench.py', '-b=' + bench]
- if compiler:
- build_cmd.append('-c=' + compiler[setting_no])
- if llvm_version:
- build_cmd.append('-l=' + llvm_version[setting_no])
- if build_os:
- build_cmd.append('-o=' + build_os[setting_no])
- if cflags:
- build_cmd.append('-f=' + cflags[setting_no])
- if ldflags:
- build_cmd.append('--ldflags=' + ldflags[setting_no])
-
- logging.info('Building benchmark for toolchain setting No.%d...', setting_no)
- logging.info('Command: %s', build_cmd)
-
- try:
- subprocess.check_call(build_cmd)
- except:
- logging.error('Error while building benchmark!')
- raise
-
-
-def run_and_collect_result(test_cmd, setting_no, i, bench, serial='default'):
-
- # Run autotest script for benchmark on DUT
- check_call_with_log(test_cmd, 'test_log')
-
- logging.info('Benchmark with setting No.%d, iter.%d finished testing on '
- 'device %s.', setting_no, i, serial)
-
- # Rename results from the bench_result generated in autotest
- bench_result = os.path.join(config.bench_suite_dir, 'bench_result')
- if not os.path.exists(bench_result):
- logging.error('No result found at %s, '
- 'please check test_log for details.', bench_result)
- raise OSError('Result file %s not found.' % bench_result)
-
- new_bench_result = 'bench_result_%s_%s_%d_%d' % (bench, serial, setting_no, i)
- new_bench_result_path = os.path.join(config.bench_suite_dir, new_bench_result)
- try:
- os.rename(bench_result, new_bench_result_path)
- except OSError:
- logging.error('Error while renaming raw result %s to %s', bench_result,
- new_bench_result_path)
- raise
-
- logging.info('Benchmark result saved at %s.', new_bench_result_path)
-
-
-def test_bench(bench, setting_no, iterations, serials, remote, mode):
- logging.info('Start running benchmark on device...')
-
- # Run benchmark and tests on DUT
- for i in range(iterations):
- logging.info('Iteration No.%d:', i)
- test_cmd = [
- os.path.join(
- os.path.join(config.android_home, config.autotest_dir),
- 'site_utils/test_bench.py')
- ]
- test_cmd.append('-b=' + bench)
- test_cmd.append('-r=' + remote)
- test_cmd.append('-m=' + mode)
-
- # Deal with serials.
- # If there is no serails specified, try to run test on the only device.
- # If specified, split the serials into a list and run test on each device.
- if serials:
- for serial in serials.split(','):
- test_cmd.append('-s=' + serial)
-
- run_and_collect_result(test_cmd, setting_no, i, bench, serial)
- test_cmd.pop()
- else:
- run_and_collect_result(test_cmd, setting_no, i, bench)
-
-
-def gen_json(bench, setting_no, iterations, serials):
- bench_result = os.path.join(config.bench_suite_dir, 'bench_result')
-
- logging.info('Generating JSON file for Crosperf...')
-
- if not serials:
- serials = 'default'
-
- for serial in serials.split(','):
-
- # Platform will be used as device lunch combo instead
- #experiment = '_'.join([serial, str(setting_no)])
- experiment = config.product_combo
-
- # Input format: bench_result_{bench}_{serial}_{setting_no}_
- input_file = '_'.join([bench_result, bench, serial, str(setting_no), ''])
- gen_json_cmd = [
- './gen_json.py', '--input=' + input_file,
- '--output=%s.json' % os.path.join(config.bench_suite_dir, bench),
- '--bench=' + bench, '--platform=' + experiment,
- '--iterations=' + str(iterations)
- ]
-
- logging.info('Command: %s', gen_json_cmd)
- if subprocess.call(gen_json_cmd):
- logging.error('Error while generating JSON file, please check raw data'
- 'of the results at %s.', input_file)
-
-
-def gen_crosperf(infile, outfile):
- # Set environment variable for crosperf
- os.environ['PYTHONPATH'] = os.path.dirname(config.toolchain_utils)
-
- logging.info('Generating Crosperf Report...')
- crosperf_cmd = [
- os.path.join(config.toolchain_utils, 'generate_report.py'),
- '-i=' + infile, '-o=' + outfile, '-f'
- ]
-
- # Run crosperf generate_report.py
- logging.info('Command: %s', crosperf_cmd)
- subprocess.call(crosperf_cmd)
-
- logging.info('Report generated successfully!')
- logging.info('Report Location: ' + outfile + '.html at bench'
- 'suite directory.')
-
-
-def main(argv):
- # Set environment variable for the local loacation of benchmark suite.
- # This is for collecting testing results to benchmark suite directory.
- os.environ['BENCH_SUITE_DIR'] = config.bench_suite_dir
-
- # Set Android type, used for the difference part between aosp and internal.
- os.environ['ANDROID_TYPE'] = config.android_type
-
- # Set ANDROID_HOME for both building and testing.
- os.environ['ANDROID_HOME'] = config.android_home
-
- # Set environment variable for architecture, this will be used in
- # autotest.
- os.environ['PRODUCT'] = config.product
-
- arguments = _parse_arguments(argv)
-
- bench_list = arguments.bench
- if not bench_list:
- bench_list = config.bench_list
-
- compiler = arguments.compiler_dir
- build_os = arguments.build_os
- llvm_version = arguments.llvm_prebuilts_version
- cflags = arguments.cflags
- ldflags = arguments.ldflags
- iterations = arguments.iterations
- serials = arguments.serials
- remote = arguments.remote
- frequency = arguments.frequency
- mode = arguments.mode
- keep = arguments.keep
-
- # Clear old logs every time before run script
- clear_logs()
-
- if keep == 'False':
- clear_results()
-
- # Set test mode and frequency of CPU on the DUT
- set_device(serials, remote, frequency)
-
- test = arguments.test
- # if test configuration file has been given, use the build settings
- # in the configuration file and run the test.
- if test:
- test_config = ConfigParser.ConfigParser(allow_no_value=True)
- if not test_config.read(test):
- logging.error('Error while reading from building '
- 'configuration file %s.', test)
- raise RuntimeError('Error while reading configuration file %s.' % test)
-
- for setting_no, section in enumerate(test_config.sections()):
- bench = test_config.get(section, 'bench')
- compiler = [test_config.get(section, 'compiler')]
- build_os = [test_config.get(section, 'build_os')]
- llvm_version = [test_config.get(section, 'llvm_version')]
- cflags = [test_config.get(section, 'cflags')]
- ldflags = [test_config.get(section, 'ldflags')]
-
- # Set iterations from test_config file, if not exist, use the one from
- # command line.
- it = test_config.get(section, 'iterations')
- if not it:
- it = iterations
- it = int(it)
-
- # Build benchmark for each single test configuration
- build_bench(0, bench, compiler, llvm_version, build_os, cflags, ldflags)
-
- test_bench(bench, setting_no, it, serials, remote, mode)
-
- gen_json(bench, setting_no, it, serials)
-
- for bench in config.bench_list:
- infile = os.path.join(config.bench_suite_dir, bench + '.json')
- if os.path.exists(infile):
- outfile = os.path.join(config.bench_suite_dir, bench + '_report')
- gen_crosperf(infile, outfile)
-
- # Stop script if there is only config file provided
- return 0
-
- # If no configuration file specified, continue running.
- # Check if the count of the setting arguments are log_ambiguous.
- setting_count = check_count(compiler, llvm_version, build_os, cflags, ldflags)
-
- for bench in bench_list:
- logging.info('Start building and running benchmark: [%s]', bench)
- # Run script for each toolchain settings
- for setting_no in range(setting_count):
- build_bench(setting_no, bench, compiler, llvm_version, build_os, cflags,
- ldflags)
-
- # Run autotest script for benchmark test on device
- test_bench(bench, setting_no, iterations, serials, remote, mode)
-
- gen_json(bench, setting_no, iterations, serials)
-
- infile = os.path.join(config.bench_suite_dir, bench + '.json')
- outfile = os.path.join(config.bench_suite_dir, bench + '_report')
- gen_crosperf(infile, outfile)
-
-
-if __name__ == '__main__':
- main(sys.argv[1:])