Skip to content

Commit 2b01980

Browse files
committed
Merge remote-tracking branch 'upstream/main' into debug-builds
2 parents 1608973 + f983b9d commit 2b01980

File tree

6 files changed

+124
-11
lines changed

6 files changed

+124
-11
lines changed

cuda_bindings/build_hooks.py

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,41 @@
3333
_extensions = None
3434

3535

36+
# Please keep in sync with the copy in cuda_core/build_hooks.py.
37+
def _import_get_cuda_path_or_home():
38+
"""Import get_cuda_path_or_home, working around PEP 517 namespace shadowing.
39+
40+
See https://github.com/NVIDIA/cuda-python/issues/1824 for why this helper is needed.
41+
"""
42+
try:
43+
import cuda.pathfinder
44+
except ModuleNotFoundError as exc:
45+
if exc.name not in ("cuda", "cuda.pathfinder"):
46+
raise
47+
try:
48+
import cuda
49+
except ModuleNotFoundError:
50+
cuda = None
51+
52+
for p in sys.path:
53+
sp_cuda = os.path.join(p, "cuda")
54+
if os.path.isdir(os.path.join(sp_cuda, "pathfinder")):
55+
cuda.__path__ = list(cuda.__path__) + [sp_cuda]
56+
break
57+
else:
58+
raise ModuleNotFoundError(
59+
"cuda-pathfinder is not installed in the build environment. "
60+
"Ensure 'cuda-pathfinder>=1.5' is in build-system.requires."
61+
)
62+
import cuda.pathfinder
63+
64+
return cuda.pathfinder.get_cuda_path_or_home
65+
66+
3667
@functools.cache
3768
def _get_cuda_path() -> str:
38-
# Not using cuda.pathfinder.get_cuda_path_or_home() here because this
39-
# build backend runs in an isolated venv where the cuda namespace package
40-
# from backend-path shadows the installed cuda-pathfinder. See #1803 for
41-
# a workaround to apply after cuda-pathfinder >= 1.5 is released.
42-
cuda_path = os.environ.get("CUDA_PATH", os.environ.get("CUDA_HOME"))
69+
get_cuda_path_or_home = _import_get_cuda_path_or_home()
70+
cuda_path = get_cuda_path_or_home()
4371
if not cuda_path:
4472
raise RuntimeError("Environment variable CUDA_PATH or CUDA_HOME is not set")
4573
print("CUDA path:", cuda_path)

cuda_bindings/pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ requires = [
66
"setuptools_scm[simple]>=8",
77
"cython>=3.2,<3.3",
88
"pyclibrary>=0.1.7",
9+
"cuda-pathfinder>=1.5",
910
]
1011
build-backend = "build_hooks"
1112
backend-path = ["."]

cuda_core/build_hooks.py

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,41 @@
2828
COMPILE_FOR_COVERAGE = bool(int(os.environ.get("CUDA_PYTHON_COVERAGE", "0")))
2929

3030

31+
# Please keep in sync with the copy in cuda_bindings/build_hooks.py.
32+
def _import_get_cuda_path_or_home():
33+
"""Import get_cuda_path_or_home, working around PEP 517 namespace shadowing.
34+
35+
See https://github.com/NVIDIA/cuda-python/issues/1824 for why this helper is needed.
36+
"""
37+
try:
38+
import cuda.pathfinder
39+
except ModuleNotFoundError as exc:
40+
if exc.name not in ("cuda", "cuda.pathfinder"):
41+
raise
42+
try:
43+
import cuda
44+
except ModuleNotFoundError:
45+
cuda = None
46+
47+
for p in sys.path:
48+
sp_cuda = os.path.join(p, "cuda")
49+
if os.path.isdir(os.path.join(sp_cuda, "pathfinder")):
50+
cuda.__path__ = list(cuda.__path__) + [sp_cuda]
51+
break
52+
else:
53+
raise ModuleNotFoundError(
54+
"cuda-pathfinder is not installed in the build environment. "
55+
"Ensure 'cuda-pathfinder>=1.5' is in build-system.requires."
56+
)
57+
import cuda.pathfinder
58+
59+
return cuda.pathfinder.get_cuda_path_or_home
60+
61+
3162
@functools.cache
3263
def _get_cuda_path() -> str:
33-
# Not using cuda.pathfinder.get_cuda_path_or_home() here because this
34-
# build backend runs in an isolated venv where the cuda namespace package
35-
# from backend-path shadows the installed cuda-pathfinder. See #1803 for
36-
# a workaround to apply after cuda-pathfinder >= 1.5 is released.
37-
cuda_path = os.environ.get("CUDA_PATH", os.environ.get("CUDA_HOME"))
64+
get_cuda_path_or_home = _import_get_cuda_path_or_home()
65+
cuda_path = get_cuda_path_or_home()
3866
if not cuda_path:
3967
raise RuntimeError("Environment variable CUDA_PATH or CUDA_HOME is not set")
4068
print("CUDA path:", cuda_path)

cuda_core/docs/source/install.rst

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,56 @@ and likewise use ``cuda-version=13`` for CUDA 13.
7171
Note that to use ``cuda.core`` with nvJitLink installed from conda-forge requires ``cuda.bindings`` 12.8.0+.
7272

7373

74+
Development environment
75+
-----------------------
76+
77+
The sections above cover end-user installation. The section below focuses on
78+
a repeatable *development* workflow (editable installs and running tests).
79+
80+
Development with uv
81+
~~~~~~~~~~~~~~~~~~~
82+
83+
`uv`_ is a fast Python package and project manager. For example, to work on
84+
``cuda-core`` against CUDA 13:
85+
86+
.. code-block:: console
87+
88+
$ git clone https://github.com/NVIDIA/cuda-python
89+
$ cd cuda-python/cuda_core
90+
$ uv venv
91+
$ source .venv/bin/activate # On Windows: .venv\Scripts\activate
92+
$ uv pip install -e .[cu13] --group test
93+
94+
Run tests:
95+
96+
.. code-block:: console
97+
98+
$ python -m pytest tests
99+
100+
.. _uv: https://docs.astral.sh/uv/
101+
102+
Development with pixi
103+
~~~~~~~~~~~~~~~~~~~~~
104+
105+
`pixi`_ provides a reproducible development environment across the repository.
106+
From the repository root:
107+
108+
.. code-block:: console
109+
110+
$ git clone https://github.com/NVIDIA/cuda-python
111+
$ cd cuda-python
112+
$ pixi run -e cu13 test-core
113+
114+
To run all repository tests (pathfinder → bindings → core):
115+
116+
.. code-block:: console
117+
118+
$ pixi run -e cu13 test
119+
120+
Use ``-e cu12`` to test against CUDA 12 instead.
121+
122+
.. _pixi: https://pixi.sh/
123+
74124
Installing from Source
75125
----------------------
76126

cuda_core/pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ requires = [
77
"setuptools>=80",
88
"setuptools-scm[simple]>=8",
99
"Cython>=3.2,<3.3",
10+
"cuda-pathfinder>=1.5"
1011
]
1112
build-backend = "build_hooks"
1213
backend-path = ["."]

cuda_core/tests/test_build_hooks.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# SPDX-FileCopyrightText: Copyright (c) 2024-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
1+
# SPDX-FileCopyrightText: Copyright (c) 2024-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
22
# SPDX-License-Identifier: Apache-2.0
33

44
"""Tests for build_hooks.py build infrastructure.
@@ -24,6 +24,8 @@
2424

2525
import pytest
2626

27+
from cuda.pathfinder import get_cuda_path_or_home
28+
2729
# build_hooks.py imports Cython and setuptools at the top level, so skip if not available
2830
pytest.importorskip("Cython")
2931
pytest.importorskip("setuptools")
@@ -68,6 +70,7 @@ def _check_version_detection(
6870

6971
build_hooks._get_cuda_path.cache_clear()
7072
build_hooks._determine_cuda_major_version.cache_clear()
73+
get_cuda_path_or_home.cache_clear()
7174

7275
mock_env = {
7376
k: v
@@ -92,6 +95,7 @@ def test_env_var_override(self, version):
9295
"""CUDA_CORE_BUILD_MAJOR env var override works with various versions."""
9396
build_hooks._get_cuda_path.cache_clear()
9497
build_hooks._determine_cuda_major_version.cache_clear()
98+
get_cuda_path_or_home.cache_clear()
9599
with mock.patch.dict(os.environ, {"CUDA_CORE_BUILD_MAJOR": version}, clear=False):
96100
result = build_hooks._determine_cuda_major_version()
97101
assert result == version
@@ -125,6 +129,7 @@ def test_missing_cuda_path_raises_error(self):
125129
"""RuntimeError is raised when CUDA_PATH/CUDA_HOME not set and no env var override."""
126130
build_hooks._get_cuda_path.cache_clear()
127131
build_hooks._determine_cuda_major_version.cache_clear()
132+
get_cuda_path_or_home.cache_clear()
128133
with (
129134
mock.patch.dict(os.environ, {}, clear=True),
130135
pytest.raises(RuntimeError, match="CUDA_PATH or CUDA_HOME"),

0 commit comments

Comments
 (0)