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
156 lines
5.5 KiB
Python
156 lines
5.5 KiB
Python
#!/usr/bin/env python3
|
|
# Copyright Advanced Micro Devices, Inc., or its affiliates.
|
|
# SPDX-License-Identifier: MIT
|
|
#
|
|
# Run TensileLogic --check-all on library logic. Cross-platform (Windows and Unix).
|
|
#
|
|
# How to run (from hipblaslt project root):
|
|
# python scripts/run_tensile_logic_check.py [LIBLOGIC_PATH]
|
|
# If the current Python is missing deps (e.g. joblib), the script will re-run itself
|
|
# with .venv/bin/python (Unix) or .venv\Scripts\python.exe (Windows) if that venv exists.
|
|
# Requires: a full build first so rocisa exists under build/tensilelite/rocisa
|
|
# (nanobind package: rocisa/_rocisa*.so) or legacy build/tensilelite/rocisa/lib.
|
|
|
|
import os
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
|
|
def _find_hipblaslt_root() -> Path:
|
|
root = Path(__file__).resolve().parent.parent
|
|
if not (root / "tensilelite").is_dir() or not (root / "library").is_dir():
|
|
raise SystemExit(
|
|
"Error: Cannot find hipblaslt root (expected tensilelite/ and library/). "
|
|
"Run from hipblaslt root or keep scripts/ in the project tree."
|
|
)
|
|
return root
|
|
|
|
|
|
def _ensure_paths(root: Path, build_dir: Path, lib_logic_path: Path) -> None:
|
|
"""Prepend sys.path entries so `import rocisa` and Tensile resolve.
|
|
|
|
CMake places the nanobind module under build/tensilelite/rocisa/rocisa/
|
|
(_rocisa*.so). The importable package root is build/tensilelite/rocisa.
|
|
Older trees may only have a single rocisa*.so under rocisa/lib/; prefer
|
|
the modern layout when both exist so a stale lib/ artifact cannot shadow.
|
|
"""
|
|
tensilelite = root / "tensilelite"
|
|
rocisa_build = build_dir / "tensilelite" / "rocisa"
|
|
rocisa_pkg = rocisa_build / "rocisa"
|
|
rocisa_lib = rocisa_build / "lib"
|
|
|
|
def _has_modern_rocisa() -> bool:
|
|
if not rocisa_pkg.is_dir():
|
|
return False
|
|
return bool(
|
|
list(rocisa_pkg.glob("_rocisa*.so")) + list(rocisa_pkg.glob("_rocisa*.pyd"))
|
|
)
|
|
|
|
def _has_legacy_rocisa() -> bool:
|
|
if not rocisa_lib.is_dir():
|
|
return False
|
|
return bool(
|
|
list(rocisa_lib.glob("rocisa*.so")) + list(rocisa_lib.glob("rocisa*.pyd"))
|
|
)
|
|
|
|
if _has_modern_rocisa():
|
|
rocisa_path_entries = [rocisa_build]
|
|
elif _has_legacy_rocisa():
|
|
rocisa_path_entries = [rocisa_lib]
|
|
else:
|
|
raise SystemExit(
|
|
"Error: rocisa not built. Run a full build first. Expected either:\n"
|
|
f" {rocisa_pkg} with _rocisa*.so or .pyd, or legacy\n"
|
|
f" {rocisa_lib} with rocisa*.so or .pyd"
|
|
)
|
|
|
|
if not lib_logic_path.exists():
|
|
raise SystemExit(f"Error: Library logic path not found: {lib_logic_path}")
|
|
|
|
for path in (*rocisa_path_entries, tensilelite):
|
|
path_str = str(path.resolve())
|
|
if path_str not in sys.path:
|
|
sys.path.insert(0, path_str)
|
|
|
|
|
|
def _parse_argv(root: Path):
|
|
"""Split script argv into library path (or default) and options to pass to TensileLogic (-j, -v, etc.)."""
|
|
default_lib = root / "library"
|
|
args = sys.argv[1:]
|
|
lib_path = None
|
|
passthrough = []
|
|
i = 0
|
|
while i < len(args):
|
|
a = args[i]
|
|
if a in ("-j", "--jobs", "-v", "--verbose") or a.startswith("--jobs="):
|
|
passthrough.append(a)
|
|
i += 1
|
|
if i < len(args) and a in ("-j", "--jobs", "-v", "--verbose") and not args[i].startswith("-"):
|
|
passthrough.append(args[i])
|
|
i += 1
|
|
elif a == "--check-all":
|
|
i += 1 # we add it below
|
|
elif a == "--known-bugs":
|
|
passthrough.append(a)
|
|
i += 1
|
|
if i < len(args) and not args[i].startswith("-"):
|
|
passthrough.append(args[i])
|
|
i += 1
|
|
else:
|
|
raise SystemExit("Error: --known-bugs requires a file path")
|
|
elif not a.startswith("-"):
|
|
lib_path = Path(a)
|
|
i += 1
|
|
passthrough.extend(args[i:])
|
|
break
|
|
else:
|
|
passthrough.append(a)
|
|
i += 1
|
|
return (lib_path if lib_path is not None else default_lib, passthrough)
|
|
|
|
|
|
def main() -> None:
|
|
root = _find_hipblaslt_root()
|
|
build_dir = root / "build"
|
|
lib_logic_path, passthrough = _parse_argv(root)
|
|
_ensure_paths(root, build_dir, lib_logic_path)
|
|
|
|
default_known_bugs = (
|
|
root / "tensilelite" / "Tensile" / "TensileLogic" / "known_bugs.yaml"
|
|
)
|
|
if default_known_bugs.is_file() and "--known-bugs" not in passthrough:
|
|
passthrough = ["--known-bugs", str(default_known_bugs)] + passthrough
|
|
|
|
# TensileLogic: LOGIC_PATH [options] --check-all
|
|
sys.argv = ["TensileLogic", str(lib_logic_path.resolve())] + passthrough + ["--check-all"]
|
|
|
|
from Tensile.TensileLogic import main as tensile_logic_main
|
|
tensile_logic_main()
|
|
|
|
|
|
def _try_venv_reexec() -> None:
|
|
"""If key deps are missing but project .venv exists, re-exec with venv Python (never returns)."""
|
|
if os.environ.get("HIPBLASLT_LOGIC_CHECK_VENV"):
|
|
return # Already running under venv
|
|
try:
|
|
import joblib # noqa: F401
|
|
return
|
|
except ImportError:
|
|
pass
|
|
root = Path(__file__).resolve().parent.parent
|
|
if sys.platform == "win32":
|
|
venv_py = root / ".venv" / "Scripts" / "python.exe"
|
|
else:
|
|
venv_py = root / ".venv" / "bin" / "python"
|
|
if not venv_py.is_file():
|
|
return
|
|
os.environ["HIPBLASLT_LOGIC_CHECK_VENV"] = "1"
|
|
script = Path(__file__).resolve()
|
|
os.execv(venv_py, [str(venv_py), str(script)] + sys.argv[1:])
|
|
# execv does not return on success
|
|
|
|
|
|
if __name__ == "__main__":
|
|
_try_venv_reexec()
|
|
main()
|