| #!/usr/bin/env python |
| # |
| # Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| # See https://llvm.org/LICENSE.txt for license information. |
| # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| # |
| # ==------------------------------------------------------------------------==# |
| |
| import os |
| import glob |
| import re |
| import subprocess |
| import json |
| import datetime |
| import argparse |
| |
| try: |
| from urllib.parse import urlencode |
| from urllib.request import urlopen, Request |
| except ImportError: |
| from urllib import urlencode |
| from urllib2 import urlopen, Request |
| |
| |
| 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(r"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 = urlencode({"input_data": data}).encode("ascii") |
| urlopen(Request(args.url, data2)) |
| |
| |
| os.chdir(args.benchmark_directory) |
| data = buildLntJson(getBenchmarks()) |
| submitToServer(data) |