{"record":{"id":"8537ef62b06697f7","repo":"sgl-project/sglang","slug":"out-must-have-stride-1-in-the-last-dimension-8537ef","errorCode":null,"errorMessage":"out must have stride 1 in the last dimension","messagePattern":"out must have stride 1 in the last dimension","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/kernels/ops/attention/flash_attn/cute/interface.py","lineNumber":646,"sourceCode":"        lse_shape = (\n            (batch_size, seqlen_q, num_head)\n            if cu_seqlens_q is None\n            else (total_q, num_head)\n        )\n\n    if out is None:\n        out = torch.empty(\n            *q_batch_seqlen_shape,\n            num_head,\n            head_dim_v,\n            dtype=out_torch_dtype,\n            device=device,\n        )\n    else:\n        if out.requires_grad:\n            raise ValueError(\"out must not require gradients\")\n        if out.stride(-1) != 1:\n            raise ValueError(\"out must have stride 1 in the last dimension\")\n        _validate_tensor(\n            out,\n            \"out\",\n            (*q_batch_seqlen_shape, num_head, head_dim_v),\n            out_torch_dtype,\n            device,\n        )\n\n    if lse is None:\n        lse = (\n            torch.empty(lse_shape, dtype=torch.float32, device=device)\n            if requires_grad or return_lse\n            else None\n        )\n    elif lse is not None:\n        _validate_tensor(lse, \"lse\", lse_shape, torch.float32, device)\n\n    if seqlen_k == 0 or total_q == 0:","sourceCodeStart":628,"sourceCodeEnd":664,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/kernels/ops/attention/flash_attn/cute/interface.py#L628-L664","documentation":"The FA4 kernel writes output via TMA/vectorized stores that require the last dimension of the user-supplied out tensor to be contiguous (stride 1). A strided last dim would cause incorrect or illegal memory access.","triggerScenarios":"Passing out= whose last-dimension stride != 1, typically a slice/transpose/view (e.g. out = buf[:, :, ::2] or out = buf.transpose(-1,-2)).","commonSituations":"Writing into a preallocated buffer viewed with padding or channels-last-like layouts; slicing a larger workspace tensor.","solutions":["Pass a contiguous output: out = out.contiguous() before the call","Or allocate out fresh with torch.empty(expected_shape, dtype, device)","If writing into a bigger buffer, copy back afterwards instead of passing a strided view"],"exampleFix":"// before\nfa(..., out=buf[:, :, ::2])\n// after\nout = torch.empty(shape, dtype=dt, device=dev)\nfa(..., out=out)\nbuf[:, :, ::2] = out","handlingStrategy":"validation","validationCode":"if out is not None and out.stride(-1) != 1:\n    out = out.contiguous()","typeGuard":"def out_stride_safe(out) -> bool: return out is None or out.stride(-1) == 1","tryCatchPattern":null,"preventionTips":["Avoid passing sliced/transposed views as out=; materialize contiguous buffers","Add a debug helper that asserts last-dim contiguity of all out= tensors"],"tags":["flash-attention","stride","memory-layout","out-tensor"],"backgroundTag":"tensor-layout-mismatch","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}