Coverage for cuda/core/__init__.py: 0.00%

95 statements  

« prev     ^ index     » next       coverage.py v7.16.2, created at 2026-10-16 01:23 +0000

1# SPDX-FileCopyrightText: Copyright (c) 2024-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 

2# 

3# SPDX-License-Identifier: Apache-2.0 

4 

5from cuda.core._version import __version__ 

6 

7 

8def _import_versioned_module() -> None: 

9 """Check that the installed cuda-bindings is supported, then select the build for it. 

10 

11 The published wheel carries one build per CUDA major series, as the 

12 subpackages ``cuda.core.cu12`` and ``cuda.core.cu13``. A conda or local 

13 build carries one build at the top level. Each build records the CUDA 

14 header that it compiled against and its cuda-bindings floor in the 

15 ``_build_info`` extension module. The installed cuda-bindings 

16 must be of the build's major, at least as new as the floor, and generated 

17 from a ``cuda.h`` at least as new as the build's. See 

18 ``_bindings_floor.check_installed_bindings``. If it is not, import fails 

19 here with an actionable message instead of later with a missing C function 

20 or a silently disabled feature. 

21 """ 

22 import importlib 

23 import os 

24 

25 from cuda.core import _bindings_floor 

26 

27 try: 

28 from cuda import bindings 

29 except ModuleNotFoundError as exc: 

30 if exc.name in ("cuda", "cuda.bindings"): 

31 raise ImportError("cuda.core requires cuda-bindings. Install cuda-core[cu12] or cuda-core[cu13]") from None 

32 raise 

33 

34 def load_build_info(cuda_major: int): 

35 # Prefer this major's build in the merged wheel, then fall back to a plain build. 

36 try: 

37 return importlib.import_module(f".cu{cuda_major}._build_info", __package__) 

38 except ModuleNotFoundError as exc: 

39 if exc.name != f"{__package__}.cu{cuda_major}": 

40 raise 

41 return importlib.import_module("._build_info", __package__) 

42 

43 def missing_build_message(cuda_major: int) -> str: 

44 here = os.path.dirname(__file__) 

45 builds = sorted( 

46 int(name[2:]) 

47 for name in os.listdir(here) 

48 if name.startswith("cu") and name[2:].isdigit() and os.path.isdir(os.path.join(here, name)) 

49 ) 

50 if builds: 

51 return ( 

52 f"This cuda.core installation has builds for CUDA {' and '.join(map(str, builds))}, not for " 

53 f"CUDA {cuda_major}. The installed cuda-bindings is {version_str}." 

54 ) 

55 return ( 

56 "This cuda.core has not been built: cuda/core/_build_info is missing. " 

57 "Build it with pip install, or reinstall the package." 

58 ) 

59 

60 version_str = bindings.__version__ 

61 # The major decides which build to consult. _bindings_floor validates everything else. 

62 try: 

63 cuda_major = int(version_str.split(".")[0]) 

64 except ValueError: 

65 raise ImportError( 

66 f"cuda.core requires a cuda-bindings release, but the installed cuda-bindings version is {version_str!r}" 

67 ) from None 

68 try: 

69 info = load_build_info(cuda_major) 

70 except ModuleNotFoundError as exc: 

71 raise ImportError(missing_build_message(cuda_major)) from exc 

72 # By module object: the `cuda` namespace package need not carry a `bindings` attribute. 

73 bindings_driver = importlib.import_module("cuda.bindings.driver") 

74 _bindings_floor.check_installed_bindings( 

75 version_str, 

76 int(bindings_driver.CUDA_VERSION), 

77 info.CUDA_MAJOR, 

78 info.CUDA_VERSION, 

79 info.CUDA_BINDINGS_FLOOR, 

80 __version__, 

81 ) 

82 

83 subdir = f"cu{cuda_major}" 

84 try: 

85 versioned_mod = importlib.import_module(f".{subdir}", __package__) 

86 # Import all symbols from the module 

87 globals().update(versioned_mod.__dict__) 

88 except ImportError: 

89 # This is not a wheel build, but a conda or local build, do nothing 

90 pass 

91 

92 

93_import_versioned_module() 

94del _import_versioned_module 

95 

96 

97def _patch_rlcompleter_for_cython_properties() -> None: 

98 # TODO: This can be removed when Python 3.13 is our minimum-supported version: 

99 # https://github.com/python/cpython/pull/149577 

100 

101 # Cython @property on cdef class compiles to a C-level getset_descriptor, 

102 # which rlcompleter's narrow isinstance(..., property) check misses; the 

103 # fallback getattr() then invokes the descriptor and any non-AttributeError 

104 # it raises kills tab completion. Extend that isinstance check to also 

105 # match getset_descriptor / member_descriptor. Installed unconditionally 

106 # (the patch is scoped to the rlcompleter module, so non-interactive users 

107 # only pay for the import). 

108 import os 

109 

110 raw_opt_out = os.environ.get("CUDA_CORE_DONT_FIX_TAB_COMPLETION", "").strip() 

111 try: 

112 opt_out = int(raw_opt_out) != 0 

113 except ValueError: 

114 opt_out = raw_opt_out != "" 

115 if opt_out: 

116 # Explicit opt-out for users who don't want the global rlcompleter 

117 # side effect, even in an interactive session. 

118 return 

119 

120 import rlcompleter 

121 from types import GetSetDescriptorType, MemberDescriptorType 

122 

123 # This works by overriding the `property` built-in with a custom subclass of 

124 # property, but only in the rlcompleter module. This subclass overrides the 

125 # `__instancecheck__` method to also return True for getset_descriptor and 

126 # member_descriptor types, which are what Cython uses for properties on cdef 

127 # classes. 

128 class _PatchedPropMeta(type): 

129 def __instancecheck__(cls, inst: object) -> bool: 

130 return isinstance(inst, (property, GetSetDescriptorType, MemberDescriptorType)) 

131 

132 class _PatchedProperty(metaclass=_PatchedPropMeta): 

133 pass 

134 

135 rlcompleter.property = _PatchedProperty # type: ignore[attr-defined] 

136 

137 

138_patch_rlcompleter_for_cython_properties() 

139del _patch_rlcompleter_for_cython_properties 

140 

141 

142from cuda.core import checkpoint, system, utils 

143from cuda.core._context import * 

144from cuda.core._context import __all__ as _context_all 

145from cuda.core._device import * 

146from cuda.core._device import __all__ as _device_all 

147from cuda.core._device_resources import * 

148from cuda.core._device_resources import __all__ as _device_resources_all 

149from cuda.core._event import * 

150from cuda.core._event import __all__ as _event_all 

151from cuda.core._graphics import * 

152from cuda.core._graphics import __all__ as _graphics_all 

153from cuda.core._host import * 

154from cuda.core._host import __all__ as _host_all 

155from cuda.core._launch_config import * 

156from cuda.core._launch_config import __all__ as _launch_config_all 

157from cuda.core._launcher import * 

158from cuda.core._launcher import __all__ as _launcher_all 

159from cuda.core._linker import * 

160from cuda.core._linker import __all__ as _linker_all 

161from cuda.core._memory import * 

162from cuda.core._memory import __all__ as _memory_all 

163from cuda.core._module import * 

164from cuda.core._module import __all__ as _module_all 

165from cuda.core._program import * 

166from cuda.core._program import __all__ as _program_all 

167from cuda.core._stream import * 

168from cuda.core._stream import __all__ as _stream_all 

169from cuda.core._tensor_map import * 

170from cuda.core._tensor_map import __all__ as _tensor_map_all 

171from cuda.core._utils.cuda_utils import CUDAError, CUDAWarning, NVRTCError 

172 

173__all__ = [ 

174 "CUDAError", 

175 "CUDAWarning", 

176 "NVRTCError", 

177 *_context_all, 

178 *_device_all, 

179 *_device_resources_all, 

180 *_event_all, 

181 *_graphics_all, 

182 *_host_all, 

183 *_launch_config_all, 

184 *_launcher_all, 

185 *_linker_all, 

186 *_memory_all, 

187 *_module_all, 

188 *_program_all, 

189 *_stream_all, 

190 *_tensor_map_all, 

191] 

192 

193# isort: split 

194# Texture/surface types live under the cuda.core.texture namespace (not the 

195# flat cuda.core namespace); import the subpackage so it is available as 

196# `cuda.core.texture` after `import cuda.core`. 

197# Must come after the cuda.core._* extension imports above: loading graph 

198# earlier interacts badly with the merged-wheel __path__ rewrite and leaves 

199# Graph/GraphBuilder/GraphCompleteOptions/GraphDebugPrintOptions missing from 

200# cuda.core.graph. 

201import cuda.core.graph 

202import cuda.core.texture