mirror of
https://github.com/tile-ai/tilelang.git
synced 2026-10-27 07:32:58 +08:00
[BugFix] Handle strided global buffers correctly in 1D TMA copies (#2746)
* Honor explicit strides in 1D TMA offsets * Reject non-contiguous strided regions for 1D TMA --------- Co-authored-by: Zheng Yu <17133261+cla7aye15I4nd@users.noreply.github.com> Co-authored-by: SiriusNEO <chaofan@deepseek.com>
This commit is contained in:
co-authored by
Zheng Yu
SiriusNEO
parent
1dc86d7114
commit
5ef1500ed2
@@ -177,6 +177,82 @@ def test_tma_copy_default_block_leader_scope_codegen():
|
||||
assert "tl_shuffle_elect<256>()" in source, "Expected block-wide elect<256>"
|
||||
|
||||
|
||||
@tilelang.testing.requires_cuda
|
||||
@tilelang.testing.requires_cuda_compute_version_ge(9, 0)
|
||||
def test_tma_copy_uses_explicit_global_stride_for_row_offset():
|
||||
rows = 2
|
||||
cols = 32
|
||||
row_stride = 40
|
||||
|
||||
@T.prim_func
|
||||
def main(
|
||||
A: T.StridedTensor((rows, cols), (row_stride, 1), T.float32),
|
||||
B: T.Tensor((cols,), T.float32),
|
||||
):
|
||||
with T.Kernel(1, threads=32):
|
||||
a_shared = T.alloc_shared((cols,), T.float32)
|
||||
T.copy(A[1, 0:cols], a_shared, prefer_instruction="tma")
|
||||
T.copy(a_shared, B)
|
||||
|
||||
import torch
|
||||
|
||||
kernel = tilelang.compile(main, out_idx=[1])
|
||||
assert "CUtensorMap" not in kernel.get_kernel_source()
|
||||
padded = torch.arange(rows * row_stride, dtype=torch.float32, device="cuda").reshape(rows, row_stride)
|
||||
source = padded[:, :cols]
|
||||
assert source.stride() == (row_stride, 1)
|
||||
output = kernel(source)
|
||||
torch.testing.assert_close(output, source[1])
|
||||
|
||||
|
||||
@tilelang.testing.requires_cuda
|
||||
@tilelang.testing.requires_cuda_compute_version_ge(9, 0)
|
||||
def test_tma_copy_uses_descriptor_for_padded_multirow_region():
|
||||
rows = 2
|
||||
cols = 32
|
||||
row_stride = 40
|
||||
|
||||
@T.prim_func
|
||||
def load(
|
||||
A: T.StridedTensor((rows, cols), (row_stride, 1), T.float32),
|
||||
B: T.Tensor((rows, cols), T.float32),
|
||||
):
|
||||
with T.Kernel(1, threads=32):
|
||||
a_shared = T.alloc_shared((rows, cols), T.float32)
|
||||
T.copy(A, a_shared, prefer_instruction="tma")
|
||||
T.copy(a_shared, B, prefer_instruction="sync")
|
||||
|
||||
@T.prim_func
|
||||
def store(
|
||||
A: T.Tensor((rows, cols), T.float32),
|
||||
B: T.StridedTensor((rows, cols), (row_stride, 1), T.float32),
|
||||
):
|
||||
with T.Kernel(1, threads=32):
|
||||
a_shared = T.alloc_shared((rows, cols), T.float32)
|
||||
T.copy(A, a_shared, prefer_instruction="sync")
|
||||
T.copy(a_shared, B, prefer_instruction="tma")
|
||||
|
||||
import torch
|
||||
|
||||
source = torch.arange(rows * cols, dtype=torch.float32, device="cuda").reshape(rows, cols)
|
||||
|
||||
load_kernel = tilelang.compile(load, out_idx=[1])
|
||||
assert "CUtensorMap" in load_kernel.get_kernel_source()
|
||||
padded_source = torch.full((rows, row_stride), -1.0, dtype=torch.float32, device="cuda")
|
||||
strided_source = padded_source[:, :cols]
|
||||
strided_source.copy_(source)
|
||||
output = load_kernel(strided_source)
|
||||
torch.testing.assert_close(output, source)
|
||||
|
||||
store_kernel = tilelang.compile(store)
|
||||
assert "CUtensorMap" in store_kernel.get_kernel_source()
|
||||
padded_destination = torch.full((rows, row_stride), -1.0, dtype=torch.float32, device="cuda")
|
||||
strided_destination = padded_destination[:, :cols]
|
||||
store_kernel(source, strided_destination)
|
||||
torch.testing.assert_close(strided_destination, source)
|
||||
torch.testing.assert_close(padded_destination[:, cols:], torch.full_like(padded_destination[:, cols:], -1.0))
|
||||
|
||||
|
||||
def matmul_tma_copy_store(
|
||||
M,
|
||||
N,
|
||||
|
||||
Reference in New Issue
Block a user