Merge benchmark data into single file for presentation
Change-Id: Ib609667e050745c3d3b67c0285dc7c5d25b3fc77
diff --git a/tools/historic_run.py b/tools/historic_run.py
index 35d12d9..5d6f8d5 100755
--- a/tools/historic_run.py
+++ b/tools/historic_run.py
@@ -56,11 +56,29 @@
def __repr__(self):
return self.__str__()
+ def hash(self):
+ return self.git_hash
+
+ def title(self):
+ result = subprocess.check_output(
+ ['git', 'show-branch', '--no-name', self.git_hash]).decode('utf-8')
+ return result.strip()
+
+ def author_name(self):
+ result = subprocess.check_output([
+ 'git', 'show', '--no-notes', '--no-patch', '--pretty=%an',
+ self.git_hash
+ ]).decode('utf-8')
+ return result.strip()
+
+ def committer_timestamp(self):
+ return self.timestamp
+
def git_commit_from_hash(hash):
commit_timestamp = subprocess.check_output(
- ['git', 'show', '--no-patch', '--no-notes', '--pretty=\'%ct\'',
- hash]).decode().strip().strip('\'')
+ ['git', 'show', '--no-patch', '--no-notes', '--pretty=%ct',
+ hash]).decode('utf-8').strip()
destination_dir = '%s/%s/' % (MASTER_COMMITS, hash)
destination = '%s%s' % (destination_dir, 'r8.jar')
commit = GitCommit(hash, destination_dir, destination, commit_timestamp)
diff --git a/tools/perf.py b/tools/perf.py
index 9e7a7b8..32d657a 100755
--- a/tools/perf.py
+++ b/tools/perf.py
@@ -94,18 +94,18 @@
return json.loads(''.join(lines))
-def GetArtifactLocation(app, filename, options):
- version = options.version or utils.get_HEAD_sha1()
- return f'{app}/{options.target}/{version}/{filename}'
+def GetArtifactLocation(app, target, version, filename):
+ version_or_head = version or utils.get_HEAD_sha1()
+ return f'{app}/{target}/{version_or_head}/{filename}'
def GetGSLocation(filename):
return f'gs://{BUCKET}/{filename}'
-def ArchiveOutputFile(file, dest, options):
- if options.outdir:
- dest_in_outdir = os.path.join(options.outdir, dest)
+def ArchiveOutputFile(file, dest, outdir=None):
+ if outdir:
+ dest_in_outdir = os.path.join(outdir, dest)
os.makedirs(os.path.dirname(dest_in_outdir), exist_ok=True)
shutil.copyfile(file, dest_in_outdir)
else:
@@ -126,7 +126,8 @@
if options.outdir:
raise NotImplementedError
output = GetGSLocation(
- GetArtifactLocation(app, 'result.json', options))
+ GetArtifactLocation(app, options.target, options.version,
+ 'result.json'))
if utils.cloud_storage_exists(output):
print(f'Skipping run, {output} already exists.')
continue
@@ -165,18 +166,20 @@
json.dump(
MergeBenchmarkResultJsonFiles(benchmark_result_json_files),
f)
- ArchiveOutputFile(result_file,
- GetArtifactLocation(app, 'result.json', options),
- options)
+ ArchiveOutputFile(
+ result_file,
+ GetArtifactLocation(app, options.target, options.version,
+ 'result.json'), options.outdir)
# Write metadata.
if os.environ.get('SWARMING_BOT_ID'):
meta_file = os.path.join(temp, "meta")
with open(meta_file, 'w') as f:
f.write("Produced by: " + os.environ.get('SWARMING_BOT_ID'))
- ArchiveOutputFile(meta_file,
- GetArtifactLocation(app, 'meta', options),
- options)
+ ArchiveOutputFile(
+ meta_file,
+ GetArtifactLocation(app, options.target, options.version,
+ 'meta'), options.outdir)
if __name__ == '__main__':
diff --git a/tools/upload_benchmark_data_to_google_storage.py b/tools/upload_benchmark_data_to_google_storage.py
new file mode 100755
index 0000000..02b46e2
--- /dev/null
+++ b/tools/upload_benchmark_data_to_google_storage.py
@@ -0,0 +1,70 @@
+#!/usr/bin/env python3
+# Copyright (c) 2024, the R8 project authors. Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+import historic_run
+import json
+import os
+import perf
+import utils
+
+import sys
+
+APPS = ['NowInAndroidApp', 'TiviApp']
+TARGETS = ['r8-full']
+NUM_COMMITS = 1000
+
+
+def ParseJsonFromCloudStorage(filename):
+ gs_location = perf.GetGSLocation(filename)
+ if not utils.file_exists_on_cloud_storage(gs_location):
+ return None
+ content = utils.cat_file_on_cloud_storage(gs_location)
+ try:
+ return json.loads(''.join(content))
+ except:
+ return None
+
+
+def main():
+ if utils.get_HEAD_branch() != 'main':
+ print('Expected to be on branch \'main\'')
+ sys.exit(1)
+
+ # Get the N most recent commits sorted by newest first.
+ top = utils.get_HEAD_sha1()
+ bottom = utils.get_nth_sha1_from_HEAD(NUM_COMMITS - 1)
+ commits = historic_run.enumerate_git_commits(top, bottom)
+ assert len(commits) == NUM_COMMITS
+
+ # Aggregate all the result.json files into a single benchmark_data.json file
+ # that has the same format as tools/perf/benchmark_data.json.
+ benchmark_data = []
+ for commit in commits:
+ benchmarks = {}
+ for app in APPS:
+ for target in TARGETS:
+ filename = perf.GetArtifactLocation(app, target, commit.hash(),
+ 'result.json')
+ app_benchmark_data = ParseJsonFromCloudStorage(filename)
+ if app_benchmark_data:
+ benchmarks[app] = app_benchmark_data
+ if len(benchmarks):
+ benchmark_data.append({
+ 'author': commit.author_name(),
+ 'hash': commit.hash(),
+ 'submitted': commit.committer_timestamp(),
+ 'title': commit.title(),
+ 'benchmarks': benchmarks
+ })
+
+ with utils.TempDir() as temp:
+ benchmark_data_file = os.path.join(temp, 'benchmark_data.json')
+ with open(benchmark_data_file, 'w') as f:
+ json.dump(benchmark_data, f)
+ perf.ArchiveOutputFile(benchmark_data_file, 'benchmark_data.json')
+
+
+if __name__ == '__main__':
+ sys.exit(main())
diff --git a/tools/utils.py b/tools/utils.py
index 4bd6910..f483212 100644
--- a/tools/utils.py
+++ b/tools/utils.py
@@ -350,6 +350,13 @@
subprocess.check_output(cmd)
+def get_nth_sha1_from_HEAD(n):
+ result = subprocess.check_output(
+ ['git', 'log', f'--skip={n}', '--max-count=1',
+ '--pretty=format:%H']).decode('utf-8')
+ return result.strip()
+
+
def get_sha1(filename):
sha1 = hashlib.sha1()
with open(filename, 'rb') as f: