{"record":{"id":"39247e10efc2db11","repo":"sgl-project/sglang","slug":"kda-cutedsl-safe-gate-lower-bound-not-yet-suppo","errorCode":null,"errorMessage":"KDA cutedsl: safe_gate (lower_bound) not yet supported","messagePattern":"KDA cutedsl: safe_gate \\(lower_bound\\) not yet supported","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"python/sglang/kernels/ops/attention/linear/kda_blackwell/__init__.py","lineNumber":147,"sourceCode":"    Pool mode: ``h0`` is the state pool [num_slots, Hv, V, K] and ``h0_indices``\n    maps each sequence to its slot; the h kernel reads AND writes the pool rows\n    in place (fused state gather/scatter — no [N, Hv, V, K] intermediates), and\n    the returned ``ht`` is the pool tensor itself.\n    \"\"\"\n    import torch.nn.functional as F\n\n    T, Hv, K = q.shape\n    V = v.shape[-1]\n    if scale is None:\n        scale = K**-0.5\n    if num_sms is None:\n        num_sms = torch.cuda.get_device_properties(q.device).multi_processor_count\n\n    # Gate activation (standard KDA gate). Fused into the prologue is a B2 TODO;\n    # for now a small PyTorch pass, matching chunk_kda's kda_gate_chunk_cumsum.\n    if A_log is not None:\n        if lower_bound is not None:\n            raise NotImplementedError(\n                \"KDA cutedsl: safe_gate (lower_bound) not yet supported\"\n            )\n        x = g.float()\n        if dt_bias is not None:\n            x = x + dt_bias.float().view(1, Hv, K)\n        g_act = -torch.exp(A_log.float()).view(1, Hv, 1) * F.softplus(x)\n    else:\n        g_act = g.float()\n\n    # Reusable scratch (eye/pack/U/W/V_new/h_chunks) + cached metadata; only the\n    # returned o/ht are freshly allocated. This removes the ~0.2-0.6ms/call host\n    # overhead (re-alloc + re-zero of ~200MB + metadata sync) that otherwise drags\n    # the (fast) cutedsl kernels below Triton.\n    ws, chunk_indices, chunk_offsets, total_chunks, total, pad_t = _kda_workspace(\n        q, T, Hv, K, V, cu_seqlens\n    )\n\n    # KL/qg2 from the prologue fold the decay with a chunk-global g_last reference","sourceCodeStart":129,"sourceCodeEnd":165,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/kernels/ops/attention/linear/kda_blackwell/__init__.py#L129-L165","documentation":"The CUTLASS-DSL chunked KDA prefill kernel (chunk_kda_cutedsl) computes the gate as -exp(A_log)*softplus(g+dt_bias) in a PyTorch prologue pass, and that formulation has no support for the numerically-safe gate variant (lower_bound / safe_gate, which clamps the gate to avoid -inf decay). Passing both A_log and lower_bound is therefore explicitly rejected with NotImplementedError until the gate fusion TODO is done.","triggerScenarios":"Calling chunk_kda_cutedsl(q, k, v, g, A_log=..., lower_bound=0.1, ...) — i.e. a KDA model configured with a safe-gate lower bound (e.g. KDA-2 style checkpoints) on the Blackwell CUTLASS path.","commonSituations":"Serving a KDA model whose config sets a nonzero lower_bound while the runtime selects the cutedsl kernel; tests like test_kda_chunk_cutedsl_realistic_gate that probe safe-gate support; Blackwell GPU routing that prefers the CUTLASS implementation over the Triton one.","solutions":["Drop lower_bound (pass None) so the standard gate path is used — only valid if the checkpoint tolerates it","Use the non-cutedsl chunk_kda implementation (Triton path) which supports safe_gate, by disabling the cutedsl backend/flag","Wait for or implement safe_gate support in the cutedsl gate prologue (the B2 TODO noted in the code)"],"exampleFix":"# before\no, final_state = chunk_kda_cutedsl(q, k, v, g, A_log=A_log, lower_bound=0.1, dt_bias=dt_bias)\n# after\no, final_state = chunk_kda(q, k, v, g, A_log=A_log, lower_bound=0.1, dt_bias=dt_bias)  # Triton path supports safe_gate","handlingStrategy":"fallback","validationCode":"if A_log is not None and lower_bound is not None:\\n    # cutedsl path lacks safe_gate support; use the Triton chunk_kda path\n    out = chunk_kda(q, k, v, g, A_log=A_log, lower_bound=lower_bound, ...)\nelse:\\n    out = chunk_kda_cutedsl(...)","typeGuard":null,"tryCatchPattern":"try:\\n    out = chunk_kda_cutedsl(q, k, v, g, A_log=A_log, lower_bound=lb)\\nexcept NotImplementedError:\\n    out = chunk_kda(q, k, v, g, A_log=A_log, lower_bound=lb)","preventionTips":["Check lower_bound is None before selecting the cutedsl backend","Track upstream: safe_gate support for cutedsl is a planned TODO"],"tags":["kda","cutedsl","safe-gate","not-implemented","linear-attention"],"backgroundTag":"unsupported-feature-not-implemented","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}