{"record":{"id":"c853243f5ae1e081","repo":"xai-org/x-algorithm","slug":"block-sparsity-expects-sparse-block-size-1-n-blo","errorCode":null,"errorMessage":"Block sparsity expects sparse_block_size[1]={n_block_size} to match tile_n.","messagePattern":"Block sparsity expects sparse_block_size\\[1\\]=(.+?) to match tile_n\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"phoenix/xrex/cutedsl/ranker_fa4/block_sparsity.py","lineNumber":621,"sourceCode":"    batch_size: int,\n    num_head: int,\n    seqlen_q: int,\n    seqlen_k: int,\n    block_size: tuple[int, int],\n    subtile_factor: int,\n) -> tuple[BlockSparseTensorsTorch, Tuple[Tuple[bool, ...], ...] | None]:\n    m_block_size, n_block_size = block_size\n    if tensors.block_size is None:\n        sparse_block_size_q, sparse_block_size_kv = subtile_factor * m_block_size, n_block_size\n    else:\n        sparse_block_size_q, sparse_block_size_kv = tensors.block_size\n    if sparse_block_size_q != subtile_factor * m_block_size:\n        raise ValueError(\n            f\"Block sparsity expects sparse_block_size_q={subtile_factor * m_block_size} \"\n            f\"for subtile_factor={subtile_factor}.\"\n        )\n    if sparse_block_size_kv != n_block_size:\n        raise ValueError(\n            f\"Block sparsity expects sparse_block_size[1]={n_block_size} to match tile_n.\"\n        )\n    expected_count_shape, expected_index_shape = get_block_sparse_expected_shapes_bwd(\n        batch_size,\n        num_head,\n        seqlen_q,\n        seqlen_k,\n        m_block_size,\n        n_block_size,\n        subtile_factor,\n    )\n    normalized_tensors = normalize_block_sparse_tensors(\n        tensors,\n        expected_count_shape=expected_count_shape,\n        expected_index_shape=expected_index_shape,\n        context=\"_flash_attn_bwd\",\n        hint=lambda: (\n            f\"Backward expects Q-direction block-sparse tensors (q_mask_cnt/q_mask_idx, \"","sourceCodeStart":603,"sourceCodeEnd":639,"githubUrl":"https://github.com/xai-org/x-algorithm/blob/24c60942c5c5fdad3a6addffb4c6e6d2f228f04f/phoenix/xrex/cutedsl/ranker_fa4/block_sparsity.py#L603-L639","documentation":"Backward counterpart of error 353: sparse_block_size_kv (block_size[1]) must match tile_n in normalize_block_sparse_config_bwd. Fires when an explicit KV block size differs from the kernel's N tile.","triggerScenarios":"bwd normalization with tensors.block_size = (q, kv) where kv != tile_n; a shared fwd/bwd tensor config whose kv block size was chosen for a different tile config.","commonSituations":"Reusing BlockMask BLOCK_SIZE across kernel configs; tile_n changed by a kernel version bump while masks stayed fixed.","solutions":["Set block_size[1] to tile_n or use block_size=None","Rebuild masks with the backward kernel's tile_n","Align mask generator and kernel tile config in one place"],"exampleFix":"# before\ntensors_bwd = BlockSparseTensorsTorch(..., block_size=(128, 256))  # tile_n=128\n\n# after\ntensors_bwd = BlockSparseTensorsTorch(..., block_size=(128, 128))\n# or block_size=None","handlingStrategy":"validation","validationCode":"assert tensors.block_size is None or tensors.block_size[1] == tile_n","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Share one tile config between mask generation and fwd/bwd kernels","Use defaults (block_size=None) wherever possible"],"tags":["block-sparsity","backward","block-size","tile-config"],"backgroundTag":"configuration-mismatch","analyzedSha":"24c60942c5c5fdad3a6addffb4c6e6d2f228f04f","analyzedAt":"2026-08-28T11:40:14.686Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}