diff options
author | android-build-team Robot <android-build-team-robot@google.com> | 2017-08-30 08:05:31 +0000 |
---|---|---|
committer | android-build-team Robot <android-build-team-robot@google.com> | 2017-08-30 08:05:31 +0000 |
commit | 48c78d0e2fd61dbc3136ce9dd76e6352f16f0700 (patch) | |
tree | b5dcde35107d6b6f855356b8c66153ad9abb666c | |
parent | f5a00c31e8587e7e1fa4f95e15c11ff7a588ab0b (diff) | |
parent | 134b63c1ffe5aec975a97c6e363aa4589909e797 (diff) | |
download | benchmark-48c78d0e2fd61dbc3136ce9dd76e6352f16f0700.tar.gz |
release-request-dbb5053c-c8af-4c07-a295-d7d7b281ce3f-for-git_pi-release-4306414 snap-temp-L16000000097876522
Change-Id: I1ef23ed4dc55fa6b25403fa388538fc0d17a8971
-rwxr-xr-x | apply_patches.py | 1 | ||||
-rw-r--r-- | autotest.diff | 212 | ||||
-rwxr-xr-x | collect_profile.py | 139 | ||||
-rwxr-xr-x | discard_patches.py | 5 | ||||
-rwxr-xr-x | run.py | 4 |
5 files changed, 357 insertions, 4 deletions
diff --git a/apply_patches.py b/apply_patches.py index e0499d44..ff706f1d 100755 --- a/apply_patches.py +++ b/apply_patches.py @@ -64,6 +64,7 @@ def try_patch_panorama(): # FIXME: A quick hack, need to handle errors and check whether has been # applied in the future. try: + subprocess.check_call(['mkdir', '-p', panorama_dir]) subprocess.check_call(['git', '-C', panorama_dir, 'apply', panorama_patch]) print('Panorama patched successfully!') except subprocess.CalledProcessError: diff --git a/autotest.diff b/autotest.diff index ef0029ae..95ef2e4d 100644 --- a/autotest.diff +++ b/autotest.diff @@ -237,7 +237,7 @@ index 000000000..763864f3a +parallel_simple(run_dex2oat, machines) diff --git a/server/site_tests/android_Hwui/android_Hwui.py b/server/site_tests/android_Hwui/android_Hwui.py new file mode 100644 -index 000000000..d1837e042 +index 000000000..9a1accb09 --- /dev/null +++ b/server/site_tests/android_Hwui/android_Hwui.py @@ -0,0 +1,67 @@ @@ -360,7 +360,7 @@ index 000000000..89c47da20 +parallel_simple(run_hwui_test, machines) diff --git a/server/site_tests/android_Panorama/android_Panorama.py b/server/site_tests/android_Panorama/android_Panorama.py new file mode 100644 -index 000000000..db2a29cde +index 000000000..89b2355e5 --- /dev/null +++ b/server/site_tests/android_Panorama/android_Panorama.py @@ -0,0 +1,53 @@ @@ -467,6 +467,92 @@ index 000000000..3cd589eed + job.run_test("android_Panorama", host=host) + +parallel_simple(run_panorama_test, machines) +diff --git a/server/site_tests/android_Pull/android_Pull.py b/server/site_tests/android_Pull/android_Pull.py +new file mode 100644 +index 000000000..cff373899 +--- /dev/null ++++ b/server/site_tests/android_Pull/android_Pull.py +@@ -0,0 +1,30 @@ ++# Pull profraw data from device ++from __future__ import print_function ++ ++import bench_config ++ ++from autotest_lib.server import test ++ ++class android_Pull(test.test): ++ version = 1 ++ ++ def run_once(self, host=None): ++ self.client = host ++ ++ # Tar all the files in profraw directory ++ tar_file= bench_config.location_DUT + '.tar' ++ raw_cmd = ('tar -cvf {tar_file} {location_DUT}'.format( ++ tar_file=tar_file, ++ location_DUT=bench_config.location_DUT)) ++ self.client.run(raw_cmd) ++ ++ # Pull tar of profraw data from the device ++ out_dir = bench_config.location ++ ++ host.get_file(tar_file, out_dir, delete_dest=True) ++ ++ # Remove the data on the device ++ self.client.run('rm %s' % tar_file) ++ self.client.run('rm -rf %s' % bench_config.location_DUT) ++ ++ print('Profraw data has been pulled from device to local.') +diff --git a/server/site_tests/android_Pull/bench_config.py b/server/site_tests/android_Pull/bench_config.py +new file mode 100644 +index 000000000..37967c2f9 +--- /dev/null ++++ b/server/site_tests/android_Pull/bench_config.py +@@ -0,0 +1,19 @@ ++#!/bin/bash/python ++import os ++ ++home = os.environ["HOME"] ++ ++android_home = os.getenv("ANDROID_HOME", ++ default=os.path.join(home, ++ 'android_source/master-googleplex/')) ++bench_suite_dir = os.getenv('BENCH_SUITE_DIR', ++ default=os.path.join(android_home, ++ 'benchtoolchain')) ++ ++bench = os.getenv('BENCH', default='Hwui') ++location_DUT = os.getenv('LOCATION_DUT', ++ default=os.path.join('/data/local/tmp', ++ bench + '_profraw')) ++location = os.getenv('LOCATION', default=bench_suite_dir) ++ ++product = os.getenv("PRODUCT", default="generic") +diff --git a/server/site_tests/android_Pull/control b/server/site_tests/android_Pull/control +new file mode 100644 +index 000000000..7b00df7cb +--- /dev/null ++++ b/server/site_tests/android_Pull/control +@@ -0,0 +1,19 @@ ++#Control ++ ++NAME = "Pull" ++AUTHOR = "Zhizhou Yang" ++ATTRIBUTES = "suite:android_toolchain_benchmark" ++TIME = "MEDIUM" ++TEST_CATEGORY = "Functional" ++TEST_CLASS = "library" ++TEST_TYPE = "server" ++ ++DOC = """ ++ ++""" ++ ++def run_pull_test(machine): ++ host = hosts.create_host(machine) ++ job.run_test("android_Pull", host=host) ++ ++parallel_simple(run_pull_test, machines) diff --git a/server/site_tests/android_SetDevice/android_SetDevice.py b/server/site_tests/android_SetDevice/android_SetDevice.py new file mode 100644 index 000000000..7a7134d58 @@ -800,6 +886,128 @@ index 000000000..144766351 + job.run_test("android_Synthmark", host=host) + +parallel_simple(run_synthmark_test, machines) +diff --git a/site_utils/pull_device.py b/site_utils/pull_device.py +new file mode 100755 +index 000000000..959c4443d +--- /dev/null ++++ b/site_utils/pull_device.py +@@ -0,0 +1,116 @@ ++#!/usr/bin/python ++# ++# Script to pull data from android device ++from __future__ import print_function ++ ++import argparse ++import common ++import logging ++import os ++import sys ++ ++# Turn the logging level to INFO before importing other autotest ++# code, to avoid having failed import logging messages confuse the ++# test_droid user. ++logging.basicConfig(level=logging.INFO) ++ ++# Unfortunately, autotest depends on external packages for assorted ++# functionality regardless of whether or not it is needed in a particular ++# context. ++# Since we can't depend on people to import these utilities in any principled ++# way, we dynamically download code before any autotest imports. ++try: ++ import chromite.lib.terminal # pylint: disable=unused-import ++ import django.http # pylint: disable=unused-import ++except ImportError: ++ # Ensure the chromite site-package is installed. ++ import subprocess ++ build_externals_path = os.path.join( ++ os.path.dirname(os.path.dirname(os.path.realpath(__file__))), ++ 'utils', 'build_externals.py') ++ subprocess.check_call([build_externals_path, '--names_to_check', ++ 'chromiterepo', 'django']) ++ # Restart the script so python now finds the autotest site-packages. ++ sys.exit(os.execv(__file__, sys.argv)) ++ ++from autotest_lib.client.common_lib import utils ++from autotest_lib.server.hosts import adb_host ++from autotest_lib.site_utils import test_runner_utils ++from autotest_lib.site_utils import tester_feedback ++ ++def _parse_arguments_internal(argv): ++ """ ++ Parse command line arguments ++ ++ @param argv: argument list to parse ++ ++ @returns: tuple of parsed arguments and argv suitable for remote runs ++ ++ @raises SystemExit if arguments are malformed, or required arguments ++ are not present. ++ """ ++ ++ parser = argparse.ArgumentParser(description='Run remote tests.') ++ ++ parser.add_argument('-b', '--bench', metavar='BENCH', required=True, ++ help='Select the benchmark want to be run for ' ++ 'test.') ++ parser.add_argument('-s', '--serials', metavar='SERIALS', ++ help='Comma separate list of device serials under ' ++ 'test.') ++ parser.add_argument('-r', '--remote', metavar='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"') ++ ++ parser.add_argument('-d', '--pathDUT', ++ help='Specify the location to put the file on DUT.') ++ parser.add_argument('-p', '--path', ++ help='Specify the location to put the file locally.') ++ ++ return parser.parse_args(argv) ++ ++def main(argv): ++ """ ++ Entry point for pull_device script. ++ ++ @param argv: arguments list ++ """ ++ arguments = _parse_arguments_internal(argv) ++ ++ serials = arguments.serials ++ if serials is None: ++ result = utils.run(['adb', 'devices']) ++ devices = adb_host.ADBHost.parse_device_serials(result.stdout) ++ if len(devices) != 1: ++ logging.error('Could not detect exactly one device; please select ' ++ 'one with -s: %s', devices) ++ return 1 ++ serials = devices[0] ++ ++ autotest_path = os.path.dirname(os.path.dirname( ++ os.path.realpath(__file__))) ++ site_utils_path = os.path.join(autotest_path, 'site_utils') ++ realpath = os.path.realpath(__file__) ++ site_utils_path = os.path.realpath(site_utils_path) ++ host_attributes = {'serials': serials, ++ 'os_type': 'android'} ++ results_directory = test_runner_utils.create_results_directory(None) ++ ++ os.environ['BENCH'] = arguments.bench ++ os.environ['LOCATION_DUT'] = arguments.pathDUT ++ os.environ['LOCATION'] = arguments.path ++ ++ tests = ['Pull'] ++ ++ if test_runner_utils.perform_run_from_autotest_root( ++ autotest_path, argv, tests, arguments.remote, ++ host_attributes=host_attributes, ++ results_directory=results_directory): ++ logging.error('Error while running on device.') ++ return 1 ++ ++if __name__ == '__main__': ++ sys.exit(main(sys.argv[1:])) diff --git a/site_utils/set_device.py b/site_utils/set_device.py new file mode 100755 index 000000000..abb8a8dcc diff --git a/collect_profile.py b/collect_profile.py new file mode 100755 index 00000000..27d5e5d6 --- /dev/null +++ b/collect_profile.py @@ -0,0 +1,139 @@ +#!/usr/bin/python + +# Script to generate and collect PGO data based on benchmark +from __future__ import print_function + +import argparse +import config +import logging +import os +import subprocess +import sys +import tempfile + +# Turn the logging level to INFO before importing other code, to avoid having +# failed import logging messages confuse the user. +logging.basicConfig(level=logging.INFO) + +def _parse_arguments_internal(argv): + """ + Parse command line arguments + + @param argv: argument list to parse + + @returns: tuple of parsed arguments and argv suitable for remote runs + + @raises SystemExit if arguments are malformed, or required arguments + are not present. + """ + + parser = argparse.ArgumentParser(description='Run this script to collect ' + 'PGO data.') + + parser.add_argument('-b', '--bench', + help='Select which benchmark to collect profdata.') + + parser.add_argument('-d', '--pathDUT', default='/data/local/tmp', + help='Specify where to generate PGO data on device, ' + 'set to /data/local/tmp by default.') + + parser.add_argument('-p', '--path', default=config.bench_suite_dir, + help='Specify the location to put the profdata, set ' + ' to bench_suite_dir by default.') + + parser.add_argument('-s', '--serial', + help='Device serial number.') + + 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"') + return parser.parse_args(argv) + +# Call run.py to build benchmark with -fprofile-generate flags and run on DUT +def run_suite(bench, serial, remote, pathDUT): + logging.info('Build and run instrumented benchmark...') + run_cmd = ['./run.py', '-b=' + bench] + if serial: + run_cmd.append('-s=' + serial) + run_cmd.append('-r=' + remote) + run_cmd.append('-f=-fprofile-generate=%s' % pathDUT) + run_cmd.append('--ldflags=-fprofile-generate=%s' % pathDUT) + try: + subprocess.check_call(run_cmd) + except subprocess.CalledProcessError: + logging.error('Error running %s.', run_cmd) + raise + +# Pull profraw data from device using pull_device.py script in autotest utils. +def pull_result(bench, serial, remote, pathDUT, path): + logging.info('Pulling profraw data from device to local') + pull_cmd = [os.path.join(config.android_home, + config.autotest_dir, + 'site_utils/pull_device.py')] + pull_cmd.append('-b=' + bench) + pull_cmd.append('-r=' + remote) + if serial: + pull_cmd.append('-s=' + serial) + pull_cmd.append('-p=' + path) + pull_cmd.append('-d=' + pathDUT) + try: + subprocess.check_call(pull_cmd) + except: + logging.error('Error while pulling profraw data.') + raise + +# Use llvm-profdata tool to convert profraw data to the format llvm can +# recgonize. +def merge(bench, pathDUT, path): + logging.info('Generate profdata for PGO...') + # Untar the compressed rawdata file collected from device + tmp_dir = tempfile.mkdtemp() + untar_cmd = ['tar', + '-xf', + os.path.join(path, bench + '_profraw.tar'), + '-C', + tmp_dir] + + # call llvm-profdata to merge the profraw data + profdata = os.path.join(path, bench + '.profdata') + merge_cmd = ['llvm-profdata', + 'merge', + '-output=' + profdata, + tmp_dir + pathDUT] + try: + subprocess.check_call(untar_cmd) + subprocess.check_call(merge_cmd) + logging.info('Profdata is generated successfully, located at %s', + profdata) + except: + logging.error('Error while merging profraw data.') + raise + finally: + subprocess.check_call(['rm', '-rf', tmp_dir]) + +def main(argv): + """ + Entry point for nightly_run script. + + @param argv: arguments list + """ + arguments = _parse_arguments_internal(argv) + + bench = arguments.bench + serial = arguments.serial + path = arguments.path + remote = arguments.remote + + # Create a profraw directory to collect data + pathDUT = os.path.join(arguments.pathDUT, bench + '_profraw') + + run_suite(bench, serial, remote, pathDUT) + + pull_result(bench, serial, remote, pathDUT, path) + + merge(bench, pathDUT, path) + +if __name__ == '__main__': + main(sys.argv[1:]) diff --git a/discard_patches.py b/discard_patches.py index 7a4b0b56..4dd99ead 100755 --- a/discard_patches.py +++ b/discard_patches.py @@ -36,6 +36,11 @@ def dispatch_panorama(): panorama_dir = os.path.join(config.android_home, config.bench_dict['Panorama']) discard_git(panorama_dir) + try: + subprocess.check_call(['rm', '-rf', panorama_dir]) + print('Panorama benchmark directory deleted successfully!') + except subprocess.CalledProcessError: + print('Error deleting Panorama benchmark directory') def dispatch_synthmark(): @@ -109,12 +109,12 @@ def _parse_arguments(argv): parser.add_argument( '--frequency', type=int, - default=960000, + default=979200, 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 ' + 'The default value is 979200, which shows a ' 'balance in noise and performance. Lower ' 'frequency will slow down the performance but ' 'reduce noise.') |