Skip to content

Commit c918891

Browse files
authored
Add ObjectCode.get_module() for legacy driver API integration (#2339)
* add an api to return module in ObjectCode to support calling legacy driver APIs * cuda.core: clarify ObjectCode.handle vs get_module() docstrings Document that .handle returns the native context-independent CUlibrary for cuda.core/newer APIs, while get_module() is a legacy-interop bridge returning a context-dependent CUmodule via cuLibraryGetModule.
1 parent 55cb344 commit c918891

3 files changed

Lines changed: 57 additions & 2 deletions

File tree

cuda_core/cuda/core/_module.pyi

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -458,6 +458,20 @@ class ObjectCode:
458458
459459
"""
460460

461+
def get_module(self) -> object:
462+
"""Return a context-dependent :obj:`~driver.CUmodule` for legacy interop.
463+
464+
Bridges the native :obj:`~driver.CUlibrary` (see :attr:`handle`) to a
465+
``CUmodule`` via ``cuLibraryGetModule``, for use with legacy driver APIs
466+
that only accept ``CUmodule``.
467+
468+
Returns
469+
-------
470+
:obj:`~driver.CUmodule`
471+
Module handle for the current CUDA context, suitable for legacy
472+
driver APIs that accept ``CUmodule``.
473+
"""
474+
461475
@property
462476
def code(self) -> CodeTypeT:
463477
"""Return the underlying code object."""
@@ -476,7 +490,10 @@ class ObjectCode:
476490

477491
@property
478492
def handle(self) -> object:
479-
"""Return the underlying handle object.
493+
"""Return the native, context-independent :obj:`~driver.CUlibrary` handle.
494+
495+
Used by ``cuda.core`` and newer driver library APIs. For legacy APIs
496+
that only accept a ``CUmodule``, use :meth:`get_module` instead.
480497
481498
.. caution::
482499

cuda_core/cuda/core/_module.pyx

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ from __future__ import annotations
66

77
cimport cython
88
from libc.stddef cimport size_t
9+
from libc.stdint cimport intptr_t
910

1011
from collections import namedtuple
1112
from os import fsencode, fspath, PathLike
@@ -796,6 +797,25 @@ cdef class ObjectCode:
796797
HANDLE_RETURN(get_last_error())
797798
return Kernel._from_handle(h_kernel)
798799

800+
def get_module(self) -> object:
801+
"""Return a context-dependent :obj:`~driver.CUmodule` for legacy interop.
802+
803+
Bridges the native :obj:`~driver.CUlibrary` (see :attr:`handle`) to a
804+
``CUmodule`` via ``cuLibraryGetModule``, for use with legacy driver APIs
805+
that only accept ``CUmodule``.
806+
807+
Returns
808+
-------
809+
:obj:`~driver.CUmodule`
810+
Module handle for the current CUDA context, suitable for legacy
811+
driver APIs that accept ``CUmodule``.
812+
"""
813+
self._lazy_load_module()
814+
cdef cydriver.CUmodule mod
815+
with nogil:
816+
HANDLE_RETURN(cydriver.cuLibraryGetModule(&mod, as_cu(self._h_library)))
817+
return driver.CUmodule(<intptr_t>mod)
818+
799819
@property
800820
def code(self) -> CodeTypeT:
801821
"""Return the underlying code object."""
@@ -818,7 +838,10 @@ cdef class ObjectCode:
818838

819839
@property
820840
def handle(self) -> object:
821-
"""Return the underlying handle object.
841+
"""Return the native, context-independent :obj:`~driver.CUlibrary` handle.
842+
843+
Used by ``cuda.core`` and newer driver library APIs. For legacy APIs
844+
that only accept a ``CUmodule``, use :meth:`get_module` instead.
822845

823846
.. caution::
824847

cuda_core/tests/test_module.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,21 @@ def test_get_kernel(init_cuda):
282282
assert object_code.get_kernel(b"ABC").handle is not None
283283

284284

285+
def test_object_code_get_module_for_legacy_integration(init_cuda):
286+
src = """
287+
extern "C" __global__ void ABC() { }
288+
extern "C" __global__ void DEF() { }
289+
"""
290+
object_code = Program(src, "c++").compile("cubin")
291+
292+
# Bridge: CUlibrary (new) → CUmodule (legacy)
293+
module = object_code.get_module()
294+
295+
# Legacy module-only API consumes it directly
296+
count = handle_return(driver.cuModuleGetFunctionCount(module))
297+
assert count == 2
298+
299+
285300
@pytest.mark.parametrize(
286301
"attr, expected_type",
287302
[

0 commit comments

Comments
 (0)