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
176 lines
5.3 KiB
Python
Executable File
176 lines
5.3 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""A utility to wrap utils/update_cc_test_checks.py for updating CHECK lines in
|
|
libclc .cl tests for a given architecture.
|
|
|
|
The script accepts an architecture argument to determine the triple and check
|
|
prefix. Supported arch values: amdgpu, amdgcn, nvptx64, spirv, spirv64.
|
|
|
|
The script does 3 things:
|
|
1. Replaces %target, %cpu, and %check_prefix in the .cl file for the arch.
|
|
2. Runs update_cc_test_checks.py to update CHECK lines.
|
|
3. Reverts the .cl file back to using %target, %cpu, and %check_prefix.
|
|
|
|
Usage:
|
|
|
|
% libclc/test/update_libclc_tests.py amdgpu
|
|
|
|
"""
|
|
|
|
import argparse
|
|
import os
|
|
import re
|
|
import subprocess
|
|
import sys
|
|
from concurrent.futures import ProcessPoolExecutor, as_completed
|
|
from pathlib import Path
|
|
|
|
ARCH_TO_TRIPLE = {
|
|
"amdgpu": "amdgcn-amd-amdhsa-llvm",
|
|
"amdgcn": "amdgcn-amd-amdhsa-llvm",
|
|
"nvptx64": "nvptx64-nvidia-cuda",
|
|
"spirv": "spirv-unknown-mesa3d",
|
|
"spirv64": "spirv64-unknown-mesa3d",
|
|
}
|
|
|
|
ARCH_TO_CPU = {
|
|
"amdgpu": "gfx900",
|
|
"amdgcn": "gfx900",
|
|
"nvptx64": "",
|
|
"spirv": "",
|
|
"spirv64": "",
|
|
}
|
|
|
|
ARCH_TO_REQUIRES = {
|
|
"amdgpu": "amdgpu-registered-target",
|
|
"amdgcn": "amdgpu-registered-target",
|
|
"nvptx64": "nvptx-registered-target",
|
|
"spirv": "spirv-registered-target",
|
|
"spirv64": "spirv-registered-target",
|
|
}
|
|
|
|
SCRIPT_DIR = Path(__file__).parent
|
|
REPO_ROOT = SCRIPT_DIR.parent.parent
|
|
UPDATE_SCRIPT = REPO_ROOT / "llvm" / "utils" / "update_cc_test_checks.py"
|
|
CLANG = REPO_ROOT / "build" / "bin" / "clang"
|
|
|
|
|
|
def find_cl_files(test_dir: Path):
|
|
return list(test_dir.rglob("*.cl"))
|
|
|
|
|
|
def replace_in_file(path: Path, triple: str, cpu: str, check_prefix: str):
|
|
content = path.read_bytes()
|
|
content = content.replace(b"%target", triple.encode())
|
|
if cpu:
|
|
content = content.replace(b"%cpu", cpu.encode())
|
|
content = content.replace(b"%check_prefix", check_prefix.encode())
|
|
content = content.replace(b"%libclc_lib", b"")
|
|
path.write_bytes(content)
|
|
|
|
|
|
def _run_line_indices(content: bytes) -> list:
|
|
RUN_MARKERS = (b"// RUN:", b"; RUN:")
|
|
return [
|
|
i
|
|
for i, l in enumerate(content.splitlines(keepends=True))
|
|
if any(l.lstrip().startswith(m) for m in RUN_MARKERS)
|
|
]
|
|
|
|
|
|
def file_requires_feature(path: Path, feature: str) -> bool:
|
|
try:
|
|
text = path.read_text(encoding="utf-8", errors="replace")
|
|
except Exception:
|
|
return False
|
|
for line in text.splitlines():
|
|
stripped = line.strip().lstrip("//").strip()
|
|
if stripped.startswith("REQUIRES:"):
|
|
rest = stripped[len("REQUIRES:") :]
|
|
features = [f.strip() for f in re.split(r",|\|\|", rest)]
|
|
if feature in features:
|
|
return True
|
|
return False
|
|
|
|
|
|
def process_file(cl_file: Path, triple: str, cpu: str, check_prefix: str) -> bool:
|
|
original = cl_file.read_bytes()
|
|
orig_lines = original.splitlines(keepends=True)
|
|
saved_run = {i: orig_lines[i] for i in _run_line_indices(original)}
|
|
replace_in_file(cl_file, triple, cpu, check_prefix)
|
|
cmd = [
|
|
sys.executable,
|
|
str(UPDATE_SCRIPT),
|
|
"--clang",
|
|
str(CLANG),
|
|
str(cl_file),
|
|
]
|
|
print(f" update: {cl_file.relative_to(REPO_ROOT)}")
|
|
result = subprocess.run(cmd, capture_output=True, text=True)
|
|
ok = result.returncode == 0
|
|
if not ok:
|
|
print(f" FAILED: {result.stderr.strip()}", file=sys.stderr)
|
|
updated = cl_file.read_bytes()
|
|
updated_lines = updated.splitlines(keepends=True)
|
|
for i, line in saved_run.items():
|
|
updated_lines[i] = line
|
|
cl_file.write_bytes(b"".join(updated_lines))
|
|
return ok
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser(
|
|
description="Update libclc FileCheck assertions for a given arch."
|
|
)
|
|
parser.add_argument(
|
|
"arch",
|
|
choices=list(ARCH_TO_TRIPLE.keys()),
|
|
help="Target arch: amdgpu, amdgcn, nvptx64, spirv, spirv64",
|
|
)
|
|
args = parser.parse_args()
|
|
|
|
arch = args.arch.lower()
|
|
triple = ARCH_TO_TRIPLE[arch]
|
|
cpu = ARCH_TO_CPU[arch]
|
|
# check_prefix matches REQUIRES feature: uppercase of canonical arch name
|
|
# amdgpu -> AMDGCN (same triple as amdgcn), others uppercased
|
|
if arch == "amdgpu":
|
|
check_prefix = "AMDGCN"
|
|
else:
|
|
check_prefix = arch.upper()
|
|
|
|
requires_feature = ARCH_TO_REQUIRES[arch]
|
|
cl_files = find_cl_files(SCRIPT_DIR)
|
|
target_files = [f for f in cl_files if file_requires_feature(f, requires_feature)]
|
|
|
|
if not target_files:
|
|
print(f"No .cl files found with REQUIRES: {requires_feature}")
|
|
return
|
|
|
|
print(
|
|
f"arch={arch} triple={triple} cpu={cpu} check_prefix={check_prefix} requires={requires_feature}"
|
|
)
|
|
print(f"Processing {len(target_files)} file(s)...")
|
|
|
|
failed = []
|
|
num_workers = max(1, os.cpu_count() // 2)
|
|
with ProcessPoolExecutor(max_workers=num_workers) as executor:
|
|
futures = {
|
|
executor.submit(process_file, f, triple, cpu, check_prefix): f
|
|
for f in target_files
|
|
}
|
|
for future in as_completed(futures):
|
|
if not future.result():
|
|
failed.append(futures[future])
|
|
|
|
if failed:
|
|
print(f"\n{len(failed)} file(s) failed:", file=sys.stderr)
|
|
for f in failed:
|
|
print(f" {f}", file=sys.stderr)
|
|
sys.exit(1)
|
|
else:
|
|
print(f"Done. Updated {len(target_files)} file(s).")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|