llvm-capstone/lld/utils/benchmark.py
Tobias Hieta f98ee40f4b
[NFC][Py Reformat] Reformat python files in the rest of the dirs
This is an ongoing series of commits that are reformatting our
Python code. This catches the last of the python files to
reformat. Since they where so few I bunched them together.

Reformatting is done with `black`.

If you end up having problems merging this commit because you
have made changes to a python file, the best way to handle that
is to run git checkout --ours <yourfile> and then reformat it
with black.

If you run into any problems, post to discourse about it and
we will try to help.

RFC Thread below:

https://discourse.llvm.org/t/rfc-document-and-standardize-python-code-style

Reviewed By: jhenderson, #libc, Mordante, sivachandra

Differential Revision: https://reviews.llvm.org/D150784
2023-05-25 11:17:05 +02:00

157 lines
4.0 KiB
Python
Executable File

#!/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("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)