Skip to content

[CuTeDSL] Fix export_to_c shape slot width for 64-bit dynamic dims - #3448

Open
wilyan09007 wants to merge 1 commit into
NVIDIA:mainfrom
wilyan09007:fix/issue-3447
Open

[CuTeDSL] Fix export_to_c shape slot width for 64-bit dynamic dims#3448
wilyan09007 wants to merge 1 commit into
NVIDIA:mainfrom
wilyan09007:fix/issue-3447

Conversation

@wilyan09007

Copy link
Copy Markdown

Summary

_generate_arguments derives a tensor descriptor's stride type from the tensor but passes shape_type="int32_t" unconditionally, so cute.sym_int64() dimensions get int32_t shape slots while the compiled function reads them as i64. A C caller filling in that struct hands over a descriptor half the expected size.

The widths are already known one layer down: _tensor_binding keeps a SymInt dimension at its declared width and gives every other dynamic dimension 32 bits. This derives the shape type the same way at both call sites. One array cannot hold dimensions of two widths, so a tensor mixing them is refused, and the list/tuple descriptor check now compares width alongside the masks it already had.

Verification

Added test/python/CuTeDSL/test_export_c_header_shape_type.py, 8 tests. Four fail on main: the sym_int64 slot width, the mixed-width rejection, and both tensor-list cases. The sym_int32, static-shape, and DLPack-dynamic cases pass before and after.

Fixes #3447

The C header generator derives a tensor descriptor's stride type from
the tensor but passes shape_type="int32_t" unconditionally, so a tensor
built with cute.sym_int64() dimensions gets int32_t shape slots while
the compiled function reads them as i64. A C caller that fills in the
generated struct passes a descriptor half the expected size, and every
field from the second shape slot on is misread.

The widths are already known: _tensor_binding keeps a SymInt dimension
at its declared width and gives every other dynamic dimension 32 bits.
Derive the shape type the same way at both call sites. One array cannot
hold dimensions of two widths, so a tensor mixing them is refused, and
the list/tuple descriptor check now compares width alongside the masks.

Fixes NVIDIA#3447

Signed-off-by: William <wilyan090@gmail.com>
@anakinxc

Copy link
Copy Markdown
Contributor

LGTM

@Observer007 Observer007 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@Observer007

Copy link
Copy Markdown
Contributor

Just curious, in what real cases do we need i64 shape representation?

@wilyan09007

Copy link
Copy Markdown
Author

A genuinely 64-bit extent shows up on a flat 1-D view over a whole buffer: red.py and reduction/block_smem_reduce.py both declare (cute.sym_int64(),), and 2^31 elements is 2 GB of fp8. For GEMM M/N/K it is rare.

The corruption doesn't need a large value though. Shape and stride slots share one descriptor struct, so int32 shapes against an i64 ABI both narrow the shape read and shift the strides. M=128 breaks the same way a 3e9 dim would.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] cuteDSL export_to_c outputs i32 dynamic shapes in headers for i64 inputs

3 participants