{"record":{"id":"08daeb5be57afde3","repo":"sgl-project/sglang","slug":"kda-a-must-be-a-contiguous-2d-or-3d-tensor","errorCode":null,"errorMessage":"KDA `a` must be a contiguous 2D or 3D tensor.","messagePattern":"KDA `a` must be a contiguous 2D or 3D tensor\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/kernels/ops/attention/helion/kda_replayssm.py","lineNumber":707,"sourceCode":"    g_cache: torch.Tensor,\n    out: torch.Tensor,\n    ssm_state_indices: torch.Tensor,\n    write_pos: torch.Tensor,\n    force_flush: torch.Tensor | None = None,\n    use_qk_l2norm_in_kernel: bool = False,\n    lower_bound: float | None = None,\n) -> tuple[torch.Tensor, torch.Tensor]:\n    \"\"\"Run one buffered KDA decode step using caller-owned ReplaySSM state.\n\n    Allocates nothing persistent: the caller owns ``d_cache`` / ``k_cache`` /\n    ``g_cache`` and is responsible for advancing ``write_pos`` modulo the ring\n    length after a non-flush step and resetting it to zero after a natural or\n    forced flush. ``initial_state`` is both the checkpoint read (h0) and the\n    flush-only checkpoint write (ht), in place.\n    \"\"\"\n    batch = mixed_qkv.size(0)\n    if a.ndim not in (2, 3) or not a.is_contiguous():\n        raise ValueError(\"KDA `a` must be a contiguous 2D or 3D tensor.\")\n    if dt_bias.ndim not in (1, 2) or not dt_bias.is_contiguous():\n        raise ValueError(\"KDA `dt_bias` must be a contiguous 1D or 2D tensor.\")\n    flat_a = a.view(batch, -1)\n    flat_dt_bias = dt_bias.view(-1)\n    _, num_q_heads, num_v_heads, key_dim, value_dim = validate_packed_decode_inputs(\n        mixed_qkv,\n        flat_a,\n        b,\n        A_log,\n        flat_dt_bias,\n        initial_state,\n        out,\n        ssm_state_indices,\n    )\n\n    if write_pos.ndim != 1 or write_pos.dtype is not torch.int32:\n        raise ValueError(\"`write_pos` must be a 1D int32 tensor.\")\n    if write_pos.shape != (batch,):","sourceCodeStart":689,"sourceCodeEnd":725,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/kernels/ops/attention/helion/kda_replayssm.py#L689-L725","documentation":"helion_fused_recurrent_kda_replayssm_decode requires the KDA decay input `a` to be 2D or 3D AND contiguous, because it is flattened with a.view(batch, -1) — a view, not a reshape — before being passed to validate_packed_decode_inputs. Non-contiguous or higher-rank tensors fail this precondition.","triggerScenarios":"Passing `a` that is 4D, non-contiguous (from transpose/ slicing), or a lazily-expanded tensor to the replayssm decode; a.view(batch, -1) would throw for such inputs, so the guard fires first with a clearer message.","commonSituations":"Feeding the raw conv/gate projection output without reshaping; passing a transposed tensor from a NHWC-style layout; test tensors created via torch.randn(...).transpose(0, 1).","solutions":["Reshape and make contiguous: a = a.reshape(batch, -1).contiguous()","If a is [B, T, HV, K] from a multi-step path, select the current step a[:, t] first","Avoid passing views with holes — materialize with .contiguous() once at the producer"],"exampleFix":"// before\na = a.transpose(1, 2)  # non-contiguous\nhelion_fused_recurrent_kda_replayssm_decode(..., a=a, ...)\n// after\na = a.transpose(1, 2).contiguous()\nhelion_fused_recurrent_kda_replayssm_decode(..., a=a, ...)","handlingStrategy":"validation","validationCode":"if a.ndim not in (2, 3) or not a.is_contiguous():\n    a = a.reshape(mixed_qkv.size(0), -1).contiguous()","typeGuard":"def valid_replay_a(a: torch.Tensor) -> bool:\n    return a.ndim in (2, 3) and a.is_contiguous()","tryCatchPattern":null,"preventionTips":["Materialize `a` contiguous at the projection site","Avoid passing transposed or expanded tensors into fused decode kernels"],"tags":["kda","replayssm","contiguity","tensor-ndim"],"backgroundTag":"tensor-not-contiguous","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}