Skip to content

Commit bce9a02

Browse files
committed
more
1 parent 4da500c commit bce9a02

1 file changed

Lines changed: 16 additions & 13 deletions

File tree

transformer_nuggets/cute/block_copy.py

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ def kernel(
4545
shared_storage: cutlass.Constexpr,
4646
tile_shape: cutlass.Constexpr,
4747
dtype: cutlass.Constexpr,
48+
row_count: cutlass.Constexpr,
4849
):
4950
smem = cutlass.utils.SmemAllocator()
5051
storage = smem.allocate(shared_storage)
@@ -97,17 +98,19 @@ def kernel(
9798
)
9899
for row_step in cutlass.range(self.rows_per_cta, unroll=1):
99100
load_pipeline.consumer_wait(consumer_state)
100-
dst_tile = dst_tiles[(None, (batch_idx, row_base + row_step, 0))]
101101
stage_smem_tile = smem_tile[(consumer_state.index, None, None, None)]
102-
block_copy(
103-
store_atom,
104-
cute.group_modes(stage_smem_tile, 0, 3),
105-
cute.group_modes(dst_tile, 0, 1),
106-
)
107-
cute.arch.cp_async_bulk_commit_group()
108-
cute.arch.cp_async_bulk_wait_group(0)
109-
cute.arch.fence_view_async_shared()
110-
cute.arch.sync_warp()
102+
# Tail CTAs may TMA-load full-OOB rows as zero-filled stages; skip their stores.
103+
if row_base + row_step < row_count:
104+
dst_tile = dst_tiles[(None, (batch_idx, row_base + row_step, 0))]
105+
block_copy(
106+
store_atom,
107+
cute.group_modes(stage_smem_tile, 0, 3),
108+
cute.group_modes(dst_tile, 0, 1),
109+
)
110+
cute.arch.cp_async_bulk_commit_group()
111+
cute.arch.cp_async_bulk_wait_group(0)
112+
cute.arch.fence_view_async_shared()
113+
cute.arch.sync_warp()
111114
load_pipeline.consumer_release(consumer_state)
112115
consumer_state.advance()
113116

@@ -139,6 +142,7 @@ def __call__(self, src: cute.Tensor, dst: cute.Tensor):
139142
shared_storage,
140143
tile_shape,
141144
src.element_type,
145+
src.shape[1],
142146
).launch(
143147
grid=[src.shape[0], cute.ceil_div(src.shape[1], self.rows_per_cta), 1],
144148
block=[threads, 1, 1],
@@ -161,9 +165,8 @@ def interface(self, src: torch.Tensor) -> torch.Tensor:
161165
raise ValueError(f"Expected a 3D tensor, got rank {src.ndim}")
162166
if src.data_ptr() % 16 != 0:
163167
raise ValueError("Input tensor must be 16-byte aligned")
164-
if src.shape[1] % self.rows_per_cta != 0:
165-
raise ValueError("Input row dimension must be divisible by rows_per_cta")
166-
168+
if src.shape[2] * src.element_size() % 16 != 0:
169+
raise ValueError("Input innermost dimension must span a multiple of 16 bytes")
167170
dst = torch.empty_like(src)
168171
if dst.data_ptr() % 16 != 0:
169172
raise ValueError("Output tensor must be 16-byte aligned")

0 commit comments

Comments
 (0)