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
« 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
5from cuda.core._version import __version__
8def _import_versioned_module() -> None:
9 """Check that the installed cuda-bindings is supported, then select the build for it.
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
25 from cuda.core import _bindings_floor
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
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__)
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 )
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 )
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
93_import_versioned_module()
94del _import_versioned_module
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
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
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
120 import rlcompleter
121 from types import GetSetDescriptorType, MemberDescriptorType
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))
132 class _PatchedProperty(metaclass=_PatchedPropMeta):
133 pass
135 rlcompleter.property = _PatchedProperty # type: ignore[attr-defined]
138_patch_rlcompleter_for_cython_properties()
139del _patch_rlcompleter_for_cython_properties
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
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]
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