{"record":{"id":"51e154b93d83b4ba","repo":"sgl-project/sglang","slug":"tgv-cute-ext-tactic-tactic-out-of-range-0-len","errorCode":null,"errorMessage":"TGV cute_ext tactic {tactic} out of range [0, {len(_TGV_CUTE_EXT_TACTIC_CONFIGS)}).","messagePattern":"TGV cute_ext tactic (.+?) out of range \\[0, (.+?)\\)\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/kernels/ops/gemm/cutedsl_bf16_gemm.py","lineNumber":1256,"sourceCode":"    # bias is per-output-feature in PyTorch terms. After the A↔B swap the\n    # kernel's M-axis maps to PyTorch's N-axis, which is exactly what the\n    # bias indexes — so this is a direct (0, 1, 0) broadcast.\n    L = c_swap.shape[0]\n    M_ce = c_swap.shape[1]  # == PyTorch N\n    N_ce = c_swap.shape[2]  # == PyTorch M\n    bias_3d = bias_pt.as_strided(size=(L, M_ce, N_ce), stride=(0, 1, 0))\n    bias_ = from_dlpack(bias_3d.detach(), assumed_align=2).mark_layout_dynamic(\n        leading_dim=1\n    )\n    return a_, b_, c_, bias_, layout\n\n\ndef _resolve_tactic(tactic: int) -> Tuple[int, int, int, bool]:\n    \"\"\"Return (cta_m, cta_n, num_ab_stage, use_2cta) for the given tactic id.\"\"\"\n    if tactic < 0:\n        tactic = _TGV_CUTE_EXT_DEFAULT_TACTIC\n    if tactic >= len(_TGV_CUTE_EXT_TACTIC_CONFIGS):\n        raise ValueError(\n            f\"TGV cute_ext tactic {tactic} out of range [0, {len(_TGV_CUTE_EXT_TACTIC_CONFIGS)}).\"\n        )\n    return _TGV_CUTE_EXT_TACTIC_CONFIGS[tactic]\n\n\ndef _run_tgv(\n    a: torch.Tensor,\n    b: torch.Tensor,\n    bias: Optional[torch.Tensor],\n    out: torch.Tensor,\n    pdl: bool,\n    tactic: int,\n) -> torch.Tensor:\n    \"\"\"Dispatch one TGV GEMM: a (M, K) @ b (K, N) -> out (M, N), bias (N,).\"\"\"\n    cta_m, cta_n, num_ab_stage, use_2cta = _resolve_tactic(tactic)\n    has_bias = bias is not None\n\n    a_, b_, c_, bias_, (a_leading, b_leading, c_leading) = _to_cute_swap(","sourceCodeStart":1238,"sourceCodeEnd":1274,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/kernels/ops/gemm/cutedsl_bf16_gemm.py#L1238-L1274","documentation":"TGV tactic ids index into _TGV_CUTE_EXT_TACTIC_CONFIGS; a tactic >= len(configs) (or an explicitly non-negative out-of-range id) is invalid. Negative tactics are replaced by the default tactic.","triggerScenarios":"Calling _run_tgv with a user-supplied tactic integer larger than the number of hardcoded tactic configs.","commonSituations":"Porting tactic ids from a newer/older kernel version where the config table changed size, or autotuning sweeps that assume more tactics exist.","solutions":["Clamp tactic to the valid range: 0 <= tactic < len(_TGV_CUTE_EXT_TACTIC_CONFIGS).","Pass -1 (or omit) to use the default tactic.","Regenerate tactic lists after upgrading the kernel module."],"exampleFix":"// before\n_run_tgv(x, w, bias, tactic=999)\n// after\n_run_tgv(x, w, bias, tactic=-1)  # default tactic","handlingStrategy":"validation","validationCode":"assert -1 <= tactic < len(_TGV_CUTE_EXT_TACTIC_CONFIGS)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use -1 for the default tactic.","Validate tactic lists after kernel upgrades."],"tags":["gemm","tgv","tactic","out-of-range"],"backgroundTag":"invalid-kernel-tactic-id","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}