| #!/usr/bin/env python |
| |
| # ===--- Benchmark_QuickCheck.in -----------------------------------------===// |
| # |
| # This source file is part of the Swift.org open source project |
| # |
| # Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors |
| # Licensed under Apache License v2.0 with Runtime Library Exception |
| # |
| # See https://swift.org/LICENSE.txt for license information |
| # See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors |
| # |
| # ===---------------------------------------------------------------------===// |
| |
| import json |
| import os |
| import subprocess |
| import sys |
| |
| sys.path.append("@PATH_TO_DRIVER_LIBRARY@") |
| |
| import perf_test_driver # noqa (E402 module level import not at top of file) |
| |
| # This is a hacked up XFAIL list. It should really be a json file, but it will |
| # work for now. Add in the exact name of the pass to XFAIL. |
| XFAIL_LIST = [ |
| ] |
| |
| |
| class QuickCheckResult(perf_test_driver.Result): |
| |
| def __init__(self, name, success): |
| assert(isinstance(success, bool)) |
| did_fail = not success |
| perf_test_driver.Result.__init__(self, name, did_fail, "", XFAIL_LIST) |
| |
| def print_data(self, max_test_len): |
| fmt = '{:<%d}{:<10}' % (max_test_len + 5) |
| print(fmt.format(self.get_name(), self.get_result())) |
| |
| |
| class QuickCheckBenchmarkDriver(perf_test_driver.BenchmarkDriver): |
| |
| def __init__(self, binary, xfail_list, num_iters, opt_levels): |
| perf_test_driver.BenchmarkDriver.__init__( |
| self, binary, xfail_list, |
| enable_parallel=True, |
| opt_levels=opt_levels) |
| self.num_iters = num_iters |
| |
| def print_data_header(self, max_test_len): |
| fmt = '{:<%d}{:<10}' % (max_test_len + 5) |
| print(fmt.format('Name', 'Result')) |
| |
| # Propagate any data from this class that is needed for individual |
| # tests. The reason this is needed is to avoid issues with attempting to |
| # access a value in a different process. |
| def prepare_input(self, name): |
| return {'num_samples': 1, 'num_iters': self.num_iters} |
| |
| def run_test_inner(self, data, num_iters): |
| p = subprocess.Popen([ |
| data['path'], |
| "--num-samples={}".format(data['num_samples']), |
| "--num-iters={}".format(num_iters), data['test_name']], |
| stdout=subprocess.PIPE, stderr=subprocess.PIPE) |
| error_out = p.communicate()[1].split("\n") |
| result = p.returncode |
| if result is None: |
| raise RuntimeError("Expected one line of output") |
| if result != 0: |
| raise RuntimeError("Process segfaulted") |
| return error_out |
| |
| def run_test(self, data, num_iters): |
| try: |
| args = [data, num_iters] |
| result = perf_test_driver.run_with_timeout(self.run_test_inner, |
| args) |
| except Exception, e: |
| sys.stderr.write("Child Process Failed! (%s,%s). Error: %s\n" % ( |
| data['path'], data['test_name'], e)) |
| sys.stderr.flush() |
| return None |
| return True |
| |
| def process_input(self, data): |
| test_name = '({},{})'.format(data['opt'], data['test_name']) |
| print("Running {}...".format(test_name)) |
| sys.stdout.flush() |
| if self.run_test(data, data['num_iters']) is None: |
| return QuickCheckResult(test_name, success=False) |
| return QuickCheckResult(test_name, success=True) |
| |
| |
| SWIFT_BIN_DIR = os.path.dirname(os.path.abspath(__file__)) |
| |
| |
| def parse_args(): |
| import argparse |
| parser = argparse.ArgumentParser() |
| parser.add_argument( |
| '--filter', type=str, default=None, |
| help='Filter out any test that does not match the given regex') |
| parser.add_argument('--num-iters', type=int, default=2) |
| default_opt_levels = perf_test_driver.BenchmarkDriver_OptLevels |
| parser.add_argument('--opt-level', choices=default_opt_levels) |
| return parser.parse_args() |
| |
| |
| if __name__ == "__main__": |
| args = parse_args() |
| opt_levels = perf_test_driver.BenchmarkDriver_OptLevels |
| if args.opt_level is not None: |
| opt_levels = [args.opt_level] |
| l = QuickCheckBenchmarkDriver(SWIFT_BIN_DIR, XFAIL_LIST, args.num_iters, |
| opt_levels) |
| if l.run(args.filter): |
| sys.exit(0) |
| else: |
| sys.exit(-1) |