diff --git a/cuda_bindings/cuda/__init__.pxd b/cuda_bindings/cuda/__init__.pxd deleted file mode 100644 index e69de29bb..000000000 diff --git a/cuda_bindings/cuda/__init__.py b/cuda_bindings/cuda/__init__.py deleted file mode 100644 index 56b8d5a8c..000000000 --- a/cuda_bindings/cuda/__init__.py +++ /dev/null @@ -1,14 +0,0 @@ -def __getattr__(name): - if name == "__version__": - import warnings - - warnings.warn( - "accessing cuda.__version__ is deprecated, please switch to use cuda.bindings.__version__ instead", - DeprecationWarning, - stacklevel=2, - ) - from . import bindings - - return bindings.__version__ - - raise AttributeError(f"module {__name__!r} has no attribute {name!r}") diff --git a/cuda_bindings/cuda/ccuda.pxd b/cuda_bindings/cuda/ccuda.pxd index 73f3fc5cb..2a0f2672f 100644 --- a/cuda_bindings/cuda/ccuda.pxd +++ b/cuda_bindings/cuda/ccuda.pxd @@ -2,6 +2,11 @@ from cuda.bindings.cydriver cimport * cdef extern from *: """ + #ifdef _MSC_VER #pragma message ( "The cuda.ccuda module is deprecated and will be removed in a future release, " \ "please switch to use the cuda.bindings.cydriver module instead." ) + #else + #warning The cuda.ccuda module is deprecated and will be removed in a future release, \ + please switch to use the cuda.bindings.cydriver module instead. + #endif """ diff --git a/cuda_bindings/cuda/ccuda.pyx b/cuda_bindings/cuda/ccuda.pyx index a07525bbd..0ad01d58f 100644 --- a/cuda_bindings/cuda/ccuda.pyx +++ b/cuda_bindings/cuda/ccuda.pyx @@ -1,12 +1,4 @@ from cuda.bindings.cydriver cimport * - -cdef extern from *: - """ - #pragma message ( "The cuda.ccuda module is deprecated and will be removed in a future release, " \ - "please switch to use the cuda.bindings.cydriver module instead." ) - """ - - from cuda.bindings import cydriver __pyx_capi__ = cydriver.__pyx_capi__ del cydriver diff --git a/cuda_bindings/cuda/ccudart.pxd b/cuda_bindings/cuda/ccudart.pxd index b32eece81..f7c3def5d 100644 --- a/cuda_bindings/cuda/ccudart.pxd +++ b/cuda_bindings/cuda/ccudart.pxd @@ -2,6 +2,11 @@ from cuda.bindings.cyruntime cimport * cdef extern from *: """ + #ifdef _MSC_VER #pragma message ( "The cuda.ccudart module is deprecated and will be removed in a future release, " \ "please switch to use the cuda.bindings.cyruntime module instead." ) + #else + #warning The cuda.ccudart module is deprecated and will be removed in a future release, \ + please switch to use the cuda.bindings.cyruntime module instead. + #endif """ diff --git a/cuda_bindings/cuda/ccudart.pyx b/cuda_bindings/cuda/ccudart.pyx index 3cef08112..17b3c1ea8 100644 --- a/cuda_bindings/cuda/ccudart.pyx +++ b/cuda_bindings/cuda/ccudart.pyx @@ -1,12 +1,4 @@ from cuda.bindings.cyruntime cimport * - -cdef extern from *: - """ - #pragma message ( "The cuda.ccudart module is deprecated and will be removed in a future release, " \ - "please switch to use the cuda.bindings.cyruntime module instead." ) - """ - - from cuda.bindings import cyruntime __pyx_capi__ = cyruntime.__pyx_capi__ del cyruntime diff --git a/cuda_bindings/cuda/cnvrtc.pxd b/cuda_bindings/cuda/cnvrtc.pxd index d4034084e..ed8170713 100644 --- a/cuda_bindings/cuda/cnvrtc.pxd +++ b/cuda_bindings/cuda/cnvrtc.pxd @@ -2,6 +2,11 @@ from cuda.bindings.cynvrtc cimport * cdef extern from *: """ + #ifdef _MSC_VER #pragma message ( "The cuda.cnvrtc module is deprecated and will be removed in a future release, " \ "please switch to use the cuda.bindings.cynvrtc module instead." ) + #else + #warning The cuda.cnvrtc module is deprecated and will be removed in a future release, \ + please switch to use the cuda.bindings.cynvrtc module instead. + #endif """ diff --git a/cuda_bindings/cuda/cnvrtc.pyx b/cuda_bindings/cuda/cnvrtc.pyx index 405d7de00..319512fa5 100644 --- a/cuda_bindings/cuda/cnvrtc.pyx +++ b/cuda_bindings/cuda/cnvrtc.pyx @@ -1,12 +1,4 @@ from cuda.bindings.cynvrtc cimport * - -cdef extern from *: - """ - #pragma message ( "The cuda.cnvrtc module is deprecated and will be removed in a future release, " \ - "please switch to use the cuda.bindings.cynvrtc module instead." ) - """ - - from cuda.bindings import cynvrtc __pyx_capi__ = cynvrtc.__pyx_capi__ del cynvrtc diff --git a/cuda_bindings/cuda/cuda.pyx b/cuda_bindings/cuda/cuda.pyx index f8b197f71..981b62228 100644 --- a/cuda_bindings/cuda/cuda.pyx +++ b/cuda_bindings/cuda/cuda.pyx @@ -5,10 +5,15 @@ from cuda.bindings.driver import * cdef extern from *: """ + #ifdef _MSC_VER #pragma message ( "The cuda.cuda module is deprecated and will be removed in a future release, " \ "please switch to use the cuda.bindings.driver module instead." ) + #else + #warning The cuda.cuda module is deprecated and will be removed in a future release, \ + please switch to use the cuda.bindings.driver module instead. + #endif """ _warnings.warn("The cuda.cuda module is deprecated and will be removed in a future release, " - "please switch to use the cuda.bindings.driver module instead.", DeprecationWarning, stacklevel=2) + "please switch to use the cuda.bindings.driver module instead.", FutureWarning, stacklevel=2) diff --git a/cuda_bindings/cuda/cudart.pyx b/cuda_bindings/cuda/cudart.pyx index 8c342df80..e3d2986bb 100644 --- a/cuda_bindings/cuda/cudart.pyx +++ b/cuda_bindings/cuda/cudart.pyx @@ -5,10 +5,15 @@ from cuda.bindings.runtime import * cdef extern from *: """ + #ifdef _MSC_VER #pragma message ( "The cuda.cudart module is deprecated and will be removed in a future release, " \ "please switch to use the cuda.bindings.runtime module instead." ) + #else + #warning The cuda.cudart module is deprecated and will be removed in a future release, \ + please switch to use the cuda.bindings.runtime module instead. + #endif """ _warnings.warn("The cuda.cudart module is deprecated and will be removed in a future release, " - "please switch to use the cuda.bindings.runtime module instead.", DeprecationWarning, stacklevel=2) + "please switch to use the cuda.bindings.runtime module instead.", FutureWarning, stacklevel=2) diff --git a/cuda_bindings/cuda/nvrtc.pyx b/cuda_bindings/cuda/nvrtc.pyx index 4a9e048f2..09ff61b8c 100644 --- a/cuda_bindings/cuda/nvrtc.pyx +++ b/cuda_bindings/cuda/nvrtc.pyx @@ -5,10 +5,15 @@ from cuda.bindings.nvrtc import * cdef extern from *: """ + #ifdef _MSC_VER #pragma message ( "The cuda.nvrtc module is deprecated and will be removed in a future release, " \ "please switch to use the cuda.bindings.nvrtc module instead." ) + #else + #warning The cuda.nvrtc module is deprecated and will be removed in a future release, \ + please switch to use the cuda.bindings.nvrtc module instead. + #endif """ _warnings.warn("The cuda.nvrtc module is deprecated and will be removed in a future release, " - "please switch to use the cuda.bindings.nvrtc module instead.", DeprecationWarning, stacklevel=2) + "please switch to use the cuda.bindings.nvrtc module instead.", FutureWarning, stacklevel=2) diff --git a/cuda_bindings/pyproject.toml b/cuda_bindings/pyproject.toml index 8921cc5a2..e6a9492f5 100644 --- a/cuda_bindings/pyproject.toml +++ b/cuda_bindings/pyproject.toml @@ -25,6 +25,7 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", "Environment :: GPU :: NVIDIA CUDA", ] dynamic = [ diff --git a/cuda_bindings/setup.py b/cuda_bindings/setup.py index e14d060cf..d9fa93d5c 100644 --- a/cuda_bindings/setup.py +++ b/cuda_bindings/setup.py @@ -1,4 +1,4 @@ -# Copyright 2021-2024 NVIDIA Corporation. All rights reserved. +# Copyright 2021-2025 NVIDIA Corporation. All rights reserved. # # Please refer to the NVIDIA end user license agreement (EULA) associated # with this source code for terms and conditions that govern your use of @@ -10,6 +10,7 @@ import contextlib import glob import os +import pathlib import platform import shutil import sys @@ -23,6 +24,8 @@ from setuptools import find_packages, setup from setuptools.command.bdist_wheel import bdist_wheel from setuptools.command.build_ext import build_ext +from setuptools.command.build_py import build_py +from setuptools.command.editable_wheel import _TopLevelFinder, editable_wheel from setuptools.extension import Extension # ---------------------------------------------------------------------- @@ -402,9 +405,79 @@ def build_extension(self, ext): super().build_extension(ext) +################################################################################ +# Adapted from NVIDIA/numba-cuda +# TODO: Remove this block once we get rid of cuda.__version__ and the .pth files + +REDIRECTOR_PTH = "_cuda_bindings_redirector.pth" +REDIRECTOR_PY = "_cuda_bindings_redirector.py" +SITE_PACKAGES = pathlib.Path("site-packages") + + +class build_py_with_redirector(build_py): # noqa: N801 + """Include the redirector files in the generated wheel.""" + + def copy_redirector_file(self, source, destination="."): + destination = pathlib.Path(self.build_lib) / destination + self.copy_file(str(source), str(destination), preserve_mode=0) + + def run(self): + super().run() + self.copy_redirector_file(SITE_PACKAGES / REDIRECTOR_PTH) + self.copy_redirector_file(SITE_PACKAGES / REDIRECTOR_PY) + + def get_source_files(self): + src = super().get_source_files() + src.extend( + [ + str(SITE_PACKAGES / REDIRECTOR_PTH), + str(SITE_PACKAGES / REDIRECTOR_PY), + ] + ) + return src + + def get_output_mapping(self): + mapping = super().get_output_mapping() + build_lib = pathlib.Path(self.build_lib) + mapping[str(build_lib / REDIRECTOR_PTH)] = REDIRECTOR_PTH + mapping[str(build_lib / REDIRECTOR_PY)] = REDIRECTOR_PY + return mapping + + +class TopLevelFinderWithRedirector(_TopLevelFinder): + """Include the redirector files in the editable wheel.""" + + def get_implementation(self): + for item in super().get_implementation(): # noqa: UP028 + yield item + + with open(SITE_PACKAGES / REDIRECTOR_PTH) as f: + yield (REDIRECTOR_PTH, f.read()) + + with open(SITE_PACKAGES / REDIRECTOR_PY) as f: + yield (REDIRECTOR_PY, f.read()) + + +class editable_wheel_with_redirector(editable_wheel): + def _select_strategy(self, name, tag, build_lib): + # The default mode is "lenient" - others are "strict" and "compat". + # "compat" is deprecated. "strict" creates a tree of links to files in + # the repo. It could be implemented, but we only handle the default + # case for now. + if self.mode is not None and self.mode != "lenient": + raise RuntimeError(f"Only lenient mode is supported for editable install. Current mode is {self.mode}") + + return TopLevelFinderWithRedirector(self.distribution, name) + + +################################################################################ + + cmdclass = { "bdist_wheel": WheelsBuildExtensions, "build_ext": ParallelBuildExtensions, + "build_py": build_py_with_redirector, + "editable_wheel": editable_wheel_with_redirector, } # ---------------------------------------------------------------------- diff --git a/cuda_bindings/site-packages/_cuda_bindings_redirector.pth b/cuda_bindings/site-packages/_cuda_bindings_redirector.pth new file mode 100644 index 000000000..c8a1ca9e6 --- /dev/null +++ b/cuda_bindings/site-packages/_cuda_bindings_redirector.pth @@ -0,0 +1 @@ +import _cuda_bindings_redirector diff --git a/cuda_bindings/site-packages/_cuda_bindings_redirector.py b/cuda_bindings/site-packages/_cuda_bindings_redirector.py new file mode 100644 index 000000000..c5e7a144a --- /dev/null +++ b/cuda_bindings/site-packages/_cuda_bindings_redirector.py @@ -0,0 +1,28 @@ +# Copyright 2025 NVIDIA Corporation. All rights reserved. + +import sys +from types import ModuleType + + +class LazyCudaModule(ModuleType): + + def __getattr__(self, name): + if name == '__version__': + import warnings + warnings.warn( + "accessing cuda.__version__ is deprecated, " "please switch to use cuda.bindings.__version__ instead", + FutureWarning, + stacklevel=2, + ) + from cuda.bindings import __version__ + + return __version__ + + raise AttributeError(f"module {__name__!r} has no attribute {name!r}") + + +# Important: We need to populate the cuda namespace module first, otherwise +# we'd lose access to any of its submodules. This is a cheap op because there +# is nothing under cuda.bindings. +import cuda.bindings +sys.modules['cuda'].__class__ = LazyCudaModule