From b2b01f4352beaeef266e411e0a186db79b10de5b Mon Sep 17 00:00:00 2001 From: Michele Di Giorgio Date: Tue, 20 Sep 2016 17:53:04 +0100 Subject: [PATCH 1/3] libs/utils/android: add method to get device screen density Signed-off-by: Michele Di Giorgio --- libs/utils/android/screen.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/libs/utils/android/screen.py b/libs/utils/android/screen.py index f5af5377e..af80a5f07 100644 --- a/libs/utils/android/screen.py +++ b/libs/utils/android/screen.py @@ -129,4 +129,11 @@ class Screen(object): Screen.set_dim(target) Screen.set_timeout(target) + @staticmethod + def get_screen_density(target): + """ + Get screen density of the device. + """ + return target.execute('getprop ro.sf.lcd_density') + # vim :set tabstop=4 shiftwidth=4 expandtab -- GitLab From f3631fb614d2b71d2189ef1a0a508c516e6df29a Mon Sep 17 00:00:00 2001 From: Michele Di Giorgio Date: Tue, 20 Sep 2016 17:53:32 +0100 Subject: [PATCH 2/3] libs/utils/android/workloads: add vellamo workload for Android targets Signed-off-by: Michele Di Giorgio Signed-off-by: Ionela Voinescu --- libs/utils/android/workloads/vellamo.py | 178 ++++++++++++++++++++++++ 1 file changed, 178 insertions(+) create mode 100644 libs/utils/android/workloads/vellamo.py diff --git a/libs/utils/android/workloads/vellamo.py b/libs/utils/android/workloads/vellamo.py new file mode 100644 index 000000000..476266efa --- /dev/null +++ b/libs/utils/android/workloads/vellamo.py @@ -0,0 +1,178 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# Copyright (C) 2015, ARM Limited and contributors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +import re +import os +import collections +import copy +import logging +from time import sleep + +from subprocess import Popen, PIPE + +from android import Screen, System, Workload + +# screen density of the device with which this workload has been tested +DEFAULT_DENSITY = '420' + +VELLAMO_DB_PATH = '/data/data/com.quicinc.vellamo/files' +VELLAMO_SCORE_NAME = 'chapterscores.json' +VELLAMO_TESTS = ['BROWSER', 'METAL', 'MULTI'] + +class Vellamo(Workload): + """ + Android Vellamo workload + """ + + # Package required by this workload + package = 'com.quicinc.vellamo' + activity = 'com.quicinc.vellamo.main.MainActivity' + + def __init__(self, test_env): + super(Vellamo, self).__init__(test_env) + self._log = logging.getLogger('Vellamo') + self._log.debug('Workload created') + + def run(self, out_dir, test_name, collect=''): + """ + Run single Vellamo workload. Returns a collection of results. + + :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 collect: Specifies what to collect. Possible values: + - 'energy' + - 'systrace' + - 'ftrace' + - any combination of the above + :type collect: list(str) + """ + + self.out_dir = out_dir + self.collect = collect + + # Check if the density of the target device screen is different from + # the one used to get the values below + density = Screen.get_screen_density(self._target) + if DEFAULT_DENSITY not in density: + msg = 'Screen density of target device differs from {}.\n'\ + 'Please set it to {}' + raise RuntimeError(msg.format(DEFAULT_DENSITY, DEFAULT_DENSITY)) + + if test_name.upper() not in VELLAMO_TESTS: + raise ValueError('Vellamo workload [%s] not supported', test_name) + + # Set parameter depending on test + self._log.debug('Start Vellamo Benchmark [%s]', test_name) + test_x, test_y = (0, 0) + sleep_time = 0 + if test_name.upper() == 'BROWSER': + test_x, test_y = (91, 33) + sleep_time = 3.5 + elif test_name.upper() == 'METAL': + test_x, test_y = (91, 59) + sleep_time = 1 + elif test_name.upper() == 'MULTI': + test_x, test_y = (91, 71) + sleep_time = 3.5 + + # Unlock device screen (assume no password required) + System.menu(self._target) + System.back(self._target) + + System.force_stop(self._target, self.package, clear=True) + + # Set min brightness + Screen.set_brightness(self._target, auto=False, percent=0) + + # Clear logcat + os.system(self._adb('logcat -c')); + + # Regexps for benchmark synchronization + start_logline = r'ActivityManager: Start.*'\ + ':com.quicinc.vellamo:benchmarking' + VELLAMO_BENCHMARK_START_RE = re.compile(start_logline) + self._log.debug("START string [%s]", start_logline) + + # End of benchmark is marked by displaying results + end_logline = r'ActivityManager: START.*'\ + 'act=com.quicinc.vellamo.*_RESULTS' + VELLAMO_BENCHMARK_END_RE = re.compile(end_logline) + self._log.debug("END string [%s]", end_logline) + + # Parse logcat output lines + logcat_cmd = self._adb( + 'logcat ActivityManager:* System.out:I *:S BENCH:*'\ + .format(self._target.adb_name)) + self._log.info("%s", logcat_cmd) + + # Start the activity + System.start_activity(self._target, self.package, self.activity) + logcat = Popen(logcat_cmd, shell=True, stdout=PIPE) + sleep(2) + # Accept EULA + System.tap(self._target, 80, 86) + sleep(1) + # Click Let's Roll + System.tap(self._target, 50, 67) + sleep(1) + # Skip Arrow + System.tap(self._target, 46, 78) + # Run Workload + System.tap(self._target, test_x, test_y) + # Skip instructions + System.hswipe(self._target, 10, 80, duration=100, swipe_right=False) + System.hswipe(self._target, 10, 80, duration=100, swipe_right=False) + System.hswipe(self._target, 10, 80, duration=100, swipe_right=False) + self._log.info("Vellamo - {} started!".format(test_name.upper())) + + while True: + + # read next logcat line (up to max 1024 chars) + message = logcat.stdout.readline(1024) + + # Benchmark start trigger + if VELLAMO_BENCHMARK_START_RE.search(message): + # Start tracing + self.tracingStart() + self._log.debug("Benchmark started!") + + elif VELLAMO_BENCHMARK_END_RE.search(message): + # Stop tracing + self.tracingStop() + break + + else: + continue + + # Gather scores file from the device + db_file = os.path.join(out_dir, VELLAMO_SCORE_NAME) + self._target.pull('{}/{}'.format(VELLAMO_DB_PATH, VELLAMO_SCORE_NAME), + db_file) + + System.force_stop(self._target, self.package, clear=True) + + # Go back to home screen + System.home(self._target) + + # Set brightness back to auto + Screen.set_brightness(self._target, auto=True) + +# vim :set tabstop=4 shiftwidth=4 expandtab -- GitLab From be0e4a39eed215e826a6407a74092d5efb357fe0 Mon Sep 17 00:00:00 2001 From: Ionela Voinescu Date: Thu, 2 Feb 2017 18:26:37 +0000 Subject: [PATCH 3/3] tests/benchmarks/android_vellamo.py: initial implementation This provides an example of how to customize and execute an android vellamo workload. Signed-off-by: Ionela Voinescu --- tests/benchmarks/android_vellamo.py | 186 ++++++++++++++++++++++++++++ 1 file changed, 186 insertions(+) create mode 100755 tests/benchmarks/android_vellamo.py diff --git a/tests/benchmarks/android_vellamo.py b/tests/benchmarks/android_vellamo.py new file mode 100755 index 000000000..8afea2246 --- /dev/null +++ b/tests/benchmarks/android_vellamo.py @@ -0,0 +1,186 @@ +#!/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 VellamoTest(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" : "AndroidVellamo", + + } + + # Android Workload to run + bm_name = 'Vellamo' + + # 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, reboot=False, delay_after_s=0): + self.reboot = reboot + self.governor = governor + self.test = test + self.delay_after_s = delay_after_s + super(VellamoTest, 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 + } + + 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 + +governors = [ + 'performance', + 'ondemand', + 'interactive', + 'sched', + 'schedutil', + 'powersave' +] + +tests = [ + 'BROWSER', + 'METAL', + 'MULTI' +] + + +# 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: + VellamoTest(governor, test, 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 -- GitLab