"""Diagnostic: Check tBgK layout strides to see if the GMEM tile dim is degenerate.""" import torch, cutlass, cutlass.cute as cute, cutlass.utils as utils from cutlass.cute.nvgpu import cpasync, tcgen05 from cutlass import Float32, BFloat16, Int32 from cutlass.utils import LayoutEnum import cutlass.torch as ct import math HEAD_DIM = 64 n = 256 q = torch.randn(128, HEAD_DIM, 1, dtype=torch.bfloat16, device='cuda') k = torch.randn(n, HEAD_DIM, 1, dtype=torch.bfloat16, device='cuda') v = torch.randn(n, HEAD_DIM, dtype=torch.bfloat16, device='cuda') v_kernel = v.unsqueeze(-1) mQ = ct.from_dlpack(q).mark_layout_dynamic(leading_dim=ct.get_leading_dim(q)) mK = ct.from_dlpack(k).mark_layout_dynamic(leading_dim=ct.get_leading_dim(k)) mV = ct.from_dlpack(v_kernel).mark_layout_dynamic(leading_dim=ct.get_leading_dim(v_kernel)) qk_mma = utils.sm100.make_trivial_tiled_mma(BFloat16, BFloat16, cute.nvgpu.OperandMajorMode.K, cute.nvgpu.OperandMajorMode.K, Float32, tcgen05.CtaGroup.ONE, (128,128), tcgen05.OperandSource.SMEM) pv_mma = utils.sm100.make_trivial_tiled_mma(BFloat16, BFloat16, cute.nvgpu.OperandMajorMode.K, cute.nvgpu.OperandMajorMode.MN, Float32, tcgen05.CtaGroup.ONE, (128,HEAD_DIM), tcgen05.OperandSource.TMEM) qk_ik = cute.size(qk_mma.shape_mnk, mode=[2]) qk_mma_tiler = (128, 128, qk_ik * 4) pv_ik = cute.size(pv_mma.shape_mnk, mode=[2]) pv_mma_tiler = (128, HEAD_DIM, pv_ik * (128 // pv_ik)) cluster_layout_vmnk = cute.tiled_divide(cute.make_layout((1,1,1)), (qk_mma.thr_id.shape,)) kv_stage = 2; q_stage = 1 k_smem_s = utils.sm100.make_smem_layout_b(qk_mma, qk_mma_tiler, BFloat16, kv_stage) v_smem_s = utils.sm100.make_smem_layout_b(pv_mma, pv_mma_tiler, BFloat16, kv_stage) k_s = cute.slice_(k_smem_s,(None,None,None,0)) v_s = cute.slice_(v_smem_s,(None,None,None,0)) tma_k, mK_tma = cute.nvgpu.make_tiled_tma_atom_B( utils.sm100.cluster_shape_to_tma_atom_B(cluster_layout_vmnk.shape, qk_mma.thr_id), mK, k_s, qk_mma_tiler, qk_mma, cluster_layout_vmnk.shape ) tma_v, mV_tma = cute.nvgpu.make_tiled_tma_atom_B( utils.sm100.cluster_shape_to_tma_atom_B(cluster_layout_vmnk.shape, pv_mma.thr_id), mV, v_s, pv_mma_tiler, pv_mma, cluster_layout_vmnk.shape ) gK = cute.local_tile(mK_tma, cute.slice_(qk_mma_tiler,(0,None,None)),(None,None,None)) gV = cute.local_tile(mV_tma, cute.slice_(pv_mma_tiler,(0,None,None)),(None,None,None)) print(f'gK shape: {cute.shape(gK)}') print(f'gK layout: {gK.layout}') print(f'gK stride: {gK.layout.stride}') print(f'gK size per mode: {[cute.size(gK, mode=[i]) for i in range(len(cute.shape(gK)))]}') print() print(f'gV shape: {cute.shape(gV)}') print(f'gV layout: {gV.layout}') print(f'gV stride: {gV.layout.stride}') print() qk_thr = qk_mma.get_slice(0) pv_thr = pv_mma.get_slice(0) tCgK = qk_thr.partition_B(gK) tCgV = pv_thr.partition_B(gV) print(f'tCgK shape: {cute.shape(tCgK)}') print(f'tCgK layout: {tCgK.layout}') print(f'tCgK stride: {tCgK.layout.stride}') print() print(f'tCgV shape: {cute.shape(tCgV)}') print(f'tCgV layout: {tCgV.layout}') print(f'tCgV stride: {tCgV.layout.stride}') print() sK = cute.make_tensor(BFloat16, k_s) sV = cute.make_tensor(BFloat16, v_s) b_lay = cute.make_layout(cute.slice_(cluster_layout_vmnk,(0,None,0,0)).shape) tBsK, tBgK = cpasync.tma_partition(tma_k, 0, b_lay, cute.group_modes(sK,0,3), cute.group_modes(tCgK,0,3)) tVsV, tVgV = cpasync.tma_partition(tma_v, 0, b_lay, cute.group_modes(sV,0,3), cute.group_modes(tCgV,0,3)) print(f'=== tBgK (K TMA partition) ===') print(f'shape: {cute.shape(tBgK)}') print(f'layout: {tBgK.layout}') print(f'stride: {tBgK.layout.stride}') print(f'size per mode: {[cute.size(tBgK, mode=[i]) for i in range(len(cute.shape(tBgK)))]}') print() print(f'=== tVgV (V TMA partition) ===') print(f'shape: {cute.shape(tVgV)}') print(f'layout: {tVgV.layout}') print(f'stride: {tVgV.layout.stride}') print(f'size per mode: {[cute.size(tVgV, mode=[i]) for i in range(len(cute.shape(tVgV)))]}') print() # Now check the slices print(f'=== tBgK after (None,None,0,0) ===') tBgK_nn = tBgK[(None,None,0,0)] print(f'shape: {cute.shape(tBgK_nn)}') print(f'layout: {tBgK_nn.layout}') print(f'stride: {tBgK_nn.layout.stride}') print() print(f'=== tBgK after (None,0,None,0) ===') tBgK_n0 = tBgK[(None,0,None,0)] print(f'shape: {cute.shape(tBgK_n0)}') print(f'layout: {tBgK_n0.layout}') print(f'stride: {tBgK_n0.layout.stride}') print() print(f'=== tVgV after (None,0,None,0) ===') tVgV_n0 = tVgV[(None,0,None,0)] print(f'shape: {cute.shape(tVgV_n0)}') print(f'layout: {tVgV_n0.layout}') print(f'stride: {tVgV_n0.layout.stride}') print(f'=== tVgV after (None,None,0,0) ===') tVgV_nn = tVgV[(None,None,0,0)] print(f'shape: {cute.shape(tVgV_nn)}') print(f'layout: {tVgV_nn.layout}') print(f'stride: {tVgV_nn.layout.stride}')