1*a65addddSAndroid Build Coastguard Worker#!/usr/bin/env python3 2*a65addddSAndroid Build Coastguard Worker# Copyright 2016 Google Inc. All Rights Reserved. 3*a65addddSAndroid Build Coastguard Worker# 4*a65addddSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); 5*a65addddSAndroid Build Coastguard Worker# you may not use this file except in compliance with the License. 6*a65addddSAndroid Build Coastguard Worker# You may obtain a copy of the License at 7*a65addddSAndroid Build Coastguard Worker# 8*a65addddSAndroid Build Coastguard Worker# http://www.apache.org/licenses/LICENSE-2.0 9*a65addddSAndroid Build Coastguard Worker# 10*a65addddSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software 11*a65addddSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS-IS" BASIS, 12*a65addddSAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*a65addddSAndroid Build Coastguard Worker# See the License for the specific language governing permissions and 14*a65addddSAndroid Build Coastguard Worker# limitations under the License. 15*a65addddSAndroid Build Coastguard Worker 16*a65addddSAndroid Build Coastguard Workerimport argparse 17*a65addddSAndroid Build Coastguard Workerimport re 18*a65addddSAndroid Build Coastguard Workerimport textwrap 19*a65addddSAndroid Build Coastguard Workerfrom collections import defaultdict 20*a65addddSAndroid Build Coastguard Workerfrom timeit import default_timer as timer 21*a65addddSAndroid Build Coastguard Workerimport tempfile 22*a65addddSAndroid Build Coastguard Workerimport os 23*a65addddSAndroid Build Coastguard Workerimport shutil 24*a65addddSAndroid Build Coastguard Workerimport itertools 25*a65addddSAndroid Build Coastguard Workerimport traceback 26*a65addddSAndroid Build Coastguard Workerfrom typing import Dict, List, Tuple, Optional, Any, TypeVar, Callable, Iterable 27*a65addddSAndroid Build Coastguard Worker 28*a65addddSAndroid Build Coastguard Workerimport numpy 29*a65addddSAndroid Build Coastguard Workerimport subprocess 30*a65addddSAndroid Build Coastguard Workerimport yaml 31*a65addddSAndroid Build Coastguard Workerfrom numpy import floor, log10 32*a65addddSAndroid Build Coastguard Workerimport scipy 33*a65addddSAndroid Build Coastguard Workerimport multiprocessing 34*a65addddSAndroid Build Coastguard Workerimport json 35*a65addddSAndroid Build Coastguard Workerimport statsmodels.stats.api as stats 36*a65addddSAndroid Build Coastguard Workerfrom generate_benchmark import generate_benchmark 37*a65addddSAndroid Build Coastguard Workerimport git 38*a65addddSAndroid Build Coastguard Workerfrom functools import lru_cache as memoize 39*a65addddSAndroid Build Coastguard Worker 40*a65addddSAndroid Build Coastguard Workerclass CommandFailedException(Exception): 41*a65addddSAndroid Build Coastguard Worker def __init__(self, command: List[str], stdout: str, stderr: str, error_code: str): 42*a65addddSAndroid Build Coastguard Worker self.command = command 43*a65addddSAndroid Build Coastguard Worker self.stdout = stdout 44*a65addddSAndroid Build Coastguard Worker self.stderr = stderr 45*a65addddSAndroid Build Coastguard Worker self.error_code = error_code 46*a65addddSAndroid Build Coastguard Worker 47*a65addddSAndroid Build Coastguard Worker def __str__(self): 48*a65addddSAndroid Build Coastguard Worker return textwrap.dedent('''\ 49*a65addddSAndroid Build Coastguard Worker Ran command: {command} 50*a65addddSAndroid Build Coastguard Worker Exit code {error_code} 51*a65addddSAndroid Build Coastguard Worker Stdout: 52*a65addddSAndroid Build Coastguard Worker {stdout} 53*a65addddSAndroid Build Coastguard Worker 54*a65addddSAndroid Build Coastguard Worker Stderr: 55*a65addddSAndroid Build Coastguard Worker {stderr} 56*a65addddSAndroid Build Coastguard Worker ''').format(command=self.command, error_code=self.error_code, stdout=self.stdout, stderr=self.stderr) 57*a65addddSAndroid Build Coastguard Worker 58*a65addddSAndroid Build Coastguard Workerdef run_command(executable: str, args: List[Any]=[], cwd: str=None, env: Dict[str, str]=None) -> Tuple[str, str]: 59*a65addddSAndroid Build Coastguard Worker args = [str(arg) for arg in args] 60*a65addddSAndroid Build Coastguard Worker command = [executable] + args 61*a65addddSAndroid Build Coastguard Worker try: 62*a65addddSAndroid Build Coastguard Worker p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True, cwd=cwd, 63*a65addddSAndroid Build Coastguard Worker env=env) 64*a65addddSAndroid Build Coastguard Worker (stdout, stderr) = p.communicate() 65*a65addddSAndroid Build Coastguard Worker except Exception as e: 66*a65addddSAndroid Build Coastguard Worker raise Exception("While executing: %s" % command) 67*a65addddSAndroid Build Coastguard Worker if p.returncode != 0: 68*a65addddSAndroid Build Coastguard Worker raise CommandFailedException(command, stdout, stderr, p.returncode) 69*a65addddSAndroid Build Coastguard Worker return (stdout, stderr) 70*a65addddSAndroid Build Coastguard Worker 71*a65addddSAndroid Build Coastguard Workercompile_flags = ['-O2', '-DNDEBUG'] 72*a65addddSAndroid Build Coastguard Worker 73*a65addddSAndroid Build Coastguard Workermake_args = ['-j', multiprocessing.cpu_count() + 1] 74*a65addddSAndroid Build Coastguard Worker 75*a65addddSAndroid Build Coastguard Workerdef parse_results(result_lines: List[str]) -> Dict[str, float]: 76*a65addddSAndroid Build Coastguard Worker """ 77*a65addddSAndroid Build Coastguard Worker Parses results from the format: 78*a65addddSAndroid Build Coastguard Worker ['Dimension name1 = 123', 79*a65addddSAndroid Build Coastguard Worker 'Long dimension name2 = 23.45'] 80*a65addddSAndroid Build Coastguard Worker 81*a65addddSAndroid Build Coastguard Worker Into a dict {'Dimension name1': 123.0, 'Dimension name2': 23.45} 82*a65addddSAndroid Build Coastguard Worker """ 83*a65addddSAndroid Build Coastguard Worker result_dict = dict() 84*a65addddSAndroid Build Coastguard Worker for line in result_lines: 85*a65addddSAndroid Build Coastguard Worker line_splits = line.split('=') 86*a65addddSAndroid Build Coastguard Worker metric = line_splits[0].strip() 87*a65addddSAndroid Build Coastguard Worker value = float(line_splits[1].strip()) 88*a65addddSAndroid Build Coastguard Worker result_dict[metric] = value 89*a65addddSAndroid Build Coastguard Worker return result_dict 90*a65addddSAndroid Build Coastguard Worker 91*a65addddSAndroid Build Coastguard Worker 92*a65addddSAndroid Build Coastguard Worker# We memoize the result since this might be called repeatedly and it's somewhat expensive. 93*a65addddSAndroid Build Coastguard Worker@memoize(maxsize=None) 94*a65addddSAndroid Build Coastguard Workerdef determine_compiler_name(compiler_executable_name: str) -> str: 95*a65addddSAndroid Build Coastguard Worker tmpdir = tempfile.gettempdir() + '/fruit-determine-compiler-version-dir' 96*a65addddSAndroid Build Coastguard Worker ensure_empty_dir(tmpdir) 97*a65addddSAndroid Build Coastguard Worker with open(tmpdir + '/CMakeLists.txt', 'w') as file: 98*a65addddSAndroid Build Coastguard Worker file.write('message("@@@${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION}@@@")\n') 99*a65addddSAndroid Build Coastguard Worker modified_env = os.environ.copy() 100*a65addddSAndroid Build Coastguard Worker modified_env['CXX'] = compiler_executable_name 101*a65addddSAndroid Build Coastguard Worker # By converting to a list, we force all output to be read (so the command execution is guaranteed to be complete after this line). 102*a65addddSAndroid Build Coastguard Worker # Otherwise, subsequent calls to determine_compiler_name might have trouble deleting the temporary directory because the cmake 103*a65addddSAndroid Build Coastguard Worker # process is still writing files in there. 104*a65addddSAndroid Build Coastguard Worker _, stderr = run_command('cmake', args=['.'], cwd=tmpdir, env=modified_env) 105*a65addddSAndroid Build Coastguard Worker cmake_output = stderr.splitlines() 106*a65addddSAndroid Build Coastguard Worker for line in cmake_output: 107*a65addddSAndroid Build Coastguard Worker re_result = re.search('@@@(.*)@@@', line) 108*a65addddSAndroid Build Coastguard Worker if re_result: 109*a65addddSAndroid Build Coastguard Worker pretty_name = re_result.group(1) 110*a65addddSAndroid Build Coastguard Worker # CMake calls GCC 'GNU', change it into 'GCC'. 111*a65addddSAndroid Build Coastguard Worker return pretty_name.replace('GNU ', 'GCC ') 112*a65addddSAndroid Build Coastguard Worker raise Exception('Unable to determine compiler. CMake output was: \n', cmake_output) 113*a65addddSAndroid Build Coastguard Worker 114*a65addddSAndroid Build Coastguard Worker 115*a65addddSAndroid Build Coastguard Worker# Returns a pair (sha256_hash, version_name), where version_name will be None if no version tag was found at HEAD. 116*a65addddSAndroid Build Coastguard Worker@memoize(maxsize=None) 117*a65addddSAndroid Build Coastguard Workerdef git_repo_info(repo_path: str) -> Tuple[str, str]: 118*a65addddSAndroid Build Coastguard Worker repo = git.Repo(repo_path) 119*a65addddSAndroid Build Coastguard Worker head_tags = [tag.name for tag in repo.tags if tag.commit == repo.head.commit and re.match('v[0-9].*', tag.name)] 120*a65addddSAndroid Build Coastguard Worker if head_tags == []: 121*a65addddSAndroid Build Coastguard Worker head_tag = None 122*a65addddSAndroid Build Coastguard Worker else: 123*a65addddSAndroid Build Coastguard Worker # There should be only 1 version at any given commit. 124*a65addddSAndroid Build Coastguard Worker [head_tag] = head_tags 125*a65addddSAndroid Build Coastguard Worker # Remove the 'v' prefix. 126*a65addddSAndroid Build Coastguard Worker head_tag = head_tag[1:] 127*a65addddSAndroid Build Coastguard Worker return (repo.head.commit.hexsha, head_tag) 128*a65addddSAndroid Build Coastguard Worker 129*a65addddSAndroid Build Coastguard Worker 130*a65addddSAndroid Build Coastguard Worker# Some benchmark parameters, e.g. 'compiler_name' are synthesized automatically from other dimensions (e.g. 'compiler' dimension) or from the environment. 131*a65addddSAndroid Build Coastguard Worker# We put the compiler name/version in the results because the same 'compiler' value might refer to different compiler versions 132*a65addddSAndroid Build Coastguard Worker# (e.g. if GCC 6.0.0 is installed when benchmarks are run, then it's updated to GCC 6.0.1 and finally the results are formatted, we 133*a65addddSAndroid Build Coastguard Worker# want the formatted results to say "GCC 6.0.0" instead of "GCC 6.0.1"). 134*a65addddSAndroid Build Coastguard Workerdef add_synthetic_benchmark_parameters(original_benchmark_parameters: Dict[str, Any], path_to_code_under_test: Optional[str]): 135*a65addddSAndroid Build Coastguard Worker benchmark_params = original_benchmark_parameters.copy() 136*a65addddSAndroid Build Coastguard Worker benchmark_params['compiler_name'] = determine_compiler_name(original_benchmark_parameters['compiler']) 137*a65addddSAndroid Build Coastguard Worker if path_to_code_under_test is not None: 138*a65addddSAndroid Build Coastguard Worker sha256_hash, version_name = git_repo_info(path_to_code_under_test) 139*a65addddSAndroid Build Coastguard Worker benchmark_params['di_library_git_commit_hash'] = sha256_hash 140*a65addddSAndroid Build Coastguard Worker if version_name is not None: 141*a65addddSAndroid Build Coastguard Worker benchmark_params['di_library_version_name'] = version_name 142*a65addddSAndroid Build Coastguard Worker return benchmark_params 143*a65addddSAndroid Build Coastguard Worker 144*a65addddSAndroid Build Coastguard Worker 145*a65addddSAndroid Build Coastguard Workerclass Benchmark: 146*a65addddSAndroid Build Coastguard Worker def prepare(self) -> None: ... 147*a65addddSAndroid Build Coastguard Worker def run(self) -> Dict[str, float]: ... 148*a65addddSAndroid Build Coastguard Worker def describe(self) -> str: ... 149*a65addddSAndroid Build Coastguard Worker 150*a65addddSAndroid Build Coastguard Workerclass SimpleNewDeleteRunTimeBenchmark(Benchmark): 151*a65addddSAndroid Build Coastguard Worker def __init__(self, benchmark_definition: Dict[str, Any], fruit_benchmark_sources_dir: str): 152*a65addddSAndroid Build Coastguard Worker self.benchmark_definition = add_synthetic_benchmark_parameters(benchmark_definition, path_to_code_under_test=None) 153*a65addddSAndroid Build Coastguard Worker self.fruit_benchmark_sources_dir = fruit_benchmark_sources_dir 154*a65addddSAndroid Build Coastguard Worker 155*a65addddSAndroid Build Coastguard Worker def prepare(self): 156*a65addddSAndroid Build Coastguard Worker cxx_std = self.benchmark_definition['cxx_std'] 157*a65addddSAndroid Build Coastguard Worker num_classes = self.benchmark_definition['num_classes'] 158*a65addddSAndroid Build Coastguard Worker compiler_executable_name = self.benchmark_definition['compiler'] 159*a65addddSAndroid Build Coastguard Worker 160*a65addddSAndroid Build Coastguard Worker self.tmpdir = tempfile.gettempdir() + '/fruit-benchmark-dir' 161*a65addddSAndroid Build Coastguard Worker ensure_empty_dir(self.tmpdir) 162*a65addddSAndroid Build Coastguard Worker run_command(compiler_executable_name, 163*a65addddSAndroid Build Coastguard Worker args=compile_flags + [ 164*a65addddSAndroid Build Coastguard Worker '-std=%s' % cxx_std, 165*a65addddSAndroid Build Coastguard Worker '-DMULTIPLIER=%s' % num_classes, 166*a65addddSAndroid Build Coastguard Worker self.fruit_benchmark_sources_dir + '/extras/benchmark/new_delete_benchmark.cpp', 167*a65addddSAndroid Build Coastguard Worker '-o', 168*a65addddSAndroid Build Coastguard Worker self.tmpdir + '/main', 169*a65addddSAndroid Build Coastguard Worker ]) 170*a65addddSAndroid Build Coastguard Worker 171*a65addddSAndroid Build Coastguard Worker def run(self): 172*a65addddSAndroid Build Coastguard Worker loop_factor = self.benchmark_definition['loop_factor'] 173*a65addddSAndroid Build Coastguard Worker stdout, _ = run_command(self.tmpdir + '/main', args = [int(5000000 * loop_factor)]) 174*a65addddSAndroid Build Coastguard Worker return parse_results(stdout.splitlines()) 175*a65addddSAndroid Build Coastguard Worker 176*a65addddSAndroid Build Coastguard Worker def describe(self): 177*a65addddSAndroid Build Coastguard Worker return self.benchmark_definition 178*a65addddSAndroid Build Coastguard Worker 179*a65addddSAndroid Build Coastguard Worker 180*a65addddSAndroid Build Coastguard Workerclass FruitSingleFileCompileTimeBenchmark(Benchmark): 181*a65addddSAndroid Build Coastguard Worker def __init__(self, benchmark_definition: Dict[str, Any], fruit_sources_dir: str, fruit_build_dir: str, fruit_benchmark_sources_dir: str): 182*a65addddSAndroid Build Coastguard Worker self.benchmark_definition = add_synthetic_benchmark_parameters(benchmark_definition, path_to_code_under_test=fruit_sources_dir) 183*a65addddSAndroid Build Coastguard Worker self.fruit_sources_dir = fruit_sources_dir 184*a65addddSAndroid Build Coastguard Worker self.fruit_build_dir = fruit_build_dir 185*a65addddSAndroid Build Coastguard Worker self.fruit_benchmark_sources_dir = fruit_benchmark_sources_dir 186*a65addddSAndroid Build Coastguard Worker num_bindings = self.benchmark_definition['num_bindings'] 187*a65addddSAndroid Build Coastguard Worker assert (num_bindings % 5) == 0, num_bindings 188*a65addddSAndroid Build Coastguard Worker 189*a65addddSAndroid Build Coastguard Worker def prepare(self): 190*a65addddSAndroid Build Coastguard Worker pass 191*a65addddSAndroid Build Coastguard Worker 192*a65addddSAndroid Build Coastguard Worker def run(self): 193*a65addddSAndroid Build Coastguard Worker start = timer() 194*a65addddSAndroid Build Coastguard Worker cxx_std = self.benchmark_definition['cxx_std'] 195*a65addddSAndroid Build Coastguard Worker num_bindings = self.benchmark_definition['num_bindings'] 196*a65addddSAndroid Build Coastguard Worker compiler_executable_name = self.benchmark_definition['compiler'] 197*a65addddSAndroid Build Coastguard Worker 198*a65addddSAndroid Build Coastguard Worker run_command(compiler_executable_name, 199*a65addddSAndroid Build Coastguard Worker args = compile_flags + [ 200*a65addddSAndroid Build Coastguard Worker '-std=%s' % cxx_std, 201*a65addddSAndroid Build Coastguard Worker '-DMULTIPLIER=%s' % (num_bindings // 5), 202*a65addddSAndroid Build Coastguard Worker '-I', self.fruit_sources_dir + '/include', 203*a65addddSAndroid Build Coastguard Worker '-I', self.fruit_build_dir + '/include', 204*a65addddSAndroid Build Coastguard Worker '-ftemplate-depth=1000', 205*a65addddSAndroid Build Coastguard Worker '-c', 206*a65addddSAndroid Build Coastguard Worker self.fruit_benchmark_sources_dir + '/extras/benchmark/compile_time_benchmark.cpp', 207*a65addddSAndroid Build Coastguard Worker '-o', 208*a65addddSAndroid Build Coastguard Worker '/dev/null', 209*a65addddSAndroid Build Coastguard Worker ]) 210*a65addddSAndroid Build Coastguard Worker end = timer() 211*a65addddSAndroid Build Coastguard Worker return {"compile_time": end - start} 212*a65addddSAndroid Build Coastguard Worker 213*a65addddSAndroid Build Coastguard Worker def describe(self): 214*a65addddSAndroid Build Coastguard Worker return self.benchmark_definition 215*a65addddSAndroid Build Coastguard Worker 216*a65addddSAndroid Build Coastguard Worker 217*a65addddSAndroid Build Coastguard Workerdef ensure_empty_dir(dirname: str): 218*a65addddSAndroid Build Coastguard Worker # We start by creating the directory instead of just calling rmtree with ignore_errors=True because that would ignore 219*a65addddSAndroid Build Coastguard Worker # all errors, so we might otherwise go ahead even if the directory wasn't properly deleted. 220*a65addddSAndroid Build Coastguard Worker os.makedirs(dirname, exist_ok=True) 221*a65addddSAndroid Build Coastguard Worker shutil.rmtree(dirname) 222*a65addddSAndroid Build Coastguard Worker os.makedirs(dirname) 223*a65addddSAndroid Build Coastguard Worker 224*a65addddSAndroid Build Coastguard Worker 225*a65addddSAndroid Build Coastguard Workerclass GenericGeneratedSourcesBenchmark(Benchmark): 226*a65addddSAndroid Build Coastguard Worker def __init__(self, 227*a65addddSAndroid Build Coastguard Worker di_library, 228*a65addddSAndroid Build Coastguard Worker benchmark_definition, 229*a65addddSAndroid Build Coastguard Worker path_to_code_under_test=None, 230*a65addddSAndroid Build Coastguard Worker **other_args): 231*a65addddSAndroid Build Coastguard Worker self.di_library = di_library 232*a65addddSAndroid Build Coastguard Worker self.benchmark_definition = add_synthetic_benchmark_parameters(benchmark_definition, path_to_code_under_test=path_to_code_under_test) 233*a65addddSAndroid Build Coastguard Worker self.other_args = other_args 234*a65addddSAndroid Build Coastguard Worker self.arbitrary_file = None 235*a65addddSAndroid Build Coastguard Worker 236*a65addddSAndroid Build Coastguard Worker def prepare_compile_benchmark(self): 237*a65addddSAndroid Build Coastguard Worker num_classes = self.benchmark_definition['num_classes'] 238*a65addddSAndroid Build Coastguard Worker cxx_std = self.benchmark_definition['cxx_std'] 239*a65addddSAndroid Build Coastguard Worker compiler_executable_name = self.benchmark_definition['compiler'] 240*a65addddSAndroid Build Coastguard Worker benchmark_generation_flags = {flag_name: True for flag_name in self.benchmark_definition['benchmark_generation_flags']} 241*a65addddSAndroid Build Coastguard Worker 242*a65addddSAndroid Build Coastguard Worker self.tmpdir = tempfile.gettempdir() + '/fruit-benchmark-dir' 243*a65addddSAndroid Build Coastguard Worker ensure_empty_dir(self.tmpdir) 244*a65addddSAndroid Build Coastguard Worker num_classes_with_no_deps = int(num_classes * 0.1) 245*a65addddSAndroid Build Coastguard Worker return generate_benchmark( 246*a65addddSAndroid Build Coastguard Worker compiler=compiler_executable_name, 247*a65addddSAndroid Build Coastguard Worker num_components_with_no_deps=num_classes_with_no_deps, 248*a65addddSAndroid Build Coastguard Worker num_components_with_deps=num_classes - num_classes_with_no_deps, 249*a65addddSAndroid Build Coastguard Worker num_deps=10, 250*a65addddSAndroid Build Coastguard Worker output_dir=self.tmpdir, 251*a65addddSAndroid Build Coastguard Worker cxx_std=cxx_std, 252*a65addddSAndroid Build Coastguard Worker di_library=self.di_library, 253*a65addddSAndroid Build Coastguard Worker **benchmark_generation_flags, 254*a65addddSAndroid Build Coastguard Worker **self.other_args) 255*a65addddSAndroid Build Coastguard Worker 256*a65addddSAndroid Build Coastguard Worker def run_make_build(self): 257*a65addddSAndroid Build Coastguard Worker run_command('make', args=make_args, cwd=self.tmpdir) 258*a65addddSAndroid Build Coastguard Worker 259*a65addddSAndroid Build Coastguard Worker def prepare_incremental_compile_benchmark(self): 260*a65addddSAndroid Build Coastguard Worker files = self.prepare_compile_benchmark() 261*a65addddSAndroid Build Coastguard Worker self.run_make_build() 262*a65addddSAndroid Build Coastguard Worker files = list(sorted(file for file in files if file.endswith('.h'))) 263*a65addddSAndroid Build Coastguard Worker # 5 files, equally spaced (but not at beginning/end) in the sorted sequence. 264*a65addddSAndroid Build Coastguard Worker num_files_changed = 5 265*a65addddSAndroid Build Coastguard Worker self.arbitrary_files = [files[i * (len(files) // (num_files_changed + 2))] 266*a65addddSAndroid Build Coastguard Worker for i in range(1, num_files_changed + 1)] 267*a65addddSAndroid Build Coastguard Worker 268*a65addddSAndroid Build Coastguard Worker def prepare_compile_memory_benchmark(self): 269*a65addddSAndroid Build Coastguard Worker self.prepare_compile_benchmark() 270*a65addddSAndroid Build Coastguard Worker self.run_compile_memory_benchmark() 271*a65addddSAndroid Build Coastguard Worker 272*a65addddSAndroid Build Coastguard Worker def prepare_runtime_benchmark(self): 273*a65addddSAndroid Build Coastguard Worker self.prepare_compile_benchmark() 274*a65addddSAndroid Build Coastguard Worker self.run_make_build() 275*a65addddSAndroid Build Coastguard Worker 276*a65addddSAndroid Build Coastguard Worker def prepare_startup_benchmark(self): 277*a65addddSAndroid Build Coastguard Worker self.prepare_compile_benchmark() 278*a65addddSAndroid Build Coastguard Worker self.run_make_build() 279*a65addddSAndroid Build Coastguard Worker run_command('strip', args=[self.tmpdir + '/main']) 280*a65addddSAndroid Build Coastguard Worker 281*a65addddSAndroid Build Coastguard Worker def prepare_executable_size_benchmark(self): 282*a65addddSAndroid Build Coastguard Worker self.prepare_runtime_benchmark() 283*a65addddSAndroid Build Coastguard Worker run_command('strip', args=[self.tmpdir + '/main']) 284*a65addddSAndroid Build Coastguard Worker 285*a65addddSAndroid Build Coastguard Worker def run_compile_benchmark(self): 286*a65addddSAndroid Build Coastguard Worker run_command('make', 287*a65addddSAndroid Build Coastguard Worker args=make_args + ['clean'], 288*a65addddSAndroid Build Coastguard Worker cwd=self.tmpdir) 289*a65addddSAndroid Build Coastguard Worker start = timer() 290*a65addddSAndroid Build Coastguard Worker self.run_make_build() 291*a65addddSAndroid Build Coastguard Worker end = timer() 292*a65addddSAndroid Build Coastguard Worker result = {'compile_time': end - start} 293*a65addddSAndroid Build Coastguard Worker return result 294*a65addddSAndroid Build Coastguard Worker 295*a65addddSAndroid Build Coastguard Worker def run_incremental_compile_benchmark(self): 296*a65addddSAndroid Build Coastguard Worker run_command('touch', args=self.arbitrary_files, cwd=self.tmpdir) 297*a65addddSAndroid Build Coastguard Worker start = timer() 298*a65addddSAndroid Build Coastguard Worker self.run_make_build() 299*a65addddSAndroid Build Coastguard Worker end = timer() 300*a65addddSAndroid Build Coastguard Worker result = {'incremental_compile_time': end - start} 301*a65addddSAndroid Build Coastguard Worker return result 302*a65addddSAndroid Build Coastguard Worker 303*a65addddSAndroid Build Coastguard Worker def run_compile_memory_benchmark(self): 304*a65addddSAndroid Build Coastguard Worker run_command('make', args=make_args + ['clean'], cwd=self.tmpdir) 305*a65addddSAndroid Build Coastguard Worker run_command('make', args=make_args + ['main_ram.txt'], cwd=self.tmpdir) 306*a65addddSAndroid Build Coastguard Worker with open(self.tmpdir + '/main_ram.txt') as f: 307*a65addddSAndroid Build Coastguard Worker ram_usages = [int(n)*1024 for n in f.readlines()] 308*a65addddSAndroid Build Coastguard Worker return { 309*a65addddSAndroid Build Coastguard Worker 'total_max_ram_usage': sum(ram_usages), 310*a65addddSAndroid Build Coastguard Worker 'max_ram_usage': max(ram_usages), 311*a65addddSAndroid Build Coastguard Worker } 312*a65addddSAndroid Build Coastguard Worker 313*a65addddSAndroid Build Coastguard Worker def run_runtime_benchmark(self): 314*a65addddSAndroid Build Coastguard Worker num_classes = self.benchmark_definition['num_classes'] 315*a65addddSAndroid Build Coastguard Worker loop_factor = self.benchmark_definition['loop_factor'] 316*a65addddSAndroid Build Coastguard Worker 317*a65addddSAndroid Build Coastguard Worker results, _ = run_command(self.tmpdir + '/main', 318*a65addddSAndroid Build Coastguard Worker args = [ 319*a65addddSAndroid Build Coastguard Worker # 40M loops with 100 classes, 40M with 1000 320*a65addddSAndroid Build Coastguard Worker int(4 * 1000 * 1000 * 1000 * loop_factor / num_classes), 321*a65addddSAndroid Build Coastguard Worker ]) 322*a65addddSAndroid Build Coastguard Worker return parse_results(results.splitlines()) 323*a65addddSAndroid Build Coastguard Worker 324*a65addddSAndroid Build Coastguard Worker def run_startup_benchmark(self): 325*a65addddSAndroid Build Coastguard Worker n = 1000 326*a65addddSAndroid Build Coastguard Worker start = timer() 327*a65addddSAndroid Build Coastguard Worker for i in range(0, n): 328*a65addddSAndroid Build Coastguard Worker run_command(self.tmpdir + '/main', args = []) 329*a65addddSAndroid Build Coastguard Worker end = timer() 330*a65addddSAndroid Build Coastguard Worker result = {'startup_time': (end - start) / n} 331*a65addddSAndroid Build Coastguard Worker return result 332*a65addddSAndroid Build Coastguard Worker 333*a65addddSAndroid Build Coastguard Worker def run_executable_size_benchmark(self): 334*a65addddSAndroid Build Coastguard Worker wc_result, _ = run_command('wc', args=['-c', self.tmpdir + '/main']) 335*a65addddSAndroid Build Coastguard Worker num_bytes = wc_result.splitlines()[0].split(' ')[0] 336*a65addddSAndroid Build Coastguard Worker return {'num_bytes': float(num_bytes)} 337*a65addddSAndroid Build Coastguard Worker 338*a65addddSAndroid Build Coastguard Worker def describe(self): 339*a65addddSAndroid Build Coastguard Worker return self.benchmark_definition 340*a65addddSAndroid Build Coastguard Worker 341*a65addddSAndroid Build Coastguard Worker 342*a65addddSAndroid Build Coastguard Workerclass CompileTimeBenchmark(GenericGeneratedSourcesBenchmark): 343*a65addddSAndroid Build Coastguard Worker def __init__(self, **kwargs): 344*a65addddSAndroid Build Coastguard Worker super().__init__(generate_runtime_bench_code=False, 345*a65addddSAndroid Build Coastguard Worker **kwargs) 346*a65addddSAndroid Build Coastguard Worker 347*a65addddSAndroid Build Coastguard Worker def prepare(self): 348*a65addddSAndroid Build Coastguard Worker self.prepare_compile_benchmark() 349*a65addddSAndroid Build Coastguard Worker 350*a65addddSAndroid Build Coastguard Worker def run(self): 351*a65addddSAndroid Build Coastguard Worker return self.run_compile_benchmark() 352*a65addddSAndroid Build Coastguard Worker 353*a65addddSAndroid Build Coastguard Workerclass IncrementalCompileTimeBenchmark(GenericGeneratedSourcesBenchmark): 354*a65addddSAndroid Build Coastguard Worker def __init__(self, **kwargs): 355*a65addddSAndroid Build Coastguard Worker super().__init__(generate_runtime_bench_code=False, 356*a65addddSAndroid Build Coastguard Worker **kwargs) 357*a65addddSAndroid Build Coastguard Worker 358*a65addddSAndroid Build Coastguard Worker def prepare(self): 359*a65addddSAndroid Build Coastguard Worker self.prepare_incremental_compile_benchmark() 360*a65addddSAndroid Build Coastguard Worker 361*a65addddSAndroid Build Coastguard Worker def run(self): 362*a65addddSAndroid Build Coastguard Worker return self.run_incremental_compile_benchmark() 363*a65addddSAndroid Build Coastguard Worker 364*a65addddSAndroid Build Coastguard Workerclass CompileMemoryBenchmark(GenericGeneratedSourcesBenchmark): 365*a65addddSAndroid Build Coastguard Worker def __init__(self, **kwargs): 366*a65addddSAndroid Build Coastguard Worker super().__init__(generate_runtime_bench_code=False, 367*a65addddSAndroid Build Coastguard Worker **kwargs) 368*a65addddSAndroid Build Coastguard Worker 369*a65addddSAndroid Build Coastguard Worker def prepare(self): 370*a65addddSAndroid Build Coastguard Worker self.prepare_compile_memory_benchmark() 371*a65addddSAndroid Build Coastguard Worker 372*a65addddSAndroid Build Coastguard Worker def run(self): 373*a65addddSAndroid Build Coastguard Worker return self.run_compile_memory_benchmark() 374*a65addddSAndroid Build Coastguard Worker 375*a65addddSAndroid Build Coastguard Workerclass StartupTimeBenchmark(GenericGeneratedSourcesBenchmark): 376*a65addddSAndroid Build Coastguard Worker def __init__(self, **kwargs): 377*a65addddSAndroid Build Coastguard Worker super().__init__(generate_runtime_bench_code=False, 378*a65addddSAndroid Build Coastguard Worker **kwargs) 379*a65addddSAndroid Build Coastguard Worker 380*a65addddSAndroid Build Coastguard Worker def prepare(self): 381*a65addddSAndroid Build Coastguard Worker self.prepare_startup_benchmark() 382*a65addddSAndroid Build Coastguard Worker 383*a65addddSAndroid Build Coastguard Worker def run(self): 384*a65addddSAndroid Build Coastguard Worker return self.run_startup_benchmark() 385*a65addddSAndroid Build Coastguard Worker 386*a65addddSAndroid Build Coastguard Workerclass RunTimeBenchmark(GenericGeneratedSourcesBenchmark): 387*a65addddSAndroid Build Coastguard Worker def __init__(self, **kwargs): 388*a65addddSAndroid Build Coastguard Worker super().__init__(generate_runtime_bench_code=True, 389*a65addddSAndroid Build Coastguard Worker **kwargs) 390*a65addddSAndroid Build Coastguard Worker 391*a65addddSAndroid Build Coastguard Worker def prepare(self): 392*a65addddSAndroid Build Coastguard Worker self.prepare_runtime_benchmark() 393*a65addddSAndroid Build Coastguard Worker 394*a65addddSAndroid Build Coastguard Worker def run(self): 395*a65addddSAndroid Build Coastguard Worker return self.run_runtime_benchmark() 396*a65addddSAndroid Build Coastguard Worker 397*a65addddSAndroid Build Coastguard Worker# This is not really a 'benchmark', but we consider it as such to reuse the benchmark infrastructure. 398*a65addddSAndroid Build Coastguard Workerclass ExecutableSizeBenchmark(GenericGeneratedSourcesBenchmark): 399*a65addddSAndroid Build Coastguard Worker def __init__(self, **kwargs): 400*a65addddSAndroid Build Coastguard Worker super().__init__(generate_runtime_bench_code=False, 401*a65addddSAndroid Build Coastguard Worker **kwargs) 402*a65addddSAndroid Build Coastguard Worker 403*a65addddSAndroid Build Coastguard Worker def prepare(self): 404*a65addddSAndroid Build Coastguard Worker self.prepare_executable_size_benchmark() 405*a65addddSAndroid Build Coastguard Worker 406*a65addddSAndroid Build Coastguard Worker def run(self): 407*a65addddSAndroid Build Coastguard Worker return self.run_executable_size_benchmark() 408*a65addddSAndroid Build Coastguard Worker 409*a65addddSAndroid Build Coastguard Worker# This is not really a 'benchmark', but we consider it as such to reuse the benchmark infrastructure. 410*a65addddSAndroid Build Coastguard Workerclass ExecutableSizeBenchmarkWithoutExceptionsAndRtti(ExecutableSizeBenchmark): 411*a65addddSAndroid Build Coastguard Worker def __init__(self, **kwargs): 412*a65addddSAndroid Build Coastguard Worker super().__init__(use_exceptions=False, 413*a65addddSAndroid Build Coastguard Worker use_rtti=False, 414*a65addddSAndroid Build Coastguard Worker **kwargs) 415*a65addddSAndroid Build Coastguard Worker 416*a65addddSAndroid Build Coastguard Workerclass FruitCompileTimeBenchmark(CompileTimeBenchmark): 417*a65addddSAndroid Build Coastguard Worker def __init__(self, fruit_sources_dir, **kwargs): 418*a65addddSAndroid Build Coastguard Worker super().__init__(di_library='fruit', 419*a65addddSAndroid Build Coastguard Worker path_to_code_under_test=fruit_sources_dir, 420*a65addddSAndroid Build Coastguard Worker fruit_sources_dir=fruit_sources_dir, 421*a65addddSAndroid Build Coastguard Worker **kwargs) 422*a65addddSAndroid Build Coastguard Worker 423*a65addddSAndroid Build Coastguard Workerclass FruitIncrementalCompileTimeBenchmark(IncrementalCompileTimeBenchmark): 424*a65addddSAndroid Build Coastguard Worker def __init__(self, fruit_sources_dir, **kwargs): 425*a65addddSAndroid Build Coastguard Worker super().__init__(di_library='fruit', 426*a65addddSAndroid Build Coastguard Worker path_to_code_under_test=fruit_sources_dir, 427*a65addddSAndroid Build Coastguard Worker fruit_sources_dir=fruit_sources_dir, 428*a65addddSAndroid Build Coastguard Worker **kwargs) 429*a65addddSAndroid Build Coastguard Worker 430*a65addddSAndroid Build Coastguard Workerclass FruitCompileMemoryBenchmark(CompileMemoryBenchmark): 431*a65addddSAndroid Build Coastguard Worker def __init__(self, fruit_sources_dir, **kwargs): 432*a65addddSAndroid Build Coastguard Worker super().__init__(di_library='fruit', 433*a65addddSAndroid Build Coastguard Worker path_to_code_under_test=fruit_sources_dir, 434*a65addddSAndroid Build Coastguard Worker fruit_sources_dir=fruit_sources_dir, 435*a65addddSAndroid Build Coastguard Worker **kwargs) 436*a65addddSAndroid Build Coastguard Worker 437*a65addddSAndroid Build Coastguard Workerclass FruitRunTimeBenchmark(RunTimeBenchmark): 438*a65addddSAndroid Build Coastguard Worker def __init__(self, fruit_sources_dir, **kwargs): 439*a65addddSAndroid Build Coastguard Worker super().__init__(di_library='fruit', 440*a65addddSAndroid Build Coastguard Worker path_to_code_under_test=fruit_sources_dir, 441*a65addddSAndroid Build Coastguard Worker fruit_sources_dir=fruit_sources_dir, 442*a65addddSAndroid Build Coastguard Worker **kwargs) 443*a65addddSAndroid Build Coastguard Worker 444*a65addddSAndroid Build Coastguard Workerclass FruitStartupTimeBenchmark(StartupTimeBenchmark): 445*a65addddSAndroid Build Coastguard Worker def __init__(self, fruit_sources_dir, **kwargs): 446*a65addddSAndroid Build Coastguard Worker super().__init__(di_library='fruit', 447*a65addddSAndroid Build Coastguard Worker path_to_code_under_test=fruit_sources_dir, 448*a65addddSAndroid Build Coastguard Worker fruit_sources_dir=fruit_sources_dir, 449*a65addddSAndroid Build Coastguard Worker **kwargs) 450*a65addddSAndroid Build Coastguard Worker 451*a65addddSAndroid Build Coastguard Workerclass FruitStartupTimeWithNormalizedComponentBenchmark(FruitStartupTimeBenchmark): 452*a65addddSAndroid Build Coastguard Worker def __init__(self, **kwargs): 453*a65addddSAndroid Build Coastguard Worker super().__init__(use_normalized_component=True, 454*a65addddSAndroid Build Coastguard Worker **kwargs) 455*a65addddSAndroid Build Coastguard Worker 456*a65addddSAndroid Build Coastguard Worker# This is not really a 'benchmark', but we consider it as such to reuse the benchmark infrastructure. 457*a65addddSAndroid Build Coastguard Workerclass FruitExecutableSizeBenchmark(ExecutableSizeBenchmark): 458*a65addddSAndroid Build Coastguard Worker def __init__(self, fruit_sources_dir, **kwargs): 459*a65addddSAndroid Build Coastguard Worker super().__init__(di_library='fruit', 460*a65addddSAndroid Build Coastguard Worker path_to_code_under_test=fruit_sources_dir, 461*a65addddSAndroid Build Coastguard Worker fruit_sources_dir=fruit_sources_dir, 462*a65addddSAndroid Build Coastguard Worker **kwargs) 463*a65addddSAndroid Build Coastguard Worker 464*a65addddSAndroid Build Coastguard Worker# This is not really a 'benchmark', but we consider it as such to reuse the benchmark infrastructure. 465*a65addddSAndroid Build Coastguard Workerclass FruitExecutableSizeBenchmarkWithoutExceptionsAndRtti(ExecutableSizeBenchmarkWithoutExceptionsAndRtti): 466*a65addddSAndroid Build Coastguard Worker def __init__(self, fruit_sources_dir, **kwargs): 467*a65addddSAndroid Build Coastguard Worker super().__init__(di_library='fruit', 468*a65addddSAndroid Build Coastguard Worker path_to_code_under_test=fruit_sources_dir, 469*a65addddSAndroid Build Coastguard Worker fruit_sources_dir=fruit_sources_dir, 470*a65addddSAndroid Build Coastguard Worker **kwargs) 471*a65addddSAndroid Build Coastguard Worker 472*a65addddSAndroid Build Coastguard Workerclass BoostDiCompileTimeBenchmark(CompileTimeBenchmark): 473*a65addddSAndroid Build Coastguard Worker def __init__(self, boost_di_sources_dir, **kwargs): 474*a65addddSAndroid Build Coastguard Worker super().__init__(di_library='boost_di', 475*a65addddSAndroid Build Coastguard Worker path_to_code_under_test=boost_di_sources_dir, 476*a65addddSAndroid Build Coastguard Worker boost_di_sources_dir=boost_di_sources_dir, 477*a65addddSAndroid Build Coastguard Worker **kwargs) 478*a65addddSAndroid Build Coastguard Worker 479*a65addddSAndroid Build Coastguard Workerclass BoostDiIncrementalCompileTimeBenchmark(IncrementalCompileTimeBenchmark): 480*a65addddSAndroid Build Coastguard Worker def __init__(self, boost_di_sources_dir, **kwargs): 481*a65addddSAndroid Build Coastguard Worker super().__init__(di_library='boost_di', 482*a65addddSAndroid Build Coastguard Worker path_to_code_under_test=boost_di_sources_dir, 483*a65addddSAndroid Build Coastguard Worker boost_di_sources_dir=boost_di_sources_dir, 484*a65addddSAndroid Build Coastguard Worker **kwargs) 485*a65addddSAndroid Build Coastguard Worker 486*a65addddSAndroid Build Coastguard Workerclass BoostDiCompileMemoryBenchmark(CompileMemoryBenchmark): 487*a65addddSAndroid Build Coastguard Worker def __init__(self, boost_di_sources_dir, **kwargs): 488*a65addddSAndroid Build Coastguard Worker super().__init__(di_library='boost_di', 489*a65addddSAndroid Build Coastguard Worker path_to_code_under_test=boost_di_sources_dir, 490*a65addddSAndroid Build Coastguard Worker boost_di_sources_dir=boost_di_sources_dir, 491*a65addddSAndroid Build Coastguard Worker **kwargs) 492*a65addddSAndroid Build Coastguard Worker 493*a65addddSAndroid Build Coastguard Workerclass BoostDiRunTimeBenchmark(RunTimeBenchmark): 494*a65addddSAndroid Build Coastguard Worker def __init__(self, boost_di_sources_dir, **kwargs): 495*a65addddSAndroid Build Coastguard Worker super().__init__(di_library='boost_di', 496*a65addddSAndroid Build Coastguard Worker path_to_code_under_test=boost_di_sources_dir, 497*a65addddSAndroid Build Coastguard Worker boost_di_sources_dir=boost_di_sources_dir, 498*a65addddSAndroid Build Coastguard Worker **kwargs) 499*a65addddSAndroid Build Coastguard Worker 500*a65addddSAndroid Build Coastguard Workerclass BoostDiStartupTimeBenchmark(StartupTimeBenchmark): 501*a65addddSAndroid Build Coastguard Worker def __init__(self, boost_di_sources_dir, **kwargs): 502*a65addddSAndroid Build Coastguard Worker super().__init__(di_library='boost_di', 503*a65addddSAndroid Build Coastguard Worker path_to_code_under_test=boost_di_sources_dir, 504*a65addddSAndroid Build Coastguard Worker boost_di_sources_dir=boost_di_sources_dir, 505*a65addddSAndroid Build Coastguard Worker **kwargs) 506*a65addddSAndroid Build Coastguard Worker 507*a65addddSAndroid Build Coastguard Worker# This is not really a 'benchmark', but we consider it as such to reuse the benchmark infrastructure. 508*a65addddSAndroid Build Coastguard Workerclass BoostDiExecutableSizeBenchmark(ExecutableSizeBenchmark): 509*a65addddSAndroid Build Coastguard Worker def __init__(self, boost_di_sources_dir, **kwargs): 510*a65addddSAndroid Build Coastguard Worker super().__init__(di_library='boost_di', 511*a65addddSAndroid Build Coastguard Worker path_to_code_under_test=boost_di_sources_dir, 512*a65addddSAndroid Build Coastguard Worker boost_di_sources_dir=boost_di_sources_dir, 513*a65addddSAndroid Build Coastguard Worker **kwargs) 514*a65addddSAndroid Build Coastguard Worker 515*a65addddSAndroid Build Coastguard Worker# This is not really a 'benchmark', but we consider it as such to reuse the benchmark infrastructure. 516*a65addddSAndroid Build Coastguard Workerclass BoostDiExecutableSizeBenchmarkWithoutExceptionsAndRtti(ExecutableSizeBenchmarkWithoutExceptionsAndRtti): 517*a65addddSAndroid Build Coastguard Worker def __init__(self, boost_di_sources_dir, **kwargs): 518*a65addddSAndroid Build Coastguard Worker super().__init__(di_library='boost_di', 519*a65addddSAndroid Build Coastguard Worker path_to_code_under_test=boost_di_sources_dir, 520*a65addddSAndroid Build Coastguard Worker boost_di_sources_dir=boost_di_sources_dir, 521*a65addddSAndroid Build Coastguard Worker **kwargs) 522*a65addddSAndroid Build Coastguard Worker 523*a65addddSAndroid Build Coastguard Workerclass SimpleDiCompileTimeBenchmark(CompileTimeBenchmark): 524*a65addddSAndroid Build Coastguard Worker def __init__(self, **kwargs): 525*a65addddSAndroid Build Coastguard Worker super().__init__(di_library='none', 526*a65addddSAndroid Build Coastguard Worker **kwargs) 527*a65addddSAndroid Build Coastguard Worker 528*a65addddSAndroid Build Coastguard Workerclass SimpleDiIncrementalCompileTimeBenchmark(IncrementalCompileTimeBenchmark): 529*a65addddSAndroid Build Coastguard Worker def __init__(self, **kwargs): 530*a65addddSAndroid Build Coastguard Worker super().__init__(di_library='none', 531*a65addddSAndroid Build Coastguard Worker **kwargs) 532*a65addddSAndroid Build Coastguard Worker 533*a65addddSAndroid Build Coastguard Workerclass SimpleDiCompileMemoryBenchmark(CompileMemoryBenchmark): 534*a65addddSAndroid Build Coastguard Worker def __init__(self, **kwargs): 535*a65addddSAndroid Build Coastguard Worker super().__init__(di_library='none', 536*a65addddSAndroid Build Coastguard Worker **kwargs) 537*a65addddSAndroid Build Coastguard Worker 538*a65addddSAndroid Build Coastguard Workerclass SimpleDiRunTimeBenchmark(RunTimeBenchmark): 539*a65addddSAndroid Build Coastguard Worker def __init__(self, **kwargs): 540*a65addddSAndroid Build Coastguard Worker super().__init__(di_library='none', 541*a65addddSAndroid Build Coastguard Worker **kwargs) 542*a65addddSAndroid Build Coastguard Worker 543*a65addddSAndroid Build Coastguard Workerclass SimpleDiStartupTimeBenchmark(StartupTimeBenchmark): 544*a65addddSAndroid Build Coastguard Worker def __init__(self, **kwargs): 545*a65addddSAndroid Build Coastguard Worker super().__init__(di_library='none', 546*a65addddSAndroid Build Coastguard Worker **kwargs) 547*a65addddSAndroid Build Coastguard Worker 548*a65addddSAndroid Build Coastguard Worker# This is not really a 'benchmark', but we consider it as such to reuse the benchmark infrastructure. 549*a65addddSAndroid Build Coastguard Workerclass SimpleDiExecutableSizeBenchmark(ExecutableSizeBenchmark): 550*a65addddSAndroid Build Coastguard Worker def __init__(self, **kwargs): 551*a65addddSAndroid Build Coastguard Worker super().__init__(di_library='none', 552*a65addddSAndroid Build Coastguard Worker **kwargs) 553*a65addddSAndroid Build Coastguard Worker 554*a65addddSAndroid Build Coastguard Worker# This is not really a 'benchmark', but we consider it as such to reuse the benchmark infrastructure. 555*a65addddSAndroid Build Coastguard Workerclass SimpleDiExecutableSizeBenchmarkWithoutExceptionsAndRtti(ExecutableSizeBenchmarkWithoutExceptionsAndRtti): 556*a65addddSAndroid Build Coastguard Worker def __init__(self, **kwargs): 557*a65addddSAndroid Build Coastguard Worker super().__init__(di_library='none', 558*a65addddSAndroid Build Coastguard Worker **kwargs) 559*a65addddSAndroid Build Coastguard Worker 560*a65addddSAndroid Build Coastguard Workerclass SimpleDiWithInterfacesCompileTimeBenchmark(SimpleDiCompileTimeBenchmark): 561*a65addddSAndroid Build Coastguard Worker def __init__(self, **kwargs): 562*a65addddSAndroid Build Coastguard Worker super().__init__(use_interfaces=True, **kwargs) 563*a65addddSAndroid Build Coastguard Worker 564*a65addddSAndroid Build Coastguard Workerclass SimpleDiWithInterfacesIncrementalCompileTimeBenchmark(SimpleDiIncrementalCompileTimeBenchmark): 565*a65addddSAndroid Build Coastguard Worker def __init__(self, **kwargs): 566*a65addddSAndroid Build Coastguard Worker super().__init__(use_interfaces=True, **kwargs) 567*a65addddSAndroid Build Coastguard Worker 568*a65addddSAndroid Build Coastguard Workerclass SimpleDiWithInterfacesCompileMemoryBenchmark(SimpleDiCompileMemoryBenchmark): 569*a65addddSAndroid Build Coastguard Worker def __init__(self, **kwargs): 570*a65addddSAndroid Build Coastguard Worker super().__init__(use_interfaces=True, **kwargs) 571*a65addddSAndroid Build Coastguard Worker 572*a65addddSAndroid Build Coastguard Workerclass SimpleDiWithInterfacesRunTimeBenchmark(SimpleDiRunTimeBenchmark): 573*a65addddSAndroid Build Coastguard Worker def __init__(self, **kwargs): 574*a65addddSAndroid Build Coastguard Worker super().__init__(use_interfaces=True, **kwargs) 575*a65addddSAndroid Build Coastguard Worker 576*a65addddSAndroid Build Coastguard Workerclass SimpleDiWithInterfacesStartupTimeBenchmark(SimpleDiStartupTimeBenchmark): 577*a65addddSAndroid Build Coastguard Worker def __init__(self, **kwargs): 578*a65addddSAndroid Build Coastguard Worker super().__init__(use_interfaces=True, **kwargs) 579*a65addddSAndroid Build Coastguard Worker 580*a65addddSAndroid Build Coastguard Worker# This is not really a 'benchmark', but we consider it as such to reuse the benchmark infrastructure. 581*a65addddSAndroid Build Coastguard Workerclass SimpleDiWithInterfacesExecutableSizeBenchmark(SimpleDiExecutableSizeBenchmark): 582*a65addddSAndroid Build Coastguard Worker def __init__(self, **kwargs): 583*a65addddSAndroid Build Coastguard Worker super().__init__(use_interfaces=True, **kwargs) 584*a65addddSAndroid Build Coastguard Worker 585*a65addddSAndroid Build Coastguard Worker# This is not really a 'benchmark', but we consider it as such to reuse the benchmark infrastructure. 586*a65addddSAndroid Build Coastguard Workerclass SimpleDiWithInterfacesExecutableSizeBenchmarkWithoutExceptionsAndRtti(SimpleDiExecutableSizeBenchmarkWithoutExceptionsAndRtti): 587*a65addddSAndroid Build Coastguard Worker def __init__(self, **kwargs): 588*a65addddSAndroid Build Coastguard Worker super().__init__(use_interfaces=True, **kwargs) 589*a65addddSAndroid Build Coastguard Worker 590*a65addddSAndroid Build Coastguard Workerclass SimpleDiWithInterfacesAndNewDeleteCompileTimeBenchmark(SimpleDiWithInterfacesCompileTimeBenchmark): 591*a65addddSAndroid Build Coastguard Worker def __init__(self, **kwargs): 592*a65addddSAndroid Build Coastguard Worker super().__init__(use_new_delete=True, **kwargs) 593*a65addddSAndroid Build Coastguard Worker 594*a65addddSAndroid Build Coastguard Workerclass SimpleDiWithInterfacesAndNewDeleteIncrementalCompileTimeBenchmark(SimpleDiWithInterfacesIncrementalCompileTimeBenchmark): 595*a65addddSAndroid Build Coastguard Worker def __init__(self, **kwargs): 596*a65addddSAndroid Build Coastguard Worker super().__init__(use_new_delete=True, **kwargs) 597*a65addddSAndroid Build Coastguard Worker 598*a65addddSAndroid Build Coastguard Workerclass SimpleDiWithInterfacesAndNewDeleteCompileMemoryBenchmark(SimpleDiWithInterfacesCompileMemoryBenchmark): 599*a65addddSAndroid Build Coastguard Worker def __init__(self, **kwargs): 600*a65addddSAndroid Build Coastguard Worker super().__init__(use_new_delete=True, **kwargs) 601*a65addddSAndroid Build Coastguard Worker 602*a65addddSAndroid Build Coastguard Workerclass SimpleDiWithInterfacesAndNewDeleteRunTimeBenchmark(SimpleDiWithInterfacesRunTimeBenchmark): 603*a65addddSAndroid Build Coastguard Worker def __init__(self, **kwargs): 604*a65addddSAndroid Build Coastguard Worker super().__init__(use_new_delete=True, **kwargs) 605*a65addddSAndroid Build Coastguard Worker 606*a65addddSAndroid Build Coastguard Workerclass SimpleDiWithInterfacesAndNewDeleteStartupTimeBenchmark(SimpleDiWithInterfacesStartupTimeBenchmark): 607*a65addddSAndroid Build Coastguard Worker def __init__(self, **kwargs): 608*a65addddSAndroid Build Coastguard Worker super().__init__(use_new_delete=True, **kwargs) 609*a65addddSAndroid Build Coastguard Worker 610*a65addddSAndroid Build Coastguard Worker# This is not really a 'benchmark', but we consider it as such to reuse the benchmark infrastructure. 611*a65addddSAndroid Build Coastguard Workerclass SimpleDiWithInterfacesAndNewDeleteExecutableSizeBenchmark(SimpleDiWithInterfacesExecutableSizeBenchmark): 612*a65addddSAndroid Build Coastguard Worker def __init__(self, **kwargs): 613*a65addddSAndroid Build Coastguard Worker super().__init__(use_new_delete=True, **kwargs) 614*a65addddSAndroid Build Coastguard Worker 615*a65addddSAndroid Build Coastguard Worker# This is not really a 'benchmark', but we consider it as such to reuse the benchmark infrastructure. 616*a65addddSAndroid Build Coastguard Workerclass SimpleDiWithInterfacesAndNewDeleteExecutableSizeBenchmarkWithoutExceptionsAndRtti(SimpleDiWithInterfacesExecutableSizeBenchmarkWithoutExceptionsAndRtti): 617*a65addddSAndroid Build Coastguard Worker def __init__(self, **kwargs): 618*a65addddSAndroid Build Coastguard Worker super().__init__(use_new_delete=True, **kwargs) 619*a65addddSAndroid Build Coastguard Worker 620*a65addddSAndroid Build Coastguard Worker 621*a65addddSAndroid Build Coastguard Workerdef round_to_significant_digits(n: float, num_significant_digits: int) -> float: 622*a65addddSAndroid Build Coastguard Worker if n <= 0: 623*a65addddSAndroid Build Coastguard Worker # We special-case this, otherwise the log10 below will fail. 624*a65addddSAndroid Build Coastguard Worker return 0 625*a65addddSAndroid Build Coastguard Worker return round(n, num_significant_digits - int(floor(log10(n))) - 1) 626*a65addddSAndroid Build Coastguard Worker 627*a65addddSAndroid Build Coastguard Workerdef run_benchmark(benchmark: Benchmark, max_runs: int, timeout_hours: int, output_file: str, min_runs: int=3) -> None: 628*a65addddSAndroid Build Coastguard Worker def run_benchmark_once(): 629*a65addddSAndroid Build Coastguard Worker print('Running benchmark... ', end='', flush=True) 630*a65addddSAndroid Build Coastguard Worker result = benchmark.run() 631*a65addddSAndroid Build Coastguard Worker print(result) 632*a65addddSAndroid Build Coastguard Worker for dimension, value in result.items(): 633*a65addddSAndroid Build Coastguard Worker results_by_dimension[dimension] += [value] 634*a65addddSAndroid Build Coastguard Worker 635*a65addddSAndroid Build Coastguard Worker results_by_dimension = defaultdict(lambda: []) 636*a65addddSAndroid Build Coastguard Worker print('Preparing for benchmark... ', end='', flush=True) 637*a65addddSAndroid Build Coastguard Worker benchmark.prepare() 638*a65addddSAndroid Build Coastguard Worker print('Done.') 639*a65addddSAndroid Build Coastguard Worker 640*a65addddSAndroid Build Coastguard Worker start_time = timer() 641*a65addddSAndroid Build Coastguard Worker 642*a65addddSAndroid Build Coastguard Worker # Run at least min_runs times 643*a65addddSAndroid Build Coastguard Worker for i in range(min_runs): 644*a65addddSAndroid Build Coastguard Worker run_benchmark_once() 645*a65addddSAndroid Build Coastguard Worker 646*a65addddSAndroid Build Coastguard Worker # Then consider running a few more times to get the desired precision. 647*a65addddSAndroid Build Coastguard Worker while True: 648*a65addddSAndroid Build Coastguard Worker if timer() - start_time > timeout_hours * 3600: 649*a65addddSAndroid Build Coastguard Worker print("Warning: timed out, couldn't determine a result with the desired precision.") 650*a65addddSAndroid Build Coastguard Worker break 651*a65addddSAndroid Build Coastguard Worker 652*a65addddSAndroid Build Coastguard Worker for dimension, results in results_by_dimension.items(): 653*a65addddSAndroid Build Coastguard Worker if all(result == results[0] for result in results): 654*a65addddSAndroid Build Coastguard Worker # If all results are exactly the same the code below misbehaves. We don't need to run again in this case. 655*a65addddSAndroid Build Coastguard Worker continue 656*a65addddSAndroid Build Coastguard Worker confidence_interval = stats.DescrStatsW(results).tconfint_mean(0.05) 657*a65addddSAndroid Build Coastguard Worker confidence_interval_2dig = (round_to_significant_digits(confidence_interval[0], 2), 658*a65addddSAndroid Build Coastguard Worker round_to_significant_digits(confidence_interval[1], 2)) 659*a65addddSAndroid Build Coastguard Worker if abs(confidence_interval_2dig[0] - confidence_interval_2dig[1]) > numpy.finfo(float).eps * 10: 660*a65addddSAndroid Build Coastguard Worker if len(results) < max_runs: 661*a65addddSAndroid Build Coastguard Worker print("Running again to get more precision on the metric %s. Current confidence interval: [%.3g, %.3g]" % ( 662*a65addddSAndroid Build Coastguard Worker dimension, confidence_interval[0], confidence_interval[1])) 663*a65addddSAndroid Build Coastguard Worker break 664*a65addddSAndroid Build Coastguard Worker else: 665*a65addddSAndroid Build Coastguard Worker print("Warning: couldn't determine a precise result for the metric %s. Confidence interval: [%.3g, %.3g]" % ( 666*a65addddSAndroid Build Coastguard Worker dimension, confidence_interval[0], confidence_interval[1])) 667*a65addddSAndroid Build Coastguard Worker else: 668*a65addddSAndroid Build Coastguard Worker # We've reached sufficient precision in all metrics, or we've reached the max number of runs. 669*a65addddSAndroid Build Coastguard Worker break 670*a65addddSAndroid Build Coastguard Worker 671*a65addddSAndroid Build Coastguard Worker run_benchmark_once() 672*a65addddSAndroid Build Coastguard Worker 673*a65addddSAndroid Build Coastguard Worker # We've reached the desired precision in all dimensions or reached the maximum number of runs. Record the results. 674*a65addddSAndroid Build Coastguard Worker rounded_confidence_intervals_by_dimension = {} 675*a65addddSAndroid Build Coastguard Worker confidence_intervals_by_dimension = {} 676*a65addddSAndroid Build Coastguard Worker for dimension, results in results_by_dimension.items(): 677*a65addddSAndroid Build Coastguard Worker confidence_interval = stats.DescrStatsW(results).tconfint_mean(0.05) 678*a65addddSAndroid Build Coastguard Worker confidence_interval_2dig = (round_to_significant_digits(confidence_interval[0], 2), 679*a65addddSAndroid Build Coastguard Worker round_to_significant_digits(confidence_interval[1], 2)) 680*a65addddSAndroid Build Coastguard Worker rounded_confidence_intervals_by_dimension[dimension] = confidence_interval_2dig 681*a65addddSAndroid Build Coastguard Worker confidence_intervals_by_dimension[dimension] = (confidence_interval, confidence_interval_2dig) 682*a65addddSAndroid Build Coastguard Worker with open(output_file, 'a') as f: 683*a65addddSAndroid Build Coastguard Worker json.dump({"benchmark": benchmark.describe(), "results": confidence_intervals_by_dimension}, f) 684*a65addddSAndroid Build Coastguard Worker print(file=f) 685*a65addddSAndroid Build Coastguard Worker print('Benchmark finished. Result: ', rounded_confidence_intervals_by_dimension) 686*a65addddSAndroid Build Coastguard Worker print() 687*a65addddSAndroid Build Coastguard Worker 688*a65addddSAndroid Build Coastguard Worker 689*a65addddSAndroid Build Coastguard Workerdef expand_benchmark_definition(benchmark_definition: Dict[str, Any]) -> List[Dict[str, Tuple[Any]]]: 690*a65addddSAndroid Build Coastguard Worker """ 691*a65addddSAndroid Build Coastguard Worker Takes a benchmark definition, e.g.: 692*a65addddSAndroid Build Coastguard Worker [{name: 'foo', compiler: ['g++-5', 'g++-6']}, 693*a65addddSAndroid Build Coastguard Worker {name: ['bar', 'baz'], compiler: ['g++-5'], cxx_std: 'c++14'}] 694*a65addddSAndroid Build Coastguard Worker 695*a65addddSAndroid Build Coastguard Worker And expands it into the individual benchmarks to run, in the example above: 696*a65addddSAndroid Build Coastguard Worker [{name: 'foo', compiler: 'g++-5'}, 697*a65addddSAndroid Build Coastguard Worker {name: 'foo', compiler: 'g++-6'}, 698*a65addddSAndroid Build Coastguard Worker {name: 'bar', compiler: 'g++-5', cxx_std: 'c++14'}, 699*a65addddSAndroid Build Coastguard Worker {name: 'baz', compiler: 'g++-5', cxx_std: 'c++14'}] 700*a65addddSAndroid Build Coastguard Worker """ 701*a65addddSAndroid Build Coastguard Worker dict_keys = sorted(benchmark_definition.keys()) 702*a65addddSAndroid Build Coastguard Worker # Turn non-list values into single-item lists. 703*a65addddSAndroid Build Coastguard Worker benchmark_definition = {dict_key: value if isinstance(value, list) else [value] 704*a65addddSAndroid Build Coastguard Worker for dict_key, value in benchmark_definition.items()} 705*a65addddSAndroid Build Coastguard Worker # Compute the cartesian product of the value lists 706*a65addddSAndroid Build Coastguard Worker value_combinations = itertools.product(*(benchmark_definition[dict_key] for dict_key in dict_keys)) 707*a65addddSAndroid Build Coastguard Worker # Then turn the result back into a dict. 708*a65addddSAndroid Build Coastguard Worker return [dict(zip(dict_keys, value_combination)) 709*a65addddSAndroid Build Coastguard Worker for value_combination in value_combinations] 710*a65addddSAndroid Build Coastguard Worker 711*a65addddSAndroid Build Coastguard Worker 712*a65addddSAndroid Build Coastguard Workerdef expand_benchmark_definitions(benchmark_definitions: List[Dict[str, Any]]): 713*a65addddSAndroid Build Coastguard Worker return list(itertools.chain(*[expand_benchmark_definition(benchmark_definition) for benchmark_definition in benchmark_definitions])) 714*a65addddSAndroid Build Coastguard Worker 715*a65addddSAndroid Build Coastguard WorkerT = TypeVar('T') 716*a65addddSAndroid Build Coastguard WorkerK = TypeVar('K') 717*a65addddSAndroid Build Coastguard Worker 718*a65addddSAndroid Build Coastguard Workerdef group_by(l: List[T], element_to_key: Callable[[T], K]) -> Iterable[Tuple[K, List[T]]]: 719*a65addddSAndroid Build Coastguard Worker """Takes a list and returns a list of sublists, where the elements are grouped using the provided function""" 720*a65addddSAndroid Build Coastguard Worker result = defaultdict(list) # type: Dict[K, List[T]] 721*a65addddSAndroid Build Coastguard Worker for elem in l: 722*a65addddSAndroid Build Coastguard Worker result[element_to_key(elem)].append(elem) 723*a65addddSAndroid Build Coastguard Worker return result.items() 724*a65addddSAndroid Build Coastguard Worker 725*a65addddSAndroid Build Coastguard Workerdef main(): 726*a65addddSAndroid Build Coastguard Worker # This configures numpy/scipy to raise an exception in case of errors, instead of printing a warning and going ahead. 727*a65addddSAndroid Build Coastguard Worker numpy.seterr(all='raise') 728*a65addddSAndroid Build Coastguard Worker scipy.seterr(all='raise') 729*a65addddSAndroid Build Coastguard Worker 730*a65addddSAndroid Build Coastguard Worker parser = argparse.ArgumentParser(description='Runs a set of benchmarks defined in a YAML file.') 731*a65addddSAndroid Build Coastguard Worker parser.add_argument('--fruit-benchmark-sources-dir', help='Path to the fruit sources (used for benchmarking code only)') 732*a65addddSAndroid Build Coastguard Worker parser.add_argument('--fruit-sources-dir', help='Path to the fruit sources') 733*a65addddSAndroid Build Coastguard Worker parser.add_argument('--boost-di-sources-dir', help='Path to the Boost.DI sources') 734*a65addddSAndroid Build Coastguard Worker parser.add_argument('--output-file', 735*a65addddSAndroid Build Coastguard Worker help='The output file where benchmark results will be stored (1 per line, with each line in JSON format). These can then be formatted by e.g. the format_bench_results script.') 736*a65addddSAndroid Build Coastguard Worker parser.add_argument('--benchmark-definition', help='The YAML file that defines the benchmarks (see fruit_wiki_benchs_fruit.yml for an example).') 737*a65addddSAndroid Build Coastguard Worker parser.add_argument('--continue-benchmark', help='If this is \'true\', continues a previous benchmark run instead of starting from scratch (taking into account the existing benchmark results in the file specified with --output-file).') 738*a65addddSAndroid Build Coastguard Worker args = parser.parse_args() 739*a65addddSAndroid Build Coastguard Worker 740*a65addddSAndroid Build Coastguard Worker if args.output_file is None: 741*a65addddSAndroid Build Coastguard Worker raise Exception('You must specify --output_file') 742*a65addddSAndroid Build Coastguard Worker if args.continue_benchmark == 'true': 743*a65addddSAndroid Build Coastguard Worker try: 744*a65addddSAndroid Build Coastguard Worker with open(args.output_file, 'r') as f: 745*a65addddSAndroid Build Coastguard Worker previous_run_completed_benchmarks = [json.loads(line)['benchmark'] for line in f.readlines()] 746*a65addddSAndroid Build Coastguard Worker except FileNotFoundError: 747*a65addddSAndroid Build Coastguard Worker previous_run_completed_benchmarks = [] 748*a65addddSAndroid Build Coastguard Worker else: 749*a65addddSAndroid Build Coastguard Worker previous_run_completed_benchmarks = [] 750*a65addddSAndroid Build Coastguard Worker run_command('rm', args=['-f', args.output_file]) 751*a65addddSAndroid Build Coastguard Worker 752*a65addddSAndroid Build Coastguard Worker fruit_build_dir = tempfile.gettempdir() + '/fruit-benchmark-build-dir' 753*a65addddSAndroid Build Coastguard Worker 754*a65addddSAndroid Build Coastguard Worker with open(args.benchmark_definition, 'r') as f: 755*a65addddSAndroid Build Coastguard Worker yaml_file_content = yaml.full_load(f) 756*a65addddSAndroid Build Coastguard Worker global_definitions = yaml_file_content['global'] 757*a65addddSAndroid Build Coastguard Worker benchmark_definitions = expand_benchmark_definitions(yaml_file_content['benchmarks']) 758*a65addddSAndroid Build Coastguard Worker 759*a65addddSAndroid Build Coastguard Worker benchmark_index = 0 760*a65addddSAndroid Build Coastguard Worker 761*a65addddSAndroid Build Coastguard Worker for (compiler_executable_name, additional_cmake_args), benchmark_definitions_with_current_config \ 762*a65addddSAndroid Build Coastguard Worker in group_by(benchmark_definitions, 763*a65addddSAndroid Build Coastguard Worker lambda benchmark_definition: 764*a65addddSAndroid Build Coastguard Worker (benchmark_definition['compiler'], tuple(benchmark_definition['additional_cmake_args']))): 765*a65addddSAndroid Build Coastguard Worker 766*a65addddSAndroid Build Coastguard Worker print('Preparing for benchmarks with the compiler %s, with additional CMake args %s' % (compiler_executable_name, additional_cmake_args)) 767*a65addddSAndroid Build Coastguard Worker try: 768*a65addddSAndroid Build Coastguard Worker # We compute this here (and memoize the result) so that the benchmark's describe() will retrieve the cached 769*a65addddSAndroid Build Coastguard Worker # value instantly. 770*a65addddSAndroid Build Coastguard Worker determine_compiler_name(compiler_executable_name) 771*a65addddSAndroid Build Coastguard Worker 772*a65addddSAndroid Build Coastguard Worker # Build Fruit in fruit_build_dir, so that fruit_build_dir points to a built Fruit (useful for e.g. the config header). 773*a65addddSAndroid Build Coastguard Worker shutil.rmtree(fruit_build_dir, ignore_errors=True) 774*a65addddSAndroid Build Coastguard Worker os.makedirs(fruit_build_dir) 775*a65addddSAndroid Build Coastguard Worker modified_env = os.environ.copy() 776*a65addddSAndroid Build Coastguard Worker modified_env['CXX'] = compiler_executable_name 777*a65addddSAndroid Build Coastguard Worker run_command('cmake', 778*a65addddSAndroid Build Coastguard Worker args=[ 779*a65addddSAndroid Build Coastguard Worker args.fruit_sources_dir, 780*a65addddSAndroid Build Coastguard Worker '-DCMAKE_BUILD_TYPE=Release', 781*a65addddSAndroid Build Coastguard Worker *additional_cmake_args, 782*a65addddSAndroid Build Coastguard Worker ], 783*a65addddSAndroid Build Coastguard Worker cwd=fruit_build_dir, 784*a65addddSAndroid Build Coastguard Worker env=modified_env) 785*a65addddSAndroid Build Coastguard Worker run_command('make', args=make_args, cwd=fruit_build_dir) 786*a65addddSAndroid Build Coastguard Worker except Exception as e: 787*a65addddSAndroid Build Coastguard Worker print('Exception while preparing for benchmarks with the compiler %s, with additional CMake args %s.\n%s\nGoing ahead with the rest.' % (compiler_executable_name, additional_cmake_args, traceback.format_exc())) 788*a65addddSAndroid Build Coastguard Worker continue 789*a65addddSAndroid Build Coastguard Worker 790*a65addddSAndroid Build Coastguard Worker for benchmark_definition in benchmark_definitions_with_current_config: 791*a65addddSAndroid Build Coastguard Worker benchmark_index += 1 792*a65addddSAndroid Build Coastguard Worker print('%s/%s: %s' % (benchmark_index, len(benchmark_definitions), benchmark_definition)) 793*a65addddSAndroid Build Coastguard Worker benchmark_name = benchmark_definition['name'] 794*a65addddSAndroid Build Coastguard Worker 795*a65addddSAndroid Build Coastguard Worker if (benchmark_name in {'boost_di_compile_time', 'boost_di_run_time', 'boost_di_executable_size'} 796*a65addddSAndroid Build Coastguard Worker and args.boost_di_sources_dir is None): 797*a65addddSAndroid Build Coastguard Worker raise Exception('Error: you need to specify the --boost-di-sources-dir flag in order to run Boost.DI benchmarks.') 798*a65addddSAndroid Build Coastguard Worker 799*a65addddSAndroid Build Coastguard Worker if benchmark_name == 'new_delete_run_time': 800*a65addddSAndroid Build Coastguard Worker benchmark = SimpleNewDeleteRunTimeBenchmark( 801*a65addddSAndroid Build Coastguard Worker benchmark_definition, 802*a65addddSAndroid Build Coastguard Worker fruit_benchmark_sources_dir=args.fruit_benchmark_sources_dir) 803*a65addddSAndroid Build Coastguard Worker elif benchmark_name == 'fruit_single_file_compile_time': 804*a65addddSAndroid Build Coastguard Worker benchmark = FruitSingleFileCompileTimeBenchmark( 805*a65addddSAndroid Build Coastguard Worker benchmark_definition, 806*a65addddSAndroid Build Coastguard Worker fruit_sources_dir=args.fruit_sources_dir, 807*a65addddSAndroid Build Coastguard Worker fruit_benchmark_sources_dir=args.fruit_benchmark_sources_dir, 808*a65addddSAndroid Build Coastguard Worker fruit_build_dir=fruit_build_dir) 809*a65addddSAndroid Build Coastguard Worker elif benchmark_name.startswith('fruit_'): 810*a65addddSAndroid Build Coastguard Worker benchmark_class = { 811*a65addddSAndroid Build Coastguard Worker 'fruit_compile_time': FruitCompileTimeBenchmark, 812*a65addddSAndroid Build Coastguard Worker 'fruit_incremental_compile_time': FruitIncrementalCompileTimeBenchmark, 813*a65addddSAndroid Build Coastguard Worker 'fruit_compile_memory': FruitCompileMemoryBenchmark, 814*a65addddSAndroid Build Coastguard Worker 'fruit_run_time': FruitRunTimeBenchmark, 815*a65addddSAndroid Build Coastguard Worker 'fruit_startup_time': FruitStartupTimeBenchmark, 816*a65addddSAndroid Build Coastguard Worker 'fruit_startup_time_with_normalized_component': FruitStartupTimeWithNormalizedComponentBenchmark, 817*a65addddSAndroid Build Coastguard Worker 'fruit_executable_size': FruitExecutableSizeBenchmark, 818*a65addddSAndroid Build Coastguard Worker 'fruit_executable_size_without_exceptions_and_rtti': FruitExecutableSizeBenchmarkWithoutExceptionsAndRtti, 819*a65addddSAndroid Build Coastguard Worker }[benchmark_name] 820*a65addddSAndroid Build Coastguard Worker benchmark = benchmark_class( 821*a65addddSAndroid Build Coastguard Worker benchmark_definition=benchmark_definition, 822*a65addddSAndroid Build Coastguard Worker fruit_sources_dir=args.fruit_sources_dir, 823*a65addddSAndroid Build Coastguard Worker fruit_build_dir=fruit_build_dir) 824*a65addddSAndroid Build Coastguard Worker elif benchmark_name.startswith('boost_di_'): 825*a65addddSAndroid Build Coastguard Worker benchmark_class = { 826*a65addddSAndroid Build Coastguard Worker 'boost_di_compile_time': BoostDiCompileTimeBenchmark, 827*a65addddSAndroid Build Coastguard Worker 'boost_di_incremental_compile_time': BoostDiIncrementalCompileTimeBenchmark, 828*a65addddSAndroid Build Coastguard Worker 'boost_di_compile_memory': BoostDiCompileMemoryBenchmark, 829*a65addddSAndroid Build Coastguard Worker 'boost_di_run_time': BoostDiRunTimeBenchmark, 830*a65addddSAndroid Build Coastguard Worker 'boost_di_startup_time': BoostDiStartupTimeBenchmark, 831*a65addddSAndroid Build Coastguard Worker 'boost_di_executable_size': BoostDiExecutableSizeBenchmark, 832*a65addddSAndroid Build Coastguard Worker 'boost_di_executable_size_without_exceptions_and_rtti': BoostDiExecutableSizeBenchmarkWithoutExceptionsAndRtti, 833*a65addddSAndroid Build Coastguard Worker }[benchmark_name] 834*a65addddSAndroid Build Coastguard Worker benchmark = benchmark_class( 835*a65addddSAndroid Build Coastguard Worker benchmark_definition=benchmark_definition, 836*a65addddSAndroid Build Coastguard Worker boost_di_sources_dir=args.boost_di_sources_dir) 837*a65addddSAndroid Build Coastguard Worker elif benchmark_name.startswith('simple_di_'): 838*a65addddSAndroid Build Coastguard Worker benchmark_class = { 839*a65addddSAndroid Build Coastguard Worker 'simple_di_compile_time': SimpleDiCompileTimeBenchmark, 840*a65addddSAndroid Build Coastguard Worker 'simple_di_incremental_compile_time': SimpleDiIncrementalCompileTimeBenchmark, 841*a65addddSAndroid Build Coastguard Worker 'simple_di_compile_memory': SimpleDiCompileMemoryBenchmark, 842*a65addddSAndroid Build Coastguard Worker 'simple_di_run_time': SimpleDiRunTimeBenchmark, 843*a65addddSAndroid Build Coastguard Worker 'simple_di_startup_time': SimpleDiStartupTimeBenchmark, 844*a65addddSAndroid Build Coastguard Worker 'simple_di_executable_size': SimpleDiExecutableSizeBenchmark, 845*a65addddSAndroid Build Coastguard Worker 'simple_di_executable_size_without_exceptions_and_rtti': SimpleDiExecutableSizeBenchmarkWithoutExceptionsAndRtti, 846*a65addddSAndroid Build Coastguard Worker 'simple_di_with_interfaces_compile_time': SimpleDiWithInterfacesCompileTimeBenchmark, 847*a65addddSAndroid Build Coastguard Worker 'simple_di_with_interfaces_incremental_compile_time': SimpleDiWithInterfacesIncrementalCompileTimeBenchmark, 848*a65addddSAndroid Build Coastguard Worker 'simple_di_with_interfaces_compile_memory': SimpleDiWithInterfacesCompileMemoryBenchmark, 849*a65addddSAndroid Build Coastguard Worker 'simple_di_with_interfaces_run_time': SimpleDiWithInterfacesRunTimeBenchmark, 850*a65addddSAndroid Build Coastguard Worker 'simple_di_with_interfaces_startup_time': SimpleDiWithInterfacesStartupTimeBenchmark, 851*a65addddSAndroid Build Coastguard Worker 'simple_di_with_interfaces_executable_size': SimpleDiWithInterfacesExecutableSizeBenchmark, 852*a65addddSAndroid Build Coastguard Worker 'simple_di_with_interfaces_executable_size_without_exceptions_and_rtti': SimpleDiWithInterfacesExecutableSizeBenchmarkWithoutExceptionsAndRtti, 853*a65addddSAndroid Build Coastguard Worker 'simple_di_with_interfaces_and_new_delete_compile_time': SimpleDiWithInterfacesAndNewDeleteCompileTimeBenchmark, 854*a65addddSAndroid Build Coastguard Worker 'simple_di_with_interfaces_and_new_delete_incremental_compile_time': SimpleDiWithInterfacesAndNewDeleteIncrementalCompileTimeBenchmark, 855*a65addddSAndroid Build Coastguard Worker 'simple_di_with_interfaces_and_new_delete_compile_memory': SimpleDiWithInterfacesAndNewDeleteCompileMemoryBenchmark, 856*a65addddSAndroid Build Coastguard Worker 'simple_di_with_interfaces_and_new_delete_run_time': SimpleDiWithInterfacesAndNewDeleteRunTimeBenchmark, 857*a65addddSAndroid Build Coastguard Worker 'simple_di_with_interfaces_and_new_delete_startup_time': SimpleDiWithInterfacesAndNewDeleteStartupTimeBenchmark, 858*a65addddSAndroid Build Coastguard Worker 'simple_di_with_interfaces_and_new_delete_executable_size': SimpleDiWithInterfacesAndNewDeleteExecutableSizeBenchmark, 859*a65addddSAndroid Build Coastguard Worker 'simple_di_with_interfaces_and_new_delete_executable_size_without_exceptions_and_rtti': SimpleDiWithInterfacesAndNewDeleteExecutableSizeBenchmarkWithoutExceptionsAndRtti, 860*a65addddSAndroid Build Coastguard Worker }[benchmark_name] 861*a65addddSAndroid Build Coastguard Worker benchmark = benchmark_class( 862*a65addddSAndroid Build Coastguard Worker benchmark_definition=benchmark_definition) 863*a65addddSAndroid Build Coastguard Worker else: 864*a65addddSAndroid Build Coastguard Worker raise Exception("Unrecognized benchmark: %s" % benchmark_name) 865*a65addddSAndroid Build Coastguard Worker 866*a65addddSAndroid Build Coastguard Worker if benchmark.describe() in previous_run_completed_benchmarks: 867*a65addddSAndroid Build Coastguard Worker print("Skipping benchmark that was already run previously (due to --continue-benchmark):", benchmark.describe()) 868*a65addddSAndroid Build Coastguard Worker continue 869*a65addddSAndroid Build Coastguard Worker 870*a65addddSAndroid Build Coastguard Worker try: 871*a65addddSAndroid Build Coastguard Worker run_benchmark(benchmark, 872*a65addddSAndroid Build Coastguard Worker output_file=args.output_file, 873*a65addddSAndroid Build Coastguard Worker max_runs=global_definitions['max_runs'], 874*a65addddSAndroid Build Coastguard Worker timeout_hours=global_definitions['max_hours_per_combination']) 875*a65addddSAndroid Build Coastguard Worker except Exception as e: 876*a65addddSAndroid Build Coastguard Worker print('Exception while running benchmark: %s.\n%s\nGoing ahead with the rest.' % (benchmark.describe(), traceback.format_exc())) 877*a65addddSAndroid Build Coastguard Worker 878*a65addddSAndroid Build Coastguard Worker 879*a65addddSAndroid Build Coastguard Workerif __name__ == "__main__": 880*a65addddSAndroid Build Coastguard Worker main() 881