This is an automated email from the ASF dual-hosted git repository.

tqchen pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tvm-ffi.git


The following commit(s) were added to refs/heads/main by this push:
     new 95ea3a08 [FIX] Resolve JIT GPU backend by explicit signals, not stray 
/opt/rocm (#652)
95ea3a08 is described below

commit 95ea3a08fcee2f6103c4dd7d829f37abd3ae9b7e
Author: Tianqi Chen <[email protected]>
AuthorDate: Sun Jul 5 08:19:13 2026 +0800

    [FIX] Resolve JIT GPU backend by explicit signals, not stray /opt/rocm 
(#652)
    
    Fixes #651.
    
    The JIT extension backend selector decided CUDA-vs-HIP by probing for a
    ROCm
    home, whose fallback returns `/opt/rocm` whenever that directory merely
    exists.
    A CUDA/NVIDIA host carrying a stray `/opt/rocm` was therefore
    misclassified as
    HIP even with `nvcc` present and no `hipcc`.
    
    `_detect_gpu_backend()` now resolves the backend from explicit signals,
    in
    order: the `TVM_FFI_GPU_BACKEND` override, then PyTorch build signals
    (`torch.version.hip` / `torch.version.cuda`), then an available `hipcc`
    when no
    `nvcc` is present. Detection defaults to CUDA when otherwise
    inconclusive, and
    the existence of `/opt/rocm` alone never forces HIP. Toolkit-home,
    compiler,
    include-path, flag, and architecture discovery are unchanged and run
    only after
    the backend is resolved, so CUDA and HIP state never mix.
---
 python/tvm_ffi/cpp/extension.py | 43 ++++++++++++++++++++++++++++++++++-------
 1 file changed, 36 insertions(+), 7 deletions(-)

diff --git a/python/tvm_ffi/cpp/extension.py b/python/tvm_ffi/cpp/extension.py
index 32b3b17c..f27a48fe 100644
--- a/python/tvm_ffi/cpp/extension.py
+++ b/python/tvm_ffi/cpp/extension.py
@@ -40,21 +40,50 @@ BACKEND_STR = Literal["cuda", "hip"]
 logger = logging.getLogger(__name__)
 
 
+def _find_compiler(name: str, *home_vars: str) -> str | None:
+    """Locate a compiler on ``PATH`` or under an env-specified toolkit home's 
``bin``."""
+    found = shutil.which(name)
+    if found is not None:
+        return found
+    for var in home_vars:
+        home = os.environ.get(var)
+        if home:
+            found = shutil.which(name, path=str(Path(home) / "bin"))
+            if found is not None:
+                return found
+    return None
+
+
 @functools.lru_cache
 def _detect_gpu_backend() -> BACKEND_STR:
-    """Auto-detect whether to use CUDA or HIP (ROCm).
-
-    Returns 'hip' if ROCm/HIP is available, 'cuda' otherwise.
+    """Auto-detect whether to use CUDA or HIP (ROCm), defaulting to CUDA.
+
+    Resolution order: the ``TVM_FFI_GPU_BACKEND`` override, then PyTorch build
+    signals (``torch.version.hip`` / ``torch.version.cuda``), then a 
discoverable
+    ``hipcc`` when no ``nvcc`` can be found. Compilers are resolved from 
``PATH``
+    and from the ``CUDA_HOME``/``CUDA_PATH`` and ``ROCM_HOME``/``ROCM_PATH``
+    toolkit homes, so an env-specified CUDA install is honored even when 
``nvcc``
+    is off ``PATH``. The mere existence of ``/opt/rocm`` is not treated as
+    evidence of HIP.
     """
-    # Check environment variable override first
     backend = os.environ.get("TVM_FFI_GPU_BACKEND", "").lower()
     if backend in ("cuda", "hip"):
         return backend  # type: ignore[return-value]
     try:
-        _find_rocm_home()
+        import torch  # noqa: PLC0415
+
+        version = getattr(torch, "version", None)
+        if getattr(version, "hip", None):
+            return "hip"
+        if getattr(version, "cuda", None):
+            return "cuda"
+    except Exception:
+        pass
+    if _find_compiler("nvcc", "CUDA_HOME", "CUDA_PATH") is None and (
+        _find_compiler("hipcc", "ROCM_HOME", "ROCM_PATH") is not None
+    ):
         return "hip"
-    except RuntimeError:
-        return "cuda"
+    return "cuda"
 
 
 def _resolve_gpu_backend(backend: str | None) -> BACKEND_STR:

Reply via email to