{"record":{"id":"8495aecf7986b589","repo":"xai-org/x-algorithm","slug":"block-sparse-tensors-context-have-block-size-spa","errorCode":null,"errorMessage":"Block sparse tensors{context} have block size {sparse_block_size_q}, which must be a multiple of {base_m_block}.","messagePattern":"Block sparse tensors(.+?) have block size (.+?), which must be a multiple of (.+?)\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"phoenix/xrex/cutedsl/ranker_fa4/block_sparsity.py","lineNumber":327,"sourceCode":"        sparse_block_size_kv = base_n_block\n    if sparse_block_size_kv != base_n_block:\n        raise ValueError(f\"Block sparse tensors{context} require BLOCK_SIZE_KV={base_n_block}.\")\n    if tensors.mask_block_idx is None:\n        raise ValueError(\"mask_block_cnt and mask_block_idx must be provided for block sparsity.\")\n    num_m_blocks = tensors.mask_block_idx.shape[2]\n\n    if sparse_block_size_q is None:\n        sparse_block_size_q = get_sparse_q_block_size(tensors, seqlen_q)\n        if sparse_block_size_q is None and base_m_block != 1:\n            raise ValueError(\n                f\"Block sparse tensors{context} require explicit sparse_block_size[0] \"\n                f\"to disambiguate block size for seqlen_q={seqlen_q} and num_m_blocks={num_m_blocks}.\"\n            )\n        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(\"mask_block_cnt and mask_block_idx must be provided for block sparsity.\")\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        )","sourceCodeStart":309,"sourceCodeEnd":345,"githubUrl":"https://github.com/xai-org/x-algorithm/blob/24c60942c5c5fdad3a6addffb4c6e6d2f228f04f/phoenix/xrex/cutedsl/ranker_fa4/block_sparsity.py#L309-L345","documentation":"After resolving sparse_block_size_q (explicit or inferred), it must be divisible by base_m_block (q_stage * m_block_size), because each sparse Q block must contain an integer number of kernel M-tiles. Otherwise the block boundaries cannot align with kernel tiles.","triggerScenarios":"Passing a Q block size like 96 when base_m_block is 64 (96 % 64 != 0), or an inferred ceildiv(seqlen_q, num_m_blocks) that is not a multiple of the kernel's M-tile size.","commonSituations":"Choosing an arbitrary sparse block size for compression without considering the kernel tile size; small seqlen_q where ceildiv yields a non-aligned value; changing q_stage/m_block_size in kernel config without regenerating sparse metadata.","solutions":["Pick sparse_block_size_q as a multiple of base_m_block (e.g. 1x or 2x of q_stage * m_block_size)","Adjust q_stage/m_block_size so their product divides your sparse Q block size","Regenerate mask tensors with an aligned block size"],"exampleFix":"# before\nnormalize_block_sparse_config(..., sparse_block_size=(96, None))  # 96 % 64 != 0\n\n# after\nnormalize_block_sparse_config(..., sparse_block_size=(128, None))  # 128 = 2 * 64","handlingStrategy":"validation","validationCode":"base_m = q_stage * m_block_size\nassert sparse_block_size_q % base_m == 0, f\"{sparse_block_size_q} not divisible by {base_m}\"","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Choose Q block sizes that are powers-of-two multiples of the kernel M tile","Keep kernel tile config and sparse generation config in one source of truth"],"tags":["block-sparsity","alignment","config-validation"],"backgroundTag":"block-sparsity-config-mismatch","analyzedSha":"24c60942c5c5fdad3a6addffb4c6e6d2f228f04f","analyzedAt":"2026-08-28T11:40:14.686Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}