hp-l33's picture
Add Sol-Attn Kernel Builder source
8e9f35a verified
Raw
History Blame Contribute Delete
4.09 kB
"""CuTe copy helpers used by the Hopper mainloop."""
from typing import Callable
import cutlass
import cutlass.cute as cute
from cutlass import const_expr
from cutlass import pipeline
from cutlass.cute.nvgpu import cpasync
from cutlass.cutlass_dsl import dsl_user_op
_RAGGED_BASE = 2**30
_RAGGED_LIMIT = 2**31 - 1
_RAGGED_WRAP_STRIDE = 2**64 // _RAGGED_BASE
@dsl_user_op
def create_ragged_tensor_for_tma(
tensor: cute.Tensor,
ragged_dim: int = 0,
ptr_shift: bool = False,
*,
loc=None,
ip=None,
) -> cute.Tensor:
rank = cute.rank(tensor)
if ragged_dim < 0:
ragged_dim += rank
if ptr_shift:
shape = (
tensor.shape[:ragged_dim]
+ (_RAGGED_BASE,)
+ tensor.shape[ragged_dim + 1 :]
+ (_RAGGED_LIMIT,)
)
stride = tensor.stride + (tensor.stride[ragged_dim],)
offset = (
(None,) * ragged_dim
+ (-_RAGGED_BASE,)
+ (None,) * (rank - ragged_dim - 1)
)
pointer = cute.domain_offset(offset, tensor).iterator
return cute.make_tensor(
pointer,
cute.make_layout(shape, stride=stride),
)
ragged_stride = tensor.stride[ragged_dim]
shape = (
tensor.shape[:ragged_dim]
+ (_RAGGED_BASE,)
+ tensor.shape[ragged_dim + 1 :]
+ (_RAGGED_LIMIT, _RAGGED_LIMIT)
)
stride = (
tensor.stride[:ragged_dim]
+ (ragged_stride,)
+ tensor.stride[ragged_dim + 1 :]
+ (_RAGGED_WRAP_STRIDE - ragged_stride, ragged_stride)
)
return cute.make_tensor(
tensor.iterator,
cute.make_layout(shape, stride=stride),
)
def tma_get_copy_fn(
atom: cute.CopyAtom,
cta_coord: cute.Coord,
cta_layout: cute.Layout,
src_tensor: cute.Tensor,
dst_tensor: cute.Tensor,
filter_zeros: bool = False,
single_stage: bool = False,
*,
loc=None,
ip=None,
**kwargs,
) -> Callable:
source_is_smem = const_expr(
isinstance(src_tensor.iterator, cute.Pointer)
and src_tensor.memspace == cute.AddressSpace.smem
)
smem, gmem = (
(src_tensor, dst_tensor)
if source_is_smem
else (dst_tensor, src_tensor)
)
smem_rank = const_expr(cute.rank(smem) - (0 if single_stage else 1))
gmem_rank = const_expr(cute.rank(gmem) - (0 if single_stage else 1))
smem, gmem = cpasync.tma_partition(
atom,
cta_coord,
cta_layout,
cute.group_modes(smem, 0, smem_rank),
cute.group_modes(gmem, 0, gmem_rank),
loc=loc,
ip=ip,
)
if const_expr(filter_zeros):
smem = cute.filter_zeros(smem)
gmem = cute.filter_zeros(gmem)
source, destination = (
(smem, gmem) if source_is_smem else (gmem, smem)
)
@dsl_user_op
def copy_tma(
src_idx,
dst_idx,
*,
loc=None,
ip=None,
**call_kwargs,
):
cute.copy(
atom,
source[None, src_idx],
destination[None, dst_idx],
**call_kwargs,
**kwargs,
loc=loc,
ip=ip,
)
@dsl_user_op
def copy_single_stage(*, loc=None, ip=None, **call_kwargs):
cute.copy(
atom,
source,
destination,
**call_kwargs,
**kwargs,
loc=loc,
ip=ip,
)
return (
copy_tma if const_expr(not single_stage) else copy_single_stage,
smem,
gmem,
)
def tma_producer_copy_fn(
copy: Callable,
copy_pipeline: pipeline.PipelineAsync,
):
def copy_fn(
src_idx,
producer_state: pipeline.PipelineState,
**kwargs,
):
copy(
src_idx=src_idx,
dst_idx=producer_state.index,
tma_bar_ptr=copy_pipeline.producer_get_barrier(producer_state),
**kwargs,
)
return copy_fn
__all__ = [
"create_ragged_tensor_for_tma",
"tma_get_copy_fn",
"tma_producer_copy_fn",
]