{"record":{"id":"35c4a0c2350bf2fe","repo":"sgl-project/sglang","slug":"mixed-qkv-must-be-contiguous-in-the-last-dim-35c4a0","errorCode":null,"errorMessage":"`mixed_qkv` must be contiguous in the last dim.","messagePattern":"`mixed_qkv` must be contiguous in the last dim\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/kernels/ops/attention/helion/kda_decode.py","lineNumber":233,"sourceCode":"\n\ndef validate_packed_decode_inputs(\n    mixed_qkv: torch.Tensor,\n    a: torch.Tensor,\n    b: torch.Tensor,\n    A_log: torch.Tensor,\n    dt_bias: torch.Tensor,\n    initial_state: torch.Tensor,\n    out: torch.Tensor,\n    ssm_state_indices: torch.Tensor,\n) -> tuple[int, int, int, int, int]:\n    \"\"\"Apply the shape and layout checks from SGLang's packed wrapper.\"\"\"\n    if mixed_qkv.ndim != 2:\n        raise ValueError(\n            f\"`mixed_qkv` must be a 2D tensor (got ndim={mixed_qkv.ndim}).\"\n        )\n    if mixed_qkv.stride(-1) != 1:\n        raise ValueError(\"`mixed_qkv` must be contiguous in the last dim.\")\n    if a.ndim != 2 or b.ndim != 2:\n        raise ValueError(\n            f\"`a` and `b` must be 2D tensors (got a.ndim={a.ndim}, b.ndim={b.ndim}).\"\n        )\n    if a.stride(-1) != 1 or b.stride(-1) != 1:\n        raise ValueError(\"`a`/`b` must be contiguous in the last dim.\")\n    if A_log.ndim != 1 or dt_bias.ndim != 1:\n        raise ValueError(\"`A_log`/`dt_bias` must be 1D tensors.\")\n    if A_log.stride(0) != 1 or dt_bias.stride(0) != 1:\n        raise ValueError(\"`A_log`/`dt_bias` must be contiguous.\")\n    if ssm_state_indices.ndim != 1:\n        raise ValueError(\n            \"`ssm_state_indices` must be 1D for packed decode \"\n            f\"(got ndim={ssm_state_indices.ndim}).\"\n        )\n    if not out.is_contiguous():\n        raise ValueError(\"`out` must be contiguous.\")\n","sourceCodeStart":215,"sourceCodeEnd":251,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/kernels/ops/attention/helion/kda_decode.py#L215-L251","documentation":"The kernel reads mixed_qkv rows with unit stride in the last dimension; a non-contiguous last dim (e.g. a strided view or transpose) would produce wrong memory access. The validator enforces mixed_qkv.stride(-1) == 1.","triggerScenarios":"Passing a sliced or transposed mixed_qkv view where the last dim has stride > 1.","commonSituations":"Slicing a larger projection output tensor (qkv_buf[:, :D]); passing a transposed tensor from a fused kernel.","solutions":["Call .contiguous() on mixed_qkv before the call","Or allocate/produce mixed_qkv directly contiguous in the last dim"],"exampleFix":"# before\nout = decode(mixed_qkv[:, :kdim], ...)\n# after\nqkv = mixed_qkv[:, :kdim].contiguous()\nout = decode(qkv, ...)","handlingStrategy":"validation","validationCode":"mixed_qkv = mixed_qkv.contiguous() if mixed_qkv.stride(-1) != 1 else mixed_qkv","typeGuard":"def last_dim_contiguous(t: torch.Tensor) -> bool:\n    return t.stride(-1) == 1","tryCatchPattern":null,"preventionTips":["Avoid slicing packed buffers without copying","Add stride checks to shared tensor-prep helpers"],"tags":["kda","mamba","contiguity","helion"],"backgroundTag":"non-contiguous-tensor","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}