{"record":{"id":"6214da9ff772b691","repo":"xai-org/x-algorithm","slug":"block-sparse-tensors-context-m-block-dimension-n","errorCode":null,"errorMessage":"Block sparse tensors{context} m-block dimension {num_m_blocks} does not match sparse_block_size_q={sparse_block_size_q}. Set BlockSparseTensorsTorch.block_size to match the BlockMask BLOCK_SIZE.","messagePattern":"Block sparse tensors(.+?) m-block dimension (.+?) does not match sparse_block_size_q=(.+?)\\. Set BlockSparseTensorsTorch\\.block_size to match the BlockMask BLOCK_SIZE\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"phoenix/xrex/cutedsl/ranker_fa4/block_sparsity.py","lineNumber":365,"sourceCode":"        (\"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(f\"Block sparse tensors{context} {dim_name} dim must be {tgt} or 1.\")\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    ):\n        if cur != tgt and cur != 1:\n            raise ValueError(f\"Block sparse tensors{context} {dim_name} dim must be {tgt} or 1.\")\n    if mask_block_cnt.shape[2] != mask_block_idx.shape[2]:\n        raise ValueError(f\"Block sparse tensors{context} must share the same m-block dimension.\")\n    if mask_block_idx.shape[3] > expected_n_blocks:\n        raise ValueError(\n            f\"Block sparse tensors{context} n-block dimension must be <= {expected_n_blocks}.\"\n        )\n    if expected_m_blocks != num_m_blocks:\n        raise ValueError(\n            f\"Block sparse tensors{context} m-block dimension {num_m_blocks} does not match \"\n            f\"sparse_block_size_q={sparse_block_size_q}. \"\n            f\"Set BlockSparseTensorsTorch.block_size to match the BlockMask BLOCK_SIZE.\"\n        )\n    return expected_count_shape, expected_index_shape, q_subtile_factor\n\n\ndef get_block_sparse_expected_shapes_bwd(\n    batch_size: int,\n    num_head: int,\n    seqlen_q: int,\n    seqlen_k: int,\n    m_block_size: int,\n    n_block_size: int,\n    subtile_factor: int,\n) -> Tuple[Tuple[int, int, int], Tuple[int, int, int, int]]:\n    sparse_block_size_q = subtile_factor * m_block_size\n    expected_m_blocks = ceildiv(seqlen_q, sparse_block_size_q)","sourceCodeStart":347,"sourceCodeEnd":383,"githubUrl":"https://github.com/xai-org/x-algorithm/blob/24c60942c5c5fdad3a6addffb4c6e6d2f228f04f/phoenix/xrex/cutedsl/ranker_fa4/block_sparsity.py#L347-L383","documentation":"The number of M blocks implied by the mask metadata (num_m_blocks, derived from expected_count_shape / seqlen_q) does not equal expected_m_blocks computed from sparse_block_size_q. The BlockSparseTensorsTorch.block_size (BlockMask BLOCK_SIZE) must match the query-block size the kernel uses.","triggerScenarios":"Setting BlockSparseTensorsTorch.block_size[0] (or the BlockMask BLOCK_SIZE) to a value inconsistent with seqlen_q / the kernel's m-block layout; e.g. block_size=(128, 128) when the kernel derives 64-row m-blocks from seqlen_q.","commonSituations":"Porting a FlexAttention BlockMask created with one BLOCK_SIZE into this ranker FA4 path that assumes a specific sparse_block_size_q; mixing forward block sizes into a config without recomputing m-block count.","solutions":["Set BlockSparseTensorsTorch.block_size (and the BlockMask BLOCK_SIZE) so that seqlen_q / block_size[0] equals the kernel's expected m-block count","Regenerate the mask with the kernel's sparse_block_size_q (see normalize_block_sparse_config docs)","Print sparse_block_size_q and num_m_blocks from the error context and align the mask generator to them"],"exampleFix":"# before\ntensors = BlockSparseTensorsTorch(..., block_size=(128, 128))  # M blocks = seqlen/128\n\n# after\ntensors = BlockSparseTensorsTorch(..., block_size=(sparse_block_size_q, tile_n))  # matches kernel\n# i.e. rebuild BlockMask with BLOCK_SIZE matching the ranker FA4 config","handlingStrategy":"validation","validationCode":"assert tensors.block_size is None or tensors.block_size[0] * num_m_blocks == seqlen_q, \\\n    (tensors.block_size, num_m_blocks, seqlen_q)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep BlockMask BLOCK_SIZE in one config constant shared with the kernel","Re-run mask generation after changing seqlen or block size"],"tags":["block-sparsity","block-size","configuration"],"backgroundTag":"configuration-mismatch","analyzedSha":"24c60942c5c5fdad3a6addffb4c6e6d2f228f04f","analyzedAt":"2026-08-28T11:40:14.686Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}