Skip to content

[BUG]: CUtensorMap owned storage does not honor required alignment #3181

Open

Description

@isVoid

Type of Bug

Something else: backing-storage alignment does not meet the C type's declared requirement.

Component

cuda.bindings

Describe the bug

I discovered this alignment issue while reviewing #3095, which adds the _v2.driver API. Checking the existing cuda.bindings.driver.CUtensorMap implementation showed that the same allocation pattern is already present in released versions.

The wrapper embeds the C descriptor inside a Python object and does not explicitly enforce its alignment. The required alignment depends on the CUDA header version: the wrapper documentation specifies 128 bytes in v13.4.4 and 64 bytes in v12.9.9.

Released implementations with this allocation pattern

These are concrete released examples confirmed by source inspection, not a claim about the first affected release. PR #3095 uses equivalent inline storage for _v2.driver.TensorMap. This issue tracks the shared allocation limitation separately from that PR.

In the legacy wrapper, default construction points _pvt_ptr at &self._pvt_val:

The C compiler can align a member's offset within the containing object, but CPython's object allocator does not guarantee a 128-byte-aligned base address. Consequently, the descriptor's actual address need not meet the C type's alignment requirement.

How to Reproduce

Inspect the backing addresses of existing legacy API objects, for example with cuda.bindings v13.4.4; no GPU or CUDA API call is needed:

from cuda.bindings import driver

# Keep the objects alive so the allocator cannot simply reuse one address.
maps = [driver.CUtensorMap() for _ in range(200)]
addresses = [int(m.getPtr()) for m in maps]

print("address residues modulo 128:", sorted({p % 128 for p in addresses}))
print("address residues modulo 64:", sorted({p % 64 for p in addresses}))
assert all(p % 128 == 0 for p in addresses)

For v12.9.9, check modulo 64 instead, matching that version's documented requirement.

The assertion can fail because alignment stronger than the Python allocator's guarantee occurs only incidentally. Exact residues depend on the Python build and allocator; a run that happens to return aligned addresses does not establish a guarantee.

Validation: source inspection confirms the inline allocation in both versions. A separately compiled Cython reproduction using the actual CUDA header and the new wrapper's class layout produced descriptor addresses with residues 0, 16, 32, and 48 modulo 64. The legacy-API script above is provided for validation against an installed build; it was not run as part of that reproduction.

Expected behavior

Owned tensor-map storage should honor alignof(CUtensorMap) (128 bytes in the inspected header), including storage used internally by encoding wrappers. Regression tests should check the pointer alignment directly, not only whether encoding succeeds.

Observed impact and scope

No CUDA encoding failure or protected-memory fault has been demonstrated here. Existing tensor-map tests do not establish a storage-alignment guarantee, and successful encoding alone does not prove that guarantee. This report concerns meeting the documented alignment contract; it should not claim that tensor-map APIs are generally unusable or that #3095 newly breaks them.

Possible fix

Provide explicitly aligned owned storage for tensor-map wrappers, with matching deallocation and support for copy-producing construction paths. The generator's external-storage mode currently uses ordinary allocation, so selecting it alone does not guarantee extended alignment.

A broader generator enhancement could support alignment-aware allocation for AUTO_LOWPP_CLASS; a dedicated tensor-map allocation path is another option. Borrowing an externally aligned pointer is already possible, but does not fix wrappers that construct their output object internally, such as the new tensor_map_encode_tiled.

Activity

  1. changed the title [-][BUG]: Struct-valued setters in _v2.driver bypass read-only destination protection[/-] [+][BUG]: Existing CUtensorMap backing storage does not guarantee required alignment[/+] on Oct 21, 2026
  2. changed the title [-][BUG]: Existing CUtensorMap backing storage does not guarantee required alignment[/-] [+][BUG]: CUtensorMap owned storage does not honor required alignment[/+] on Oct 21, 2026
  3. mdboom commented on Oct 21, 2026

    @mdboom
    Contributor

    I think the fix here is:

    • In the generator, add a configuration option for types called alignment
    • Since we can't control the alignment of the wrapping PyObject, when present, this will force use of generating classes in "external" mode
    • The constructor for these classes will use alloc_align/memset rather than calloc to align to the correct amount
    • from_ptr will be updated similarly in the copy case, and in the non-copy case will raise an exception if the passed-in pointer is not aligned correctly.
  4. self-assigned this
    on Oct 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions