Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions cuda_core/cuda/core/_module.pyx
Original file line numberDiff line numberDiff line change
Expand Up@@ -802,8 +802,16 @@ cdef class ObjectCode:
try:
name = self._sym_map[name]
except KeyError:
if isinstance(name, str):
name = name.encode()
pass
# Encode after the lookup, not only on the miss path. symbol_mapping is
# annotated and documented `dict[str, str]`, but a str mapped value used
# to reach `<const char*>` unencoded and raise
# "TypeError: expected bytes, str found". Program.compile stores the
# lowered names as bytes (nvrtcGetLoweredName), so only the documented
# hand-built form was affected -- i.e. the mapping worked only when it
# did nothing.
if isinstance(name, str):
name = name.encode()

cdef KernelHandle h_kernel = create_kernel_handle(self._h_library, <const char*>name)
if not h_kernel:
Expand Down
7 changes: 7 additions & 0 deletions cuda_core/docs/source/release/1.2.0-notes.rst
Original file line numberDiff line numberDiff line change
Expand Up@@ -73,6 +73,13 @@ Fixes and enhancements
Windows, both ``ctypes.CFUNCTYPE`` and ``ctypes.WINFUNCTYPE`` are accepted.
(`#2439 <https://github.com/NVIDIA/cuda-python/issues/2439>`__)

- :meth:`ObjectCode.get_kernel` now accepts a ``symbol_mapping`` whose values
are ``str``, as :meth:`ObjectCode.from_cubin` and its siblings document
(``dict[str, str]``). The mapped name was only encoded on the *miss* path, so
a hand-built mapping raised ``TypeError: expected bytes, str found`` for
exactly the names it was supposed to translate. Mappings produced by
:meth:`Program.compile` are unaffected -- their values are already ``bytes``.

Deprecation Notices
-------------------

Expand Down
21 changes: 21 additions & 0 deletions cuda_core/tests/test_module.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -369,6 +369,27 @@ def test_object_code_load_cubin(get_saxpy_kernel_cubin):
mod.get_kernel("saxpy<double>") # force loading


@pytest.mark.agent_authored(model="claude-opus-5")
def test_object_code_symbol_mapping_accepts_str_values(get_saxpy_kernel_cubin):
"""``symbol_mapping`` is annotated and documented ``dict[str, str]``.

``Program.compile`` stores the lowered names as ``bytes`` (they come from
``nvrtcGetLoweredName``), so every existing test round-trips
``mod.symbol_mapping`` unchanged and the documented ``str`` form is never
exercised. On a mapping *hit* the value went straight to ``<const char*>``
without being encoded, so a hand-built ``dict[str, str]`` raised
``TypeError: expected bytes, str found`` -- the mapping worked only for
names it did not map.
"""
_, mod = get_saxpy_kernel_cubin
cubin = mod.code
str_sym_map = {k: v.decode() if isinstance(v, bytes) else v for k, v in mod.symbol_mapping.items()}
assert all(isinstance(v, str) for v in str_sym_map.values())

obj = ObjectCode.from_cubin(cubin, symbol_mapping=str_sym_map)
obj.get_kernel("saxpy<double>") # force loading through the mapped name


def test_object_code_load_cubin_from_file(get_saxpy_kernel_cubin, tmp_path, convert_path):
_, mod = get_saxpy_kernel_cubin
cubin = mod.code
Expand Down
Loading