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
109 lines
4.2 KiB
Python
109 lines
4.2 KiB
Python
import os
|
|
import platform
|
|
import re
|
|
import subprocess
|
|
import sys
|
|
import logging
|
|
|
|
|
|
def prepend_env_path(env: dict, var_name: str, new_path: str):
|
|
"""
|
|
Prepend a new path to an environment variable that contains a list of paths (e.g., PATH, LD_LIBRARY_PATH).
|
|
"""
|
|
existing = env.get(var_name)
|
|
if existing:
|
|
env[var_name] = f"{new_path}{os.pathsep}{existing}"
|
|
else:
|
|
env[var_name] = new_path
|
|
|
|
|
|
def _try_offload_arch(therock_build_dir: str, file_ending: str):
|
|
"""Try offload-arch; return gfxNNNN string or None."""
|
|
executable = therock_build_dir + f"/lib/llvm/bin/offload-arch{file_ending}"
|
|
try:
|
|
result = subprocess.run([executable], capture_output=True, text=True)
|
|
lines = [l.strip() for l in result.stdout.strip().split("\n") if l.strip()]
|
|
logging.info(f"DEBUG offload-arch:{lines}")
|
|
if lines:
|
|
last = lines[-1]
|
|
if last.startswith("gfx"):
|
|
if result.returncode != 0:
|
|
logging.warning(
|
|
f"offload-arch exited {result.returncode} but returned '{last}'; using it"
|
|
)
|
|
return last
|
|
if result.returncode != 0:
|
|
logging.warning(
|
|
f"offload-arch failed (exit {result.returncode}): {result.stderr}"
|
|
)
|
|
except FileNotFoundError:
|
|
logging.warning("offload-arch not found")
|
|
return None
|
|
|
|
|
|
def _try_rocminfo(therock_build_dir: str, file_ending: str):
|
|
"""Try rocminfo (uses HSA runtime, works on MxGPU); return gfxNNNN or None."""
|
|
executable = therock_build_dir + f"/bin/rocminfo{file_ending}"
|
|
try:
|
|
result = subprocess.run([executable], capture_output=True, text=True)
|
|
# rocminfo output contains lines like: Name: gfx1101
|
|
for line in result.stdout.splitlines():
|
|
line = line.strip()
|
|
if line.startswith("Name:"):
|
|
match = re.search(r"gfx\d+", line)
|
|
if match:
|
|
arch = match.group(0)
|
|
logging.info(f"DEBUG rocminfo detected: {arch}")
|
|
return arch
|
|
except FileNotFoundError:
|
|
logging.warning("rocminfo not found")
|
|
return None
|
|
|
|
|
|
def get_gpu_architecture_portable(therock_build_dir):
|
|
"""
|
|
Detect the GPU gfxNNNN architecture string.
|
|
|
|
Tries multiple detection methods in order:
|
|
1. offload-arch (fast, but fails on some MxGPU virtual GPUs)
|
|
2. rocminfo (uses HSA runtime)
|
|
|
|
If AMDGPU_TARGETS is set in the environment (as it is in CI), validates
|
|
the detected arch against it. MxGPU virtual GPUs can cause offload-arch
|
|
to return an incorrect default (e.g. gfx906) even when the actual GPU
|
|
is different (e.g. gfx1101). If the detected arch is not in AMDGPU_TARGETS,
|
|
falls back to compiling for all targets so the binary runs on whatever
|
|
GPU is present. If detection fails entirely (None), leaves it as None so
|
|
callers can apply their own fallback (e.g. --offload-arch=native).
|
|
|
|
Note: we deliberately do NOT attempt to detect the GPU by compiling
|
|
and running a HIP program. On MxGPU virtual GPUs, forcefully killing
|
|
a process that has initialized the HIP runtime (e.g. via a timeout)
|
|
can leave the virtual GPU context in a locked state, breaking
|
|
subsequent tests (e.g. rocblas) that need GPU access.
|
|
|
|
Returns:
|
|
str: The gfx architecture (or semicolon-separated list of targets),
|
|
or None if not available.
|
|
"""
|
|
therock_build_dir = str(therock_build_dir)
|
|
file_ending = ".exe" if platform.system() == "Windows" else ""
|
|
|
|
arch = _try_offload_arch(therock_build_dir, file_ending)
|
|
if not arch:
|
|
arch = _try_rocminfo(therock_build_dir, file_ending)
|
|
|
|
# Validate against AMDGPU_TARGETS when set (authoritative in CI).
|
|
# Only apply when detection returned something — if arch is None,
|
|
# leave it for the caller to handle (e.g. via --offload-arch=native).
|
|
amdgpu_targets = os.getenv("AMDGPU_TARGETS")
|
|
if amdgpu_targets and arch is not None:
|
|
valid_targets = amdgpu_targets.split(",")
|
|
if arch not in valid_targets:
|
|
arch = ";".join(valid_targets)
|
|
logging.info(
|
|
f"++ GPU arch not in AMDGPU_TARGETS, compiling for all targets: {arch}"
|
|
)
|
|
|
|
return arch
|