diff --git a/libs/utils/android/workloads/uibench.py b/libs/utils/android/workloads/uibench.py index 967ac57d14a3a7448616188570c83ea5ca56036d..0a4219cad06eb69ab0f72a0ccbf7048e401a4c4c 100644 --- a/libs/utils/android/workloads/uibench.py +++ b/libs/utils/android/workloads/uibench.py @@ -22,9 +22,7 @@ import logging from subprocess import Popen, PIPE from time import sleep -from android import Screen, System -from android.workload import Workload - +from android import Screen, System, Workload class UiBench(Workload): """ @@ -60,8 +58,27 @@ class UiBench(Workload): # Set of output data reported by UiBench self.db_file = None - def run(self, out_dir, collect, - test_name, duration_s): + def run(self, out_dir, test_name, duration_s, collect=''): + """ + Run single UiBench workload. + + :param out_dir: Path to experiment directory where to store results. + :type out_dir: str + + :param test_name: Name of the test to run + :type test_name: str + + :param duration_s: Run benchmak for this required number of seconds + :type duration_s: int + + :param collect: Specifies what to collect. Possible values: + - 'energy' + - 'systrace' + - 'ftrace' + - any combination of the above + :type collect: list(str) + """ + activity = '.' + test_name + 'Activity' # Keep track of mandatory parameters @@ -69,24 +86,27 @@ class UiBench(Workload): self.collect = collect # Press Back button to be sure we run the video from the start - System.menu(self.target) - System.back(self.target) + System.menu(self._target) + System.back(self._target) # Close and clear application - System.force_stop(self.target, self.package, clear=True) + System.force_stop(self._target, self.package, clear=True) # Set airplane mode - System.set_airplane_mode(self.target, on=True) + System.set_airplane_mode(self._target, on=True) + + # Set min brightness + Screen.set_brightness(self._target, auto=False, percent=0) # Start the main view of the app which must be running # to reset the frame statistics. - System.monkey(self.target, self.package) + System.monkey(self._target, self.package) # Force screen in PORTRAIT mode - Screen.set_orientation(self.target, portrait=True) + Screen.set_orientation(self._target, portrait=True) # Reset frame statistics - System.gfxinfo_reset(self.target, self.package) + System.gfxinfo_reset(self._target, self.package) sleep(1) # Clear logcat @@ -101,11 +121,11 @@ class UiBench(Workload): # Parse logcat output lines logcat_cmd = self._adb( 'logcat ActivityManager:* System.out:I *:S BENCH:*'\ - .format(self.target.adb_name)) + .format(self._target.adb_name)) self._log.info("%s", logcat_cmd) # Start the activity - System.start_activity(self.target, self.package, activity) + System.start_activity(self._target, self.package, activity) logcat = Popen(logcat_cmd, shell=True, stdout=PIPE) while True: @@ -129,16 +149,17 @@ class UiBench(Workload): # Get frame stats self.db_file = os.path.join(out_dir, "framestats.txt") - System.gfxinfo_get(self.target, self.package, self.db_file) + System.gfxinfo_get(self._target, self.package, self.db_file) # Close and clear application - System.force_stop(self.target, self.package, clear=True) + System.force_stop(self._target, self.package, clear=True) # Go back to home screen - System.home(self.target) + System.home(self._target) # Switch back to original settings - Screen.set_orientation(self.target, auto=True) - System.set_airplane_mode(self.target, on=False) + Screen.set_orientation(self._target, auto=True) + System.set_airplane_mode(self._target, on=False) + Screen.set_brightness(self._target, auto=True) # vim :set tabstop=4 shiftwidth=4 expandtab diff --git a/tests/benchmarks/android_uibench.py b/tests/benchmarks/android_uibench.py new file mode 100755 index 0000000000000000000000000000000000000000..97e2a3fe2de4a3627b65be7fb18683b089869fdd --- /dev/null +++ b/tests/benchmarks/android_uibench.py @@ -0,0 +1,202 @@ +#!/usr/bin/python + +import os +from time import sleep + +# The workload class MUST be loaded before the LisaBenchmark +from android import Workload +from android import LisaBenchmark + +from devlib.exception import TargetError + +class UiBenchTest(LisaBenchmark): + + bm_conf = { + + # Target platform and board + "platform" : 'android', + + # Define devlib modules to load + "modules" : [ + 'cpufreq', + ], + + # FTrace events to collect for all the tests configuration which have + # the "ftrace" flag enabled + "ftrace" : { + "events" : [ + "sched_switch", + "sched_overutilized", + "sched_contrib_scale_f", + "sched_load_avg_cpu", + "sched_load_avg_task", + "sched_tune_tasks_update", + "sched_boost_cpu", + "sched_boost_task", + "sched_energy_diff", + "cpu_frequency", + "cpu_idle", + "cpu_capacity", + ], + "buffsize" : 10 * 1024, + }, + + # Default EnergyMeter Configuration + "emeter" : { + "instrument" : "acme", + "channel_map" : { + "Device0" : 0, + } + }, + + # Tools required by the experiments + "tools" : [ 'trace-cmd' ], + + # Default results folder + "results_dir" : "AndroidUiBench", + + } + + # Android Workload to run + bm_name = 'UiBench' + + # Default products to be collected + bm_collect = 'ftrace energy' + + def benchmarkInit(self): + self.setupWorkload() + self.setupGovernor() + if self.reboot: + self.reboot_target() + + def benchmarkFinalize(self): + if self.delay_after_s: + self._log.info("Waiting %d[s] before to continue...", + self.delay_after_s) + sleep(self.delay_after_s) + + def __init__(self, governor, test, duration_s, reboot=False, + delay_after_s=0): + self.reboot = reboot + self.governor = governor + self.test = test + self.duration_s = duration_s + self.delay_after_s = delay_after_s + super(UiBenchTest, self).__init__() + + def setupWorkload(self): + # Create a results folder for each "governor/test" + self.out_dir = os.path.join(self.te.res_dir, governor, self.test) + try: + os.stat(self.out_dir) + except: + os.makedirs(self.out_dir) + # Setup workload parameters + self.bm_params = { + 'test_name' : self.test, + 'duration_s' : self.duration_s, + } + + def setupGovernor(self): + try: + self.target.cpufreq.set_all_governors(self.governor); + except TargetError: + self._log.warning('Governor [%s] not available on target', + self.governor) + raise + + # Setup schedutil parameters + if self.governor == 'schedutil': + rate_limit_us = 2000 + # Different schedutil versions have different tunables + tunables = self.target.cpufreq.list_governor_tunables(0) + if 'rate_limit_us' in tunables: + tunables = {'rate_limit_us' : str(rate_limit_us)} + else: + assert ('up_rate_limit_us' in tunables and + 'down_rate_limit_us' in tunables) + tunables = { + 'up_rate_limit_us' : str(rate_limit_us), + 'down_rate_limit_us' : str(rate_limit_us) + } + + try: + for cpu_id in range(self.te.platform['cpus_count']): + self.target.cpufreq.set_governor_tunables( + cpu_id, 'schedutil', **tunables) + except TargetError as e: + self._log.warning('Failed to set schedutils parameters: {}'\ + .format(e)) + raise + self._log.info('Set schedutil.rate_limit_us=%d', rate_limit_us) + + # Setup ondemand parameters + if self.governor == 'ondemand': + try: + for cpu_id in range(self.te.platform['cpus_count']): + tunables = self.target.cpufreq.get_governor_tunables(cpu_id) + self.target.cpufreq.set_governor_tunables( + cpu_id, 'ondemand', + **{'sampling_rate' : tunables['sampling_rate_min']}) + except TargetError as e: + self._log.warning('Failed to set ondemand parameters: {}'\ + .format(e)) + raise + self._log.info('Set ondemand.sampling_rate to minimum supported') + + # Report configured governor + governors = self.target.cpufreq.get_all_governors() + self._log.info('Using governors: %s', governors) + +# Run the benchmark in each of the supported governors + +duration_s = 20 + +governors = [ + 'performance', + 'ondemand', + 'interactive', + 'sched', + 'schedutil', + 'powersave', +] + +tests = [ + 'TrivialAnimation', + 'BitmapUpload', + 'DialogList', + 'EditTextType', + 'FullscreenOverdraw', + 'GlTextureView', + 'InflatingList', + 'Invalidate', + 'ShadowGrid', + 'TextCacheHighHitrate', + 'TextCacheLowHitrate', + 'Transition', + 'TransitionDetails', + 'TrivialList', + 'TrivialRecyclerView', +] + +# Reboot device only the first time +do_reboot = True +tests_remaining = len(governors) * len(tests) +tests_completed = 0 +for governor in governors: + for test in tests: + tests_remaining -= 1 + delay_after_s = 30 if tests_remaining else 0 + try: + UiBenchTest(governor, test, duration_s, + do_reboot, delay_after_s) + tests_completed += 1 + except: + # A test configuraion failed, continue with other tests + pass + do_reboot = False + +# We want to collect data from at least one governor +assert(tests_completed >= 1) + +# vim :set tabstop=4 shiftwidth=4 expandtab