"""Diagnostic: Q1, Q2 for Stage B TMEM debugging. Uses cute.compile with a dummy kernel that prints layout info at JIT time.""" import torch, cutlass, cutlass.cute as cute, cutlass.utils as utils from cutlass.cute.nvgpu import tcgen05 from cutlass import Float32, BFloat16 from cutlass.utils import LayoutEnum from cutlass.utils.tmem_allocator import find_tmem_tensor_col_offset import cuda.bindings.driver as cuda @cute.jit def diag_tmem(stream: cuda.CUstream): a_dtype = BFloat16; b_dtype = BFloat16 a_major = cute.nvgpu.OperandMajorMode.K b_major = cute.nvgpu.OperandMajorMode.K qk_mma = utils.sm100.make_trivial_tiled_mma( a_dtype, b_dtype, a_major, b_major, Float32, tcgen05.CtaGroup.ONE, (128, 128), tcgen05.OperandSource.SMEM) pv_mma = utils.sm100.make_trivial_tiled_mma( a_dtype, b_dtype, cute.nvgpu.OperandMajorMode.K, b_major, Float32, tcgen05.CtaGroup.ONE, (128, 128), tcgen05.OperandSource.TMEM) qk_inst_k = cute.size(qk_mma.shape_mnk, mode=[2]) pv_inst_k = cute.size(pv_mma.shape_mnk, mode=[2]) mma_tiler = (128, 128, qk_inst_k * 4) pv_mma_tiler = (128, 128, pv_inst_k * 4) qk_thr = qk_mma.get_slice(0) pv_thr = pv_mma.get_slice(0) # Q1: QK accumulator C fragment qk_acc_shape = qk_thr.partition_shape_C(mma_tiler[:2]) tStS = qk_thr.make_fragment_C(qk_acc_shape) print(f"=== Q1: QK accumulator C fragment ===") print(f" tStS.layout = {tStS.layout}") print(f" cute.size(tStS.layout) = {cute.size(tStS.layout)}") print(f" cute.cosize(tStS.layout) = {cute.cosize(tStS.layout)}") print(f" cute.size(mode=[0]) = {cute.size(tStS.layout, mode=[0])}") print(f" cute.size(mode=[1]) = {cute.size(tStS.layout, mode=[1])}") s_tmem_cols = find_tmem_tensor_col_offset(tStS) print(f" find_tmem_tensor_col_offset(tStS) = {s_tmem_cols}") # PV accumulator O fragment pv_acc_shape = pv_thr.partition_shape_C(mma_tiler[:2]) tOtO = pv_thr.make_fragment_C(pv_acc_shape) print(f"=== PV accumulator O fragment ===") print(f" tOtO.layout = {tOtO.layout}") print(f" cute.size(tOtO.layout) = {cute.size(tOtO.layout)}") print(f" cute.cosize(tOtO.layout) = {cute.cosize(tOtO.layout)}") print(f" cute.size(mode=[0]) = {cute.size(tOtO.layout, mode=[0])}") print(f" cute.size(mode=[1]) = {cute.size(tOtO.layout, mode=[1])}") o_tmem_cols = find_tmem_tensor_col_offset(tOtO) print(f" find_tmem_tensor_col_offset(tOtO) = {o_tmem_cols}") # Q2: PV A-fragment (P operand from TMEM) p_tmem_s = utils.sm100.make_smem_layout_a(pv_mma, pv_mma_tiler, BFloat16, 1) tP = cute.make_tensor(tStS.iterator, p_tmem_s.outer) tOrP_base = pv_thr.make_fragment_A(tP) tOrP_sliced = tOrP_base[(None, None, None, 0)] print(f"=== Q2: PV A-fragment (P operand) ===") print(f" tP.layout = {tP.layout}") print(f" cute.size(tP.layout) = {cute.size(tP.layout)}") print(f" cute.cosize(tP.layout) = {cute.cosize(tP.layout)}") print(f" tOrP_sliced.layout = {tOrP_sliced.layout}") print(f" cute.size(tOrP_sliced.layout) = {cute.size(tOrP_sliced.layout)}") print(f" cute.cosize(tOrP_sliced.layout) = {cute.cosize(tOrP_sliced.layout)}") p_tmem_cols = find_tmem_tensor_col_offset(tOrP_sliced) print(f" find_tmem_tensor_col_offset(tOrP_sliced) = {p_tmem_cols}") # Decompose 32800 print(f" 32800 in hex = 0x{32800:04x}") print(f" 32800 - 0x8000 = {32800 - 0x8000}") print(f" 32800 & 0x0000FFFF = {32800 & 0x0000FFFF}") print(f" p_tmem_cols in hex = 0x{p_tmem_cols:04x}") if isinstance(p_tmem_cols, int): print(f" p_tmem_cols & 0x0000FFFF = {p_tmem_cols & 0x0000FFFF}") print(f" p_tmem_cols >> 16 = {p_tmem_cols >> 16}") # Staged fragments tCtS_fake = qk_mma.make_fragment_C(cute.append(qk_acc_shape, 1)) tCtO_fake = pv_mma.make_fragment_C(cute.append(pv_acc_shape, 1)) print(f"=== Staged fragments ===") print(f" find_tmem_tensor_col_offset(tCtS_fake) = {find_tmem_tensor_col_offset(tCtS_fake)}") print(f" find_tmem_tensor_col_offset(tCtO_fake) = {find_tmem_tensor_col_offset(tCtO_fake)}") print(f" get_num_tmem_alloc_cols([tCtS_fake, tCtO_fake]) = {utils.get_num_tmem_alloc_cols([tCtS_fake, tCtO_fake], arch='sm_100')}") stream = cuda.CUstream(torch.cuda.current_stream().cuda_stream) print("Compiling diagnostics...", flush=True) compiled = cute.compile(diag_tmem, stream) print("Done. Results above.", flush=True)