{"record":{"id":"42188dc1b1f5c49e","repo":"sgl-project/sglang","slug":"block-sparse-tensors-context-must-have-shapes-b","errorCode":null,"errorMessage":"Block sparse tensors{context} must have shapes (B, H, M) and (B, H, M, N).","messagePattern":"Block sparse tensors(.+?) must have shapes \\(B, H, M\\) and \\(B, H, M, N\\)\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/kernels/ops/attention/flash_attn/cute/block_sparsity.py","lineNumber":370,"sourceCode":"        if sparse_block_size_q is None:\n            sparse_block_size_q = ceildiv(seqlen_q, num_m_blocks)\n\n    if sparse_block_size_q % base_m_block != 0:\n        raise ValueError(\n            f\"Block sparse tensors{context} have block size {sparse_block_size_q}, \"\n            f\"which must be a multiple of {base_m_block}.\"\n        )\n\n    expected_m_blocks = ceildiv(seqlen_q, sparse_block_size_q)\n    expected_n_blocks = ceildiv(seqlen_k, sparse_block_size_kv)\n    q_subtile_factor = sparse_block_size_q // base_m_block\n    expected_count_shape = (batch_size, num_head, expected_m_blocks)\n    expected_index_shape = (batch_size, num_head, expected_m_blocks, expected_n_blocks)\n\n    mask_block_cnt = tensors.mask_block_cnt\n    mask_block_idx = tensors.mask_block_idx\n    if mask_block_cnt is None or mask_block_idx is None:\n        raise ValueError(\n            \"mask_block_cnt and mask_block_idx must be provided for block sparsity.\"\n        )\n    if mask_block_cnt.ndim != 3 or mask_block_idx.ndim != 4:\n        raise ValueError(\n            f\"Block sparse tensors{context} must have shapes (B, H, M) and (B, H, M, N).\"\n        )\n    for dim_name, cur, tgt in (\n        (\"batch\", mask_block_cnt.shape[0], expected_count_shape[0]),\n        (\"head\", mask_block_cnt.shape[1], expected_count_shape[1]),\n    ):\n        if cur != tgt and cur != 1:\n            raise ValueError(\n                f\"Block sparse tensors{context} {dim_name} dim must be {tgt} or 1.\"\n            )\n    for dim_name, cur, tgt in (\n        (\"batch\", mask_block_idx.shape[0], expected_index_shape[0]),\n        (\"head\", mask_block_idx.shape[1], expected_index_shape[1]),\n    ):","sourceCodeStart":352,"sourceCodeEnd":388,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/kernels/ops/attention/flash_attn/cute/block_sparsity.py#L352-L388","documentation":"Raised when the block-sparse count tensor is not 3-D or the index tensor is not 4-D. The kernel expects per (batch, head, m-block) counts and per (batch, head, m-block, n-block) indices.","triggerScenarios":"Passing mask_block_cnt with shape (B, M) (missing head dim) or mask_block_idx with shape (B, H, N) (missing m dim) to normalize_block_sparse_config.","commonSituations":"Migrating from a 2-D/3-D layout used by another block-sparse implementation or hand-building tensors without the head dimension.","solutions":["Reshape/expand cnt to (B, H, M) — use .unsqueeze(1).expand(B, H, M) if head-uniform","Reshape idx to (B, H, M, N) with unsqueeze/expand as needed"],"exampleFix":"// before\ncnt = torch.zeros((B, M), dtype=torch.int32, device='cuda')\n// after\ncnt = torch.zeros((B, 1, M), dtype=torch.int32, device='cuda').expand(B, H, M)","handlingStrategy":"type-guard","validationCode":"assert mask_block_cnt.ndim == 3 and mask_block_idx.ndim == 4","typeGuard":"def valid_sparse_ranks(cnt, idx): return cnt.ndim == 3 and idx.ndim == 4","tryCatchPattern":null,"preventionTips":["Use (B,H,M)/(B,H,M,N) layout from the start; expand dims of size 1"],"tags":["block-sparse","shape-mismatch","rank"],"backgroundTag":"tensor-shape-mismatch","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}