{"record":{"id":"dd1e882acf828711","repo":"xai-org/x-algorithm","slug":"backward-block-sizes-block-q-dq-block-kv-dq-blo","errorCode":null,"errorMessage":"Backward block sizes (block_q_dq, block_kv_dq, block_q_dkv, block_kv_dkv) must either all be specified or all be None.","messagePattern":"Backward block sizes \\(block_q_dq, block_kv_dq, block_q_dkv, block_kv_dkv\\) must either all be specified or all be None\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"phoenix/xrex/pallas/ranker_attention_varlen.py","lineNumber":35,"sourceCode":"class TuningConfig:\n    block_q: int\n    block_kv: int\n    num_warps: int\n    num_stages: int\n\n    block_q_dq: int | None = None\n    block_kv_dq: int | None = None\n    block_q_dkv: int | None = None\n    block_kv_dkv: int | None = None\n\n    bwd_num_warps: int | None = None\n    bwd_num_stages: int | None = None\n\n    def __post_init__(self):\n        backward_blocks = [self.block_q_dq, self.block_kv_dq, self.block_q_dkv, self.block_kv_dkv]\n        block_is_set = [blk is not None for blk in backward_blocks]\n        if any(block_is_set) and not all(block_is_set):\n            raise ValueError(\n                \"Backward block sizes (block_q_dq, block_kv_dq, block_q_dkv, \"\n                \"block_kv_dkv) must either all be specified or all be None.\"\n            )\n\n\nHOPPER_CONFIG = TuningConfig(\n    block_q=128,\n    block_kv=128,\n    num_warps=8,\n    num_stages=2,\n    block_q_dq=128,\n    block_kv_dq=16,\n    block_q_dkv=16,\n    block_kv_dkv=128,\n    bwd_num_warps=8,\n    bwd_num_stages=4,\n)\n","sourceCodeStart":17,"sourceCodeEnd":53,"githubUrl":"https://github.com/xai-org/x-algorithm/blob/24c60942c5c5fdad3a6addffb4c6e6d2f228f04f/phoenix/xrex/pallas/ranker_attention_varlen.py#L17-L53","documentation":"TuningConfig for varlen ranker attention validates that the four backward block sizes (block_q_dq, block_kv_dq, block_q_dkv, block_kv_dkv) are all-or-nothing. Partially specifying them is ambiguous (autotuning would mix tuned and unset sizes), so __post_init__ rejects it immediately at config construction.","triggerScenarios":"Constructing TuningConfig (e.g. HOPPER_CONFIG-style presets or a custom config) where some but not all of block_q_dq, block_kv_dq, block_q_dkv, block_kv_dkv are provided.","commonSituations":"Copying a preset config and overriding only one block size; merging configs where overrides drop some fields; partial migration to a new config schema.","solutions":["Provide all four backward block sizes explicitly, or remove all of them so autotuning/defaults apply.","Check dataclass field defaults vs your overrides; a field left as None while siblings are ints triggers this.","Build the config programmatically so all four sizes are set together."],"exampleFix":"# before\ncfg = TuningConfig(block_q_dq=128)\n# after\ncfg = TuningConfig(block_q_dq=128, block_kv_dq=128, block_q_dkv=64, block_kv_dkv=128)\n# or simply\ncfg = TuningConfig()","handlingStrategy":"validation","validationCode":"bwd = [cfg.block_q_dq, cfg.block_kv_dq, cfg.block_q_dkv, cfg.block_kv_dkv]\nassert all(b is not None for b in bwd) or all(b is None for b in bwd)","typeGuard":"def backward_blocks_consistent(cfg) -> bool:\n    blocks = [cfg.block_q_dq, cfg.block_kv_dq, cfg.block_q_dkv, cfg.block_kv_dkv]\n    return all(b is None for b in blocks) or all(b is not None for b in blocks)","tryCatchPattern":null,"preventionTips":["Build TuningConfig presets programmatically so all four backward sizes are set together.","Never partially override a copied preset; override all-or-none of the backward block fields."],"tags":["pallas","jax","config-validation","dataclass","autotuning"],"backgroundTag":"incomplete-config","analyzedSha":"24c60942c5c5fdad3a6addffb4c6e6d2f228f04f","analyzedAt":"2026-08-28T11:40:14.686Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}