Skip to content

Commit f720e48

Browse files
authored
Improve optional CUDA module import handling for NVVM and nvJitLink (#1733)
* fix(core,pathfinder): harden optional NVVM and nvJitLink imports Add a shared `optional_cuda_import` API in cuda.pathfinder so optional module checks only suppress genuinely unavailable modules or dynamic libs while still surfacing nested import bugs. Wire cuda.core NVVM/nvJitLink detection to this helper and declare cuda-pathfinder as a direct cuda-core dependency. Made-with: Cursor * chore(pathfinder): address pre-commit follow-ups Apply ruff-preferred import ordering in pathfinder exports and rename an unused test lambda argument so repository-wide pre-commit checks pass cleanly. Made-with: Cursor * address review feedback for issue 980 PR Raise the cuda-core dependency floor to cuda-pathfinder>=1.4.2, move the new optional import note to 1.4.2 release notes, and simplify nvJitLink warning text by inlining the fixed version detail. Made-with: Cursor
1 parent 3695783 commit f720e48

File tree

12 files changed

+307
-51
lines changed

12 files changed

+307
-51
lines changed

cuda_core/cuda/core/_linker.pyx

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ from dataclasses import dataclass
2929
from typing import Union
3030
from warnings import warn
3131

32+
from cuda.pathfinder import optional_cuda_import
3233
from cuda.core._device import Device
3334
from cuda.core._module import ObjectCode
3435
from cuda.core._utils.clear_error_support import assert_type
@@ -649,23 +650,20 @@ def _decide_nvjitlink_or_driver() -> bool:
649650
" For best results, consider upgrading to a recent version of"
650651
)
651652

652-
try:
653-
__import__("cuda.bindings.nvjitlink") # availability check
654-
except ModuleNotFoundError:
653+
nvjitlink_module = optional_cuda_import(
654+
"cuda.bindings.nvjitlink",
655+
probe_function=lambda module: module.version(), # probe triggers nvJitLink runtime load
656+
)
657+
if nvjitlink_module is None:
655658
warn_txt = f"cuda.bindings.nvjitlink is not available, therefore {warn_txt_common} cuda-bindings."
656659
else:
657660
from cuda.bindings._internal import nvjitlink
658661

659-
try:
660-
if _nvjitlink_has_version_symbol(nvjitlink):
661-
_use_nvjitlink_backend = True
662-
return False # Use nvjitlink
663-
except RuntimeError:
664-
warn_detail = "not available"
665-
else:
666-
warn_detail = "too old (<12.3)"
662+
if _nvjitlink_has_version_symbol(nvjitlink):
663+
_use_nvjitlink_backend = True
664+
return False # Use nvjitlink
667665
warn_txt = (
668-
f"{'nvJitLink*.dll' if sys.platform == 'win32' else 'libnvJitLink.so*'} is {warn_detail}."
666+
f"{'nvJitLink*.dll' if sys.platform == 'win32' else 'libnvJitLink.so*'} is too old (<12.3)."
669667
f" Therefore cuda.bindings.nvjitlink is not usable and {warn_txt_common} nvJitLink."
670668
)
671669

cuda_core/cuda/core/_program.pyx

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import threading
1414
from warnings import warn
1515

1616
from cuda.bindings import driver, nvrtc
17+
from cuda.pathfinder import optional_cuda_import
1718

1819
from libcpp.vector cimport vector
1920

@@ -461,8 +462,8 @@ class ProgramOptions:
461462
# =============================================================================
462463

463464
# Module-level state for NVVM lazy loading
464-
cdef object_nvvm_module = None
465-
cdef bint _nvvm_import_attempted = False
465+
_nvvm_module = None
466+
_nvvm_import_attempted = False
466467

467468

468469
def _get_nvvm_module():
@@ -484,18 +485,21 @@ def _get_nvvm_module():
484485
"Please update cuda-bindings to use NVVM features."
485486
)
486487

487-
from cuda.bindings import nvvm
488-
from cuda.bindings._internal.nvvm import _inspect_function_pointer
489-
490-
if _inspect_function_pointer("__nvvmCreateProgram") == 0:
491-
raise RuntimeError("NVVM library (libnvvm) is not available in this Python environment. ")
488+
nvvm = optional_cuda_import(
489+
"cuda.bindings.nvvm",
490+
probe_function=lambda module: module.version(), # probe triggers libnvvm load
491+
)
492+
if nvvm is None:
493+
raise RuntimeError(
494+
"NVVM support is unavailable: cuda.bindings.nvvm is missing or libnvvm cannot be loaded."
495+
)
492496

493497
_nvvm_module = nvvm
494498
return _nvvm_module
495499

496-
except RuntimeError as e:
500+
except RuntimeError:
497501
_nvvm_module = None
498-
raise e
502+
raise
499503

500504
def _find_libdevice_path():
501505
"""Find libdevice*.bc for NVVM compilation using cuda.pathfinder."""

cuda_core/docs/source/release/0.7.x-notes.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,6 @@ Fixes and enhancements
4040
linking operations to the C level and releasing the GIL during backend calls. This benefits
4141
workloads that create many programs or linkers, and enables concurrent compilation in
4242
multithreaded applications.
43+
- Improved optional dependency handling for NVVM and nvJitLink imports so that only genuinely
44+
missing optional modules are treated as unavailable; unrelated import failures now surface
45+
normally, and ``cuda.core`` now depends directly on ``cuda-pathfinder``.

cuda_core/pixi.lock

Lines changed: 29 additions & 30 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cuda_core/pixi.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ numpy = "*"
148148
# Using path dependency now that we've added .pth support for Cython .pxd files
149149
# See build_hooks.py:_add_cython_include_paths_to_pth()
150150
cuda-bindings = { path = "../cuda_bindings" }
151+
cuda-pathfinder = { path = "../cuda_pathfinder" }
151152

152153
[target.linux.tasks.build-cython-tests]
153154
cmd = ["$PIXI_PROJECT_ROOT/tests/cython/build_tests.sh"]

cuda_core/pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ classifiers = [
4747
"Environment :: GPU :: NVIDIA CUDA :: 13",
4848
]
4949
dependencies = [
50+
"cuda-pathfinder >=1.4.2",
5051
"numpy",
5152
]
5253

0 commit comments

Comments
 (0)