CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
133 lines
5.8 KiB
Python
Executable File
133 lines
5.8 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
# ===----------------------------------------------------------------------===##
|
|
#
|
|
# 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
|
|
#
|
|
# ===----------------------------------------------------------------------===##
|
|
|
|
from typing import List, Optional, Set
|
|
import argparse
|
|
import json
|
|
import logging
|
|
import os
|
|
import pathlib
|
|
import subprocess
|
|
import sys
|
|
import time
|
|
|
|
|
|
def directory_path(string):
|
|
if os.path.isdir(string):
|
|
return pathlib.Path(string)
|
|
else:
|
|
raise NotADirectoryError(string)
|
|
|
|
def api(lnt_url: str, test_suite: str, endpoint: str):
|
|
url = f'{lnt_url}/api/db_default/v4/{test_suite}{endpoint}'
|
|
logging.debug(f'Querying {url}')
|
|
result = json.loads(subprocess.check_output(['curl', '-sS', url]).decode())
|
|
return result
|
|
|
|
def get_benchmarked_commits(lnt_url: str, test_suite: str, machine: str) -> Set[str]:
|
|
"""
|
|
Return the set of commits that have already been benchmarked on the given LNT
|
|
instance, test suite and machine.
|
|
"""
|
|
result = api(lnt_url, test_suite, f'/machines/{machine}')
|
|
commits = set()
|
|
if 'runs' not in result: # there is no such machine
|
|
return set()
|
|
for run in result['runs']:
|
|
if 'git_sha' not in run:
|
|
raise ValueError(f'Found run without a git_sha field: are you using the right LNT test suite? {run}')
|
|
commits.add(run['git_sha'])
|
|
return commits
|
|
|
|
def git_rev_list(git_repo: str, paths: List[str] = []) -> List[str]:
|
|
"""
|
|
Return the list of all revisions in the given Git repository. Older commits are earlier in the list.
|
|
"""
|
|
cli = ['git', '-C', git_repo, 'rev-list', 'origin', '--', *paths]
|
|
rev_list = subprocess.check_output(cli).decode().strip().splitlines()
|
|
return list(reversed(rev_list))
|
|
|
|
def git_sort_revlist(git_repo: str, commits: List[str]) -> List[str]:
|
|
"""
|
|
Return the list of commits sorted by their chronological order (from oldest to newest) in the
|
|
provided Git repository. Items earlier in the list are older than items later in the list.
|
|
"""
|
|
revlist_cmd = ['git', '-C', git_repo, 'rev-list', '--no-walk'] + list(commits)
|
|
revlist = subprocess.check_output(revlist_cmd, text=True).strip().splitlines()
|
|
return list(reversed(revlist))
|
|
|
|
def get_all_libcxx_commits(git_repo: str) -> Set[str]:
|
|
"""
|
|
Return the set of commits available to benchmark for libc++: this is the list of
|
|
commits that touch code in libc++ that we care to benchmark.
|
|
"""
|
|
logging.debug(f'Fetching {git_repo}')
|
|
subprocess.check_call(['git', '-C', git_repo, 'fetch', '--quiet', 'origin'])
|
|
return set(git_rev_list(git_repo, paths=['libcxx/include', 'libcxx/src']))
|
|
|
|
|
|
def main(argv):
|
|
parser = argparse.ArgumentParser(
|
|
prog='commit-watch',
|
|
description='Watch for libc++ commits to run benchmarks on and print them to standard output.',
|
|
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
|
|
parser.add_argument('--lnt-url', type=str, required=True,
|
|
help='The URL of the LNT instance to use as the source of truth for finding already-benchmarked commits.')
|
|
parser.add_argument('--test-suite', type=str, required=True,
|
|
help='The name of the test suite that we are producing results for on the LNT instance.')
|
|
parser.add_argument('--machine', type=str, required=True,
|
|
help='The name of the machine that we are producing results for on the LNT instance.')
|
|
parser.add_argument('-d', '--delay', type=int, required=False, default=60,
|
|
help='The delay (in seconds) to wait before successive polls.')
|
|
parser.add_argument('--git-repo', type=directory_path, default=os.getcwd(),
|
|
help='Optional path to the Git repository to use. By default, the current working directory is used.')
|
|
parser.add_argument('-v', '--verbose', action='count', default=0,
|
|
help='Verbosity level: passing the option multiple times increases the level.')
|
|
args = parser.parse_args(argv)
|
|
|
|
VERY_VERBOSE = logging.DEBUG - 1
|
|
if args.verbose == 1:
|
|
logging.basicConfig(level=logging.INFO)
|
|
elif args.verbose == 2:
|
|
logging.basicConfig(level=logging.DEBUG)
|
|
elif args.verbose > 2:
|
|
logging.basicConfig(level=VERY_VERBOSE)
|
|
|
|
last_commit: Optional[str] = None # last commit printed
|
|
while True:
|
|
logging.info(f'Fetching all libc++ commits in {args.git_repo}')
|
|
all_commits = get_all_libcxx_commits(args.git_repo)
|
|
logging.log(VERY_VERBOSE, f'Found all libc++ commits: {all_commits}')
|
|
|
|
logging.info(f'Getting benchmarked commits for {args.machine} from {args.lnt_url}')
|
|
benchmarked_commits = get_benchmarked_commits(args.lnt_url, args.test_suite, args.machine)
|
|
logging.log(VERY_VERBOSE, f'Found benchmarked commits: {benchmarked_commits}')
|
|
|
|
# Print the next commit that should be benchmarked, but only when it changes over the one
|
|
# that we just printed. This ensures that we don't repeatedly print that the same benchmark
|
|
# should be benchmarked, which would otherwise happen when we are running the benchmarks but
|
|
# have not submitted to LNT yet.
|
|
commits_to_benchmark = all_commits - benchmarked_commits
|
|
if not commits_to_benchmark:
|
|
logging.info('No more commits to benchmark')
|
|
else:
|
|
commits_to_benchmark = git_sort_revlist(args.git_repo, list(commits_to_benchmark))
|
|
most_recent = commits_to_benchmark[-1]
|
|
if most_recent != last_commit:
|
|
logging.info(f'Selected {most_recent}')
|
|
print(most_recent, flush=True)
|
|
last_commit = most_recent
|
|
|
|
logging.debug(f'Waiting {args.delay}s before next poll')
|
|
time.sleep(args.delay)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main(sys.argv[1:])
|