| #!/usr/bin/env python |
| # |
| # The LLVM Compiler Infrastructure |
| # |
| # This file is distributed under the University of Illinois Open Source |
| # License. See LICENSE.TXT for details. |
| # |
| # ==------------------------------------------------------------------------==# |
| |
| import os |
| import glob |
| import re |
| import subprocess |
| import json |
| import datetime |
| import argparse |
| import urllib |
| import urllib2 |
| |
| parser = argparse.ArgumentParser() |
| parser.add_argument('benchmark_directory') |
| parser.add_argument('--runs', type=int, default=10) |
| parser.add_argument('--wrapper', default='') |
| parser.add_argument('--machine', required=True) |
| parser.add_argument('--revision', required=True) |
| parser.add_argument('--threads', action='store_true') |
| parser.add_argument('--url', help='The lnt server url to send the results to', |
| default='http://localhost:8000/db_default/v4/link/submitRun') |
| args = parser.parse_args() |
| |
| class Bench: |
| def __init__(self, directory, variant): |
| self.directory = directory |
| self.variant = variant |
| def __str__(self): |
| if not self.variant: |
| return self.directory |
| return '%s-%s' % (self.directory, self.variant) |
| |
| def getBenchmarks(): |
| ret = [] |
| for i in glob.glob('*/response*.txt'): |
| m = re.match('response-(.*)\.txt', os.path.basename(i)) |
| variant = m.groups()[0] if m else None |
| ret.append(Bench(os.path.dirname(i), variant)) |
| return ret |
| |
| def parsePerfNum(num): |
| num = num.replace(b',',b'') |
| try: |
| return int(num) |
| except ValueError: |
| return float(num) |
| |
| def parsePerfLine(line): |
| ret = {} |
| line = line.split(b'#')[0].strip() |
| if len(line) != 0: |
| p = line.split() |
| ret[p[1].strip().decode('ascii')] = parsePerfNum(p[0]) |
| return ret |
| |
| def parsePerf(output): |
| ret = {} |
| lines = [x.strip() for x in output.split(b'\n')] |
| |
| seconds = [x for x in lines if b'seconds time elapsed' in x][0] |
| seconds = seconds.strip().split()[0].strip() |
| ret['seconds-elapsed'] = parsePerfNum(seconds) |
| |
| measurement_lines = [x for x in lines if b'#' in x] |
| for l in measurement_lines: |
| ret.update(parsePerfLine(l)) |
| return ret |
| |
| def run(cmd): |
| try: |
| return subprocess.check_output(cmd, stderr=subprocess.STDOUT) |
| except subprocess.CalledProcessError as e: |
| print(e.output) |
| raise e |
| |
| def combinePerfRun(acc, d): |
| for k,v in d.items(): |
| a = acc.get(k, []) |
| a.append(v) |
| acc[k] = a |
| |
| def perf(cmd): |
| # Discard the first run to warm up any system cache. |
| run(cmd) |
| |
| ret = {} |
| wrapper_args = [x for x in args.wrapper.split(',') if x] |
| for i in range(args.runs): |
| os.unlink('t') |
| out = run(wrapper_args + ['perf', 'stat'] + cmd) |
| r = parsePerf(out) |
| combinePerfRun(ret, r) |
| os.unlink('t') |
| return ret |
| |
| def runBench(bench): |
| thread_arg = [] if args.threads else ['--no-threads'] |
| os.chdir(bench.directory) |
| suffix = '-%s' % bench.variant if bench.variant else '' |
| response = 'response' + suffix + '.txt' |
| ret = perf(['../ld.lld', '@' + response, '-o', 't'] + thread_arg) |
| ret['name'] = str(bench) |
| os.chdir('..') |
| return ret |
| |
| def buildLntJson(benchmarks): |
| start = datetime.datetime.utcnow().isoformat() |
| tests = [runBench(b) for b in benchmarks] |
| end = datetime.datetime.utcnow().isoformat() |
| ret = { |
| 'format_version' : 2, |
| 'machine' : { 'name' : args.machine }, |
| 'run' : { |
| 'end_time' : start, |
| 'start_time' : end, |
| 'llvm_project_revision': args.revision |
| }, |
| 'tests' : tests |
| } |
| return json.dumps(ret, sort_keys=True, indent=4) |
| |
| def submitToServer(data): |
| data2 = urllib.urlencode({ 'input_data' : data }).encode('ascii') |
| urllib2.urlopen(urllib2.Request(args.url, data2)) |
| |
| os.chdir(args.benchmark_directory) |
| data = buildLntJson(getBenchmarks()) |
| submitToServer(data) |