From 01f33cdce0b783e721e55b779c0713b7415d105f Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Tue, 24 Mar 2026 16:47:01 -0700 Subject: [PATCH 01/10] build: use cuda.pathfinder.get_cuda_path_or_home in build hooks Pin cuda-pathfinder>=1.5 in both build-system.requires and project.dependencies. Made-with: Cursor --- cuda_bindings/build_hooks.py | 32 ++++++++++++++++++++++++----- cuda_bindings/pyproject.toml | 3 ++- cuda_core/build_hooks.py | 32 ++++++++++++++++++++++++----- cuda_core/pyproject.toml | 3 ++- cuda_core/tests/test_build_hooks.py | 7 ++++++- 5 files changed, 64 insertions(+), 13 deletions(-) diff --git a/cuda_bindings/build_hooks.py b/cuda_bindings/build_hooks.py index a48aa0f0e9..1bd2b37424 100644 --- a/cuda_bindings/build_hooks.py +++ b/cuda_bindings/build_hooks.py @@ -33,13 +33,35 @@ _extensions = None +# Please keep in sync with the copy in cuda_core/build_hooks.py. +def _import_get_cuda_path_or_home(): + """Import get_cuda_path_or_home, working around PEP 517 namespace shadowing. + + In isolated build environments, backend-path=["."] causes the ``cuda`` + namespace package to resolve to only the project's ``cuda/`` directory, + hiding ``cuda.pathfinder`` installed in the build-env's site-packages. + Fix by replacing ``cuda.__path__`` with a plain list that includes the + site-packages ``cuda/`` directory. + """ + try: + import cuda.pathfinder + except ModuleNotFoundError: + import cuda + + for p in sys.path: + sp_cuda = os.path.join(p, "cuda") + if os.path.isdir(os.path.join(sp_cuda, "pathfinder")): + cuda.__path__ = list(cuda.__path__) + [sp_cuda] + break + import cuda.pathfinder + + return cuda.pathfinder.get_cuda_path_or_home + + @functools.cache def _get_cuda_path() -> str: - # Not using cuda.pathfinder.get_cuda_path_or_home() here because this - # build backend runs in an isolated venv where the cuda namespace package - # from backend-path shadows the installed cuda-pathfinder. See #1803 for - # a workaround to apply after cuda-pathfinder >= 1.5 is released. - cuda_path = os.environ.get("CUDA_PATH", os.environ.get("CUDA_HOME")) + get_cuda_path_or_home = _import_get_cuda_path_or_home() + cuda_path = get_cuda_path_or_home() if not cuda_path: raise RuntimeError("Environment variable CUDA_PATH or CUDA_HOME is not set") print("CUDA path:", cuda_path) diff --git a/cuda_bindings/pyproject.toml b/cuda_bindings/pyproject.toml index 96cfb4dd07..9a4f189815 100644 --- a/cuda_bindings/pyproject.toml +++ b/cuda_bindings/pyproject.toml @@ -6,6 +6,7 @@ requires = [ "setuptools_scm[simple]>=8", "cython>=3.2,<3.3", "pyclibrary>=0.1.7", + "cuda-pathfinder>=1.5", ] build-backend = "build_hooks" backend-path = ["."] @@ -31,7 +32,7 @@ classifiers = [ "Environment :: GPU :: NVIDIA CUDA", ] dynamic = ["version", "readme"] -dependencies = ["cuda-pathfinder >=1.4.2"] +dependencies = ["cuda-pathfinder >=1.5"] [project.optional-dependencies] all = [ diff --git a/cuda_core/build_hooks.py b/cuda_core/build_hooks.py index b368b02759..912848317a 100644 --- a/cuda_core/build_hooks.py +++ b/cuda_core/build_hooks.py @@ -28,13 +28,35 @@ COMPILE_FOR_COVERAGE = bool(int(os.environ.get("CUDA_PYTHON_COVERAGE", "0"))) +# Please keep in sync with the copy in cuda_bindings/build_hooks.py. +def _import_get_cuda_path_or_home(): + """Import get_cuda_path_or_home, working around PEP 517 namespace shadowing. + + In isolated build environments, backend-path=["."] causes the ``cuda`` + namespace package to resolve to only the project's ``cuda/`` directory, + hiding ``cuda.pathfinder`` installed in the build-env's site-packages. + Fix by replacing ``cuda.__path__`` with a plain list that includes the + site-packages ``cuda/`` directory. + """ + try: + import cuda.pathfinder + except ModuleNotFoundError: + import cuda + + for p in sys.path: + sp_cuda = os.path.join(p, "cuda") + if os.path.isdir(os.path.join(sp_cuda, "pathfinder")): + cuda.__path__ = list(cuda.__path__) + [sp_cuda] + break + import cuda.pathfinder + + return cuda.pathfinder.get_cuda_path_or_home + + @functools.cache def _get_cuda_path() -> str: - # Not using cuda.pathfinder.get_cuda_path_or_home() here because this - # build backend runs in an isolated venv where the cuda namespace package - # from backend-path shadows the installed cuda-pathfinder. See #1803 for - # a workaround to apply after cuda-pathfinder >= 1.5 is released. - cuda_path = os.environ.get("CUDA_PATH", os.environ.get("CUDA_HOME")) + get_cuda_path_or_home = _import_get_cuda_path_or_home() + cuda_path = get_cuda_path_or_home() if not cuda_path: raise RuntimeError("Environment variable CUDA_PATH or CUDA_HOME is not set") print("CUDA path:", cuda_path) diff --git a/cuda_core/pyproject.toml b/cuda_core/pyproject.toml index 107c2ffb92..dc418342b5 100644 --- a/cuda_core/pyproject.toml +++ b/cuda_core/pyproject.toml @@ -7,6 +7,7 @@ requires = [ "setuptools>=80", "setuptools-scm[simple]>=8", "Cython>=3.2,<3.3", + "cuda-pathfinder>=1.5" ] build-backend = "build_hooks" backend-path = ["."] @@ -47,7 +48,7 @@ classifiers = [ "Environment :: GPU :: NVIDIA CUDA :: 13", ] dependencies = [ - "cuda-pathfinder >=1.4.2", + "cuda-pathfinder >=1.5", "numpy", ] diff --git a/cuda_core/tests/test_build_hooks.py b/cuda_core/tests/test_build_hooks.py index b298e7a977..121ed1be05 100644 --- a/cuda_core/tests/test_build_hooks.py +++ b/cuda_core/tests/test_build_hooks.py @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: Copyright (c) 2024-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-FileCopyrightText: Copyright (c) 2024-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. # SPDX-License-Identifier: Apache-2.0 """Tests for build_hooks.py build infrastructure. @@ -24,6 +24,8 @@ import pytest +from cuda.pathfinder import get_cuda_path_or_home + # build_hooks.py imports Cython and setuptools at the top level, so skip if not available pytest.importorskip("Cython") pytest.importorskip("setuptools") @@ -68,6 +70,7 @@ def _check_version_detection( build_hooks._get_cuda_path.cache_clear() build_hooks._determine_cuda_major_version.cache_clear() + get_cuda_path_or_home.cache_clear() mock_env = { k: v @@ -92,6 +95,7 @@ def test_env_var_override(self, version): """CUDA_CORE_BUILD_MAJOR env var override works with various versions.""" build_hooks._get_cuda_path.cache_clear() build_hooks._determine_cuda_major_version.cache_clear() + get_cuda_path_or_home.cache_clear() with mock.patch.dict(os.environ, {"CUDA_CORE_BUILD_MAJOR": version}, clear=False): result = build_hooks._determine_cuda_major_version() assert result == version @@ -125,6 +129,7 @@ def test_missing_cuda_path_raises_error(self): """RuntimeError is raised when CUDA_PATH/CUDA_HOME not set and no env var override.""" build_hooks._get_cuda_path.cache_clear() build_hooks._determine_cuda_major_version.cache_clear() + get_cuda_path_or_home.cache_clear() with ( mock.patch.dict(os.environ, {}, clear=True), pytest.raises(RuntimeError, match="CUDA_PATH or CUDA_HOME"), From 0fc45970483957817d5e7c78086afc68027cf605 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Tue, 24 Mar 2026 16:53:24 -0700 Subject: [PATCH 02/10] chore: update stale pixi package version to 1.5.0 The previous 1.3.4a0 was a stale value that could confuse someone. Made-with: Cursor --- cuda_pathfinder/pixi.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cuda_pathfinder/pixi.toml b/cuda_pathfinder/pixi.toml index 0d780290b6..961450699c 100644 --- a/cuda_pathfinder/pixi.toml +++ b/cuda_pathfinder/pixi.toml @@ -36,7 +36,7 @@ cu12 = { features = ["cu12", "test"], solve-group = "cu12" } # TODO: check if these can be extracted from pyproject.toml [package] name = "cuda-pathfinder" -version = "1.3.4a0" +version = "1.5.0" [package.build] backend = { name = "pixi-build-python", version = "*" } From 3d422de019926291c9107598918393b4c8584525 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Wed, 25 Mar 2026 11:18:42 -0700 Subject: [PATCH 03/10] build: raise actionable error when cuda-pathfinder not found on sys.path Made-with: Cursor --- cuda_bindings/build_hooks.py | 5 +++++ cuda_core/build_hooks.py | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/cuda_bindings/build_hooks.py b/cuda_bindings/build_hooks.py index 1bd2b37424..9e592431ee 100644 --- a/cuda_bindings/build_hooks.py +++ b/cuda_bindings/build_hooks.py @@ -53,6 +53,11 @@ def _import_get_cuda_path_or_home(): if os.path.isdir(os.path.join(sp_cuda, "pathfinder")): cuda.__path__ = list(cuda.__path__) + [sp_cuda] break + else: + raise ModuleNotFoundError( + "cuda-pathfinder is not installed in the build environment. " + "Ensure 'cuda-pathfinder>=1.5' is in build-system.requires." + ) import cuda.pathfinder return cuda.pathfinder.get_cuda_path_or_home diff --git a/cuda_core/build_hooks.py b/cuda_core/build_hooks.py index 912848317a..d5f2bb43a2 100644 --- a/cuda_core/build_hooks.py +++ b/cuda_core/build_hooks.py @@ -48,6 +48,11 @@ def _import_get_cuda_path_or_home(): if os.path.isdir(os.path.join(sp_cuda, "pathfinder")): cuda.__path__ = list(cuda.__path__) + [sp_cuda] break + else: + raise ModuleNotFoundError( + "cuda-pathfinder is not installed in the build environment. " + "Ensure 'cuda-pathfinder>=1.5' is in build-system.requires." + ) import cuda.pathfinder return cuda.pathfinder.get_cuda_path_or_home From 6892ae01391c92f30a28699f1e710120451b8037 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Wed, 25 Mar 2026 12:37:22 -0700 Subject: [PATCH 04/10] build: replace inline docstring with reference to issue #1824 Made-with: Cursor --- cuda_bindings/build_hooks.py | 6 +----- cuda_core/build_hooks.py | 6 +----- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/cuda_bindings/build_hooks.py b/cuda_bindings/build_hooks.py index 9e592431ee..9c6710a264 100644 --- a/cuda_bindings/build_hooks.py +++ b/cuda_bindings/build_hooks.py @@ -37,11 +37,7 @@ def _import_get_cuda_path_or_home(): """Import get_cuda_path_or_home, working around PEP 517 namespace shadowing. - In isolated build environments, backend-path=["."] causes the ``cuda`` - namespace package to resolve to only the project's ``cuda/`` directory, - hiding ``cuda.pathfinder`` installed in the build-env's site-packages. - Fix by replacing ``cuda.__path__`` with a plain list that includes the - site-packages ``cuda/`` directory. + See https://github.com/NVIDIA/cuda-python/issues/1824 for why this helper is needed. """ try: import cuda.pathfinder diff --git a/cuda_core/build_hooks.py b/cuda_core/build_hooks.py index d5f2bb43a2..ce77de3c17 100644 --- a/cuda_core/build_hooks.py +++ b/cuda_core/build_hooks.py @@ -32,11 +32,7 @@ def _import_get_cuda_path_or_home(): """Import get_cuda_path_or_home, working around PEP 517 namespace shadowing. - In isolated build environments, backend-path=["."] causes the ``cuda`` - namespace package to resolve to only the project's ``cuda/`` directory, - hiding ``cuda.pathfinder`` installed in the build-env's site-packages. - Fix by replacing ``cuda.__path__`` with a plain list that includes the - site-packages ``cuda/`` directory. + See https://github.com/NVIDIA/cuda-python/issues/1824 for why this helper is needed. """ try: import cuda.pathfinder From b779d0d99a90a155b8fd9a242c13f5b4d6d872fb Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Tue, 31 Mar 2026 08:41:32 -0700 Subject: [PATCH 05/10] build: narrow except to only catch cuda.pathfinder-not-found Made-with: Cursor --- cuda_bindings/build_hooks.py | 4 +++- cuda_core/build_hooks.py | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/cuda_bindings/build_hooks.py b/cuda_bindings/build_hooks.py index 9c6710a264..398d0d7f62 100644 --- a/cuda_bindings/build_hooks.py +++ b/cuda_bindings/build_hooks.py @@ -41,7 +41,9 @@ def _import_get_cuda_path_or_home(): """ try: import cuda.pathfinder - except ModuleNotFoundError: + except ModuleNotFoundError as exc: + if exc.name != "cuda.pathfinder": + raise import cuda for p in sys.path: diff --git a/cuda_core/build_hooks.py b/cuda_core/build_hooks.py index ce77de3c17..6b51d02b30 100644 --- a/cuda_core/build_hooks.py +++ b/cuda_core/build_hooks.py @@ -36,7 +36,9 @@ def _import_get_cuda_path_or_home(): """ try: import cuda.pathfinder - except ModuleNotFoundError: + except ModuleNotFoundError as exc: + if exc.name != "cuda.pathfinder": + raise import cuda for p in sys.path: From 6facaa5272c289e3d93576a446567871a4ca732c Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Tue, 31 Mar 2026 08:52:40 -0700 Subject: [PATCH 06/10] build: use importlib.metadata to locate cuda-pathfinder instead of scanning sys.path Made-with: Cursor --- cuda_bindings/build_hooks.py | 18 +++++++++++------- cuda_core/build_hooks.py | 18 +++++++++++------- 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/cuda_bindings/build_hooks.py b/cuda_bindings/build_hooks.py index 398d0d7f62..07c370c5ee 100644 --- a/cuda_bindings/build_hooks.py +++ b/cuda_bindings/build_hooks.py @@ -44,18 +44,22 @@ def _import_get_cuda_path_or_home(): except ModuleNotFoundError as exc: if exc.name != "cuda.pathfinder": raise + from importlib.metadata import PackageNotFoundError, distribution + from pathlib import Path + import cuda - for p in sys.path: - sp_cuda = os.path.join(p, "cuda") - if os.path.isdir(os.path.join(sp_cuda, "pathfinder")): - cuda.__path__ = list(cuda.__path__) + [sp_cuda] - break - else: + try: + dist = distribution("cuda-pathfinder") + except PackageNotFoundError: raise ModuleNotFoundError( "cuda-pathfinder is not installed in the build environment. " "Ensure 'cuda-pathfinder>=1.5' is in build-system.requires." - ) + ) from None + site_cuda = str(dist.locate_file(Path("cuda"))) + cuda_paths = list(cuda.__path__) + if site_cuda not in cuda_paths: + cuda.__path__ = cuda_paths + [site_cuda] import cuda.pathfinder return cuda.pathfinder.get_cuda_path_or_home diff --git a/cuda_core/build_hooks.py b/cuda_core/build_hooks.py index 6b51d02b30..3483f7d041 100644 --- a/cuda_core/build_hooks.py +++ b/cuda_core/build_hooks.py @@ -39,18 +39,22 @@ def _import_get_cuda_path_or_home(): except ModuleNotFoundError as exc: if exc.name != "cuda.pathfinder": raise + from importlib.metadata import PackageNotFoundError, distribution + from pathlib import Path + import cuda - for p in sys.path: - sp_cuda = os.path.join(p, "cuda") - if os.path.isdir(os.path.join(sp_cuda, "pathfinder")): - cuda.__path__ = list(cuda.__path__) + [sp_cuda] - break - else: + try: + dist = distribution("cuda-pathfinder") + except PackageNotFoundError: raise ModuleNotFoundError( "cuda-pathfinder is not installed in the build environment. " "Ensure 'cuda-pathfinder>=1.5' is in build-system.requires." - ) + ) from None + site_cuda = str(dist.locate_file(Path("cuda"))) + cuda_paths = list(cuda.__path__) + if site_cuda not in cuda_paths: + cuda.__path__ = cuda_paths + [site_cuda] import cuda.pathfinder return cuda.pathfinder.get_cuda_path_or_home From f1ef076d5063a16c5224fbacb185aaeac4f0ab5f Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Tue, 31 Mar 2026 09:40:54 -0700 Subject: [PATCH 07/10] build: produce actionable error when cuda namespace is entirely absent Made-with: Cursor --- cuda_bindings/build_hooks.py | 6 +++--- cuda_core/build_hooks.py | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/cuda_bindings/build_hooks.py b/cuda_bindings/build_hooks.py index 07c370c5ee..81a112e022 100644 --- a/cuda_bindings/build_hooks.py +++ b/cuda_bindings/build_hooks.py @@ -42,13 +42,11 @@ def _import_get_cuda_path_or_home(): try: import cuda.pathfinder except ModuleNotFoundError as exc: - if exc.name != "cuda.pathfinder": + if exc.name not in ("cuda", "cuda.pathfinder"): raise from importlib.metadata import PackageNotFoundError, distribution from pathlib import Path - import cuda - try: dist = distribution("cuda-pathfinder") except PackageNotFoundError: @@ -56,6 +54,8 @@ def _import_get_cuda_path_or_home(): "cuda-pathfinder is not installed in the build environment. " "Ensure 'cuda-pathfinder>=1.5' is in build-system.requires." ) from None + import cuda + site_cuda = str(dist.locate_file(Path("cuda"))) cuda_paths = list(cuda.__path__) if site_cuda not in cuda_paths: diff --git a/cuda_core/build_hooks.py b/cuda_core/build_hooks.py index 3483f7d041..fcca21ad95 100644 --- a/cuda_core/build_hooks.py +++ b/cuda_core/build_hooks.py @@ -37,13 +37,11 @@ def _import_get_cuda_path_or_home(): try: import cuda.pathfinder except ModuleNotFoundError as exc: - if exc.name != "cuda.pathfinder": + if exc.name not in ("cuda", "cuda.pathfinder"): raise from importlib.metadata import PackageNotFoundError, distribution from pathlib import Path - import cuda - try: dist = distribution("cuda-pathfinder") except PackageNotFoundError: @@ -51,6 +49,8 @@ def _import_get_cuda_path_or_home(): "cuda-pathfinder is not installed in the build environment. " "Ensure 'cuda-pathfinder>=1.5' is in build-system.requires." ) from None + import cuda + site_cuda = str(dist.locate_file(Path("cuda"))) cuda_paths = list(cuda.__path__) if site_cuda not in cuda_paths: From 3cb0313301d2b3ce1dd822542d8fced87546cbd5 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Tue, 31 Mar 2026 10:02:48 -0700 Subject: [PATCH 08/10] build: diagnostic for importlib.metadata locate_file in PEP 517 builds Made-with: Cursor --- cuda_bindings/build_hooks.py | 19 ++++++++++++++++++- cuda_core/build_hooks.py | 19 ++++++++++++++++++- 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/cuda_bindings/build_hooks.py b/cuda_bindings/build_hooks.py index 81a112e022..1a59777aeb 100644 --- a/cuda_bindings/build_hooks.py +++ b/cuda_bindings/build_hooks.py @@ -56,10 +56,27 @@ def _import_get_cuda_path_or_home(): ) from None import cuda - site_cuda = str(dist.locate_file(Path("cuda"))) + locate_result = str(dist.locate_file(Path("cuda"))) + print(f"[diag] dist._path: {dist._path}", flush=True) + print(f"[diag] dist._path.parent: {dist._path.parent}", flush=True) + print(f"[diag] locate_file('cuda'): {locate_result}", flush=True) + print(f"[diag] locate_file exists: {os.path.isdir(locate_result)}", flush=True) + print( + f"[diag] locate_file/pathfinder exists: {os.path.isdir(os.path.join(locate_result, 'pathfinder'))}", + flush=True, + ) + print(f"[diag] cuda.__path__ (before): {cuda.__path__}", flush=True) + print("[diag] sys.path:", flush=True) + for p in sys.path: + sp_cuda = os.path.join(p, "cuda") + has_pf = os.path.isdir(os.path.join(sp_cuda, "pathfinder")) + print(f"[diag] {p} -> cuda/pathfinder exists: {has_pf}", flush=True) + + site_cuda = locate_result cuda_paths = list(cuda.__path__) if site_cuda not in cuda_paths: cuda.__path__ = cuda_paths + [site_cuda] + print(f"[diag] cuda.__path__ (after): {cuda.__path__}", flush=True) import cuda.pathfinder return cuda.pathfinder.get_cuda_path_or_home diff --git a/cuda_core/build_hooks.py b/cuda_core/build_hooks.py index fcca21ad95..6b4a117faa 100644 --- a/cuda_core/build_hooks.py +++ b/cuda_core/build_hooks.py @@ -51,10 +51,27 @@ def _import_get_cuda_path_or_home(): ) from None import cuda - site_cuda = str(dist.locate_file(Path("cuda"))) + locate_result = str(dist.locate_file(Path("cuda"))) + print(f"[diag] dist._path: {dist._path}", flush=True) + print(f"[diag] dist._path.parent: {dist._path.parent}", flush=True) + print(f"[diag] locate_file('cuda'): {locate_result}", flush=True) + print(f"[diag] locate_file exists: {os.path.isdir(locate_result)}", flush=True) + print( + f"[diag] locate_file/pathfinder exists: {os.path.isdir(os.path.join(locate_result, 'pathfinder'))}", + flush=True, + ) + print(f"[diag] cuda.__path__ (before): {cuda.__path__}", flush=True) + print("[diag] sys.path:", flush=True) + for p in sys.path: + sp_cuda = os.path.join(p, "cuda") + has_pf = os.path.isdir(os.path.join(sp_cuda, "pathfinder")) + print(f"[diag] {p} -> cuda/pathfinder exists: {has_pf}", flush=True) + + site_cuda = locate_result cuda_paths = list(cuda.__path__) if site_cuda not in cuda_paths: cuda.__path__ = cuda_paths + [site_cuda] + print(f"[diag] cuda.__path__ (after): {cuda.__path__}", flush=True) import cuda.pathfinder return cuda.pathfinder.get_cuda_path_or_home From a9995acafe50dc42d359054acf4cb0244eee5176 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Tue, 31 Mar 2026 12:14:23 -0700 Subject: [PATCH 09/10] Revert "build: diagnostic for importlib.metadata locate_file in PEP 517 builds" This reverts commit 3cb0313301d2b3ce1dd822542d8fced87546cbd5. --- cuda_bindings/build_hooks.py | 19 +------------------ cuda_core/build_hooks.py | 19 +------------------ 2 files changed, 2 insertions(+), 36 deletions(-) diff --git a/cuda_bindings/build_hooks.py b/cuda_bindings/build_hooks.py index 1a59777aeb..81a112e022 100644 --- a/cuda_bindings/build_hooks.py +++ b/cuda_bindings/build_hooks.py @@ -56,27 +56,10 @@ def _import_get_cuda_path_or_home(): ) from None import cuda - locate_result = str(dist.locate_file(Path("cuda"))) - print(f"[diag] dist._path: {dist._path}", flush=True) - print(f"[diag] dist._path.parent: {dist._path.parent}", flush=True) - print(f"[diag] locate_file('cuda'): {locate_result}", flush=True) - print(f"[diag] locate_file exists: {os.path.isdir(locate_result)}", flush=True) - print( - f"[diag] locate_file/pathfinder exists: {os.path.isdir(os.path.join(locate_result, 'pathfinder'))}", - flush=True, - ) - print(f"[diag] cuda.__path__ (before): {cuda.__path__}", flush=True) - print("[diag] sys.path:", flush=True) - for p in sys.path: - sp_cuda = os.path.join(p, "cuda") - has_pf = os.path.isdir(os.path.join(sp_cuda, "pathfinder")) - print(f"[diag] {p} -> cuda/pathfinder exists: {has_pf}", flush=True) - - site_cuda = locate_result + site_cuda = str(dist.locate_file(Path("cuda"))) cuda_paths = list(cuda.__path__) if site_cuda not in cuda_paths: cuda.__path__ = cuda_paths + [site_cuda] - print(f"[diag] cuda.__path__ (after): {cuda.__path__}", flush=True) import cuda.pathfinder return cuda.pathfinder.get_cuda_path_or_home diff --git a/cuda_core/build_hooks.py b/cuda_core/build_hooks.py index 6b4a117faa..fcca21ad95 100644 --- a/cuda_core/build_hooks.py +++ b/cuda_core/build_hooks.py @@ -51,27 +51,10 @@ def _import_get_cuda_path_or_home(): ) from None import cuda - locate_result = str(dist.locate_file(Path("cuda"))) - print(f"[diag] dist._path: {dist._path}", flush=True) - print(f"[diag] dist._path.parent: {dist._path.parent}", flush=True) - print(f"[diag] locate_file('cuda'): {locate_result}", flush=True) - print(f"[diag] locate_file exists: {os.path.isdir(locate_result)}", flush=True) - print( - f"[diag] locate_file/pathfinder exists: {os.path.isdir(os.path.join(locate_result, 'pathfinder'))}", - flush=True, - ) - print(f"[diag] cuda.__path__ (before): {cuda.__path__}", flush=True) - print("[diag] sys.path:", flush=True) - for p in sys.path: - sp_cuda = os.path.join(p, "cuda") - has_pf = os.path.isdir(os.path.join(sp_cuda, "pathfinder")) - print(f"[diag] {p} -> cuda/pathfinder exists: {has_pf}", flush=True) - - site_cuda = locate_result + site_cuda = str(dist.locate_file(Path("cuda"))) cuda_paths = list(cuda.__path__) if site_cuda not in cuda_paths: cuda.__path__ = cuda_paths + [site_cuda] - print(f"[diag] cuda.__path__ (after): {cuda.__path__}", flush=True) import cuda.pathfinder return cuda.pathfinder.get_cuda_path_or_home From cb5ffbb136ea6559fbe62ec085327116e58bda11 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Tue, 31 Mar 2026 12:18:11 -0700 Subject: [PATCH 10/10] build: revert to sys.path scan, importlib.metadata finds wrong dist-info See https://github.com/NVIDIA/cuda-python/pull/1817#discussion_r3017709196 See https://github.com/NVIDIA/cuda-python/pull/1817#discussion_r3017746666 Made-with: Cursor --- cuda_bindings/build_hooks.py | 23 +++++++++++------------ cuda_core/build_hooks.py | 23 +++++++++++------------ 2 files changed, 22 insertions(+), 24 deletions(-) diff --git a/cuda_bindings/build_hooks.py b/cuda_bindings/build_hooks.py index 81a112e022..b08b0d24d8 100644 --- a/cuda_bindings/build_hooks.py +++ b/cuda_bindings/build_hooks.py @@ -44,22 +44,21 @@ def _import_get_cuda_path_or_home(): except ModuleNotFoundError as exc: if exc.name not in ("cuda", "cuda.pathfinder"): raise - from importlib.metadata import PackageNotFoundError, distribution - from pathlib import Path - try: - dist = distribution("cuda-pathfinder") - except PackageNotFoundError: + import cuda + except ModuleNotFoundError: + cuda = None + + for p in sys.path: + sp_cuda = os.path.join(p, "cuda") + if os.path.isdir(os.path.join(sp_cuda, "pathfinder")): + cuda.__path__ = list(cuda.__path__) + [sp_cuda] + break + else: raise ModuleNotFoundError( "cuda-pathfinder is not installed in the build environment. " "Ensure 'cuda-pathfinder>=1.5' is in build-system.requires." - ) from None - import cuda - - site_cuda = str(dist.locate_file(Path("cuda"))) - cuda_paths = list(cuda.__path__) - if site_cuda not in cuda_paths: - cuda.__path__ = cuda_paths + [site_cuda] + ) import cuda.pathfinder return cuda.pathfinder.get_cuda_path_or_home diff --git a/cuda_core/build_hooks.py b/cuda_core/build_hooks.py index fcca21ad95..491879c2ab 100644 --- a/cuda_core/build_hooks.py +++ b/cuda_core/build_hooks.py @@ -39,22 +39,21 @@ def _import_get_cuda_path_or_home(): except ModuleNotFoundError as exc: if exc.name not in ("cuda", "cuda.pathfinder"): raise - from importlib.metadata import PackageNotFoundError, distribution - from pathlib import Path - try: - dist = distribution("cuda-pathfinder") - except PackageNotFoundError: + import cuda + except ModuleNotFoundError: + cuda = None + + for p in sys.path: + sp_cuda = os.path.join(p, "cuda") + if os.path.isdir(os.path.join(sp_cuda, "pathfinder")): + cuda.__path__ = list(cuda.__path__) + [sp_cuda] + break + else: raise ModuleNotFoundError( "cuda-pathfinder is not installed in the build environment. " "Ensure 'cuda-pathfinder>=1.5' is in build-system.requires." - ) from None - import cuda - - site_cuda = str(dist.locate_file(Path("cuda"))) - cuda_paths = list(cuda.__path__) - if site_cuda not in cuda_paths: - cuda.__path__ = cuda_paths + [site_cuda] + ) import cuda.pathfinder return cuda.pathfinder.get_cuda_path_or_home