{"record":{"id":"a7219ab00b9f0fe2","repo":"sgl-project/sglang","slug":"topk-length-must-be-contiguous","errorCode":null,"errorMessage":"topk_length must be contiguous","messagePattern":"topk_length must be contiguous","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/kernels/ops/attention/sparse_mla_q8kv8_prefill_sm90.py","lineNumber":392,"sourceCode":"            \"Q8KV8 sparse-prefill topk width must be a positive multiple of 128, \"\n            f\"got {topk}\"\n        )\n\n    if topk_length is not None:\n        if topk_length.shape != (s_q,) or topk_length.dtype != torch.int32:\n            raise ValueError(\n                f\"topk_length must be int32 with shape ({s_q},), got \"\n                f\"{tuple(topk_length.shape)}/{topk_length.dtype}\"\n            )\n        if not topk_length.is_cuda:\n            raise ValueError(\"topk_length must be a CUDA tensor\")\n        if topk_length.device != device:\n            raise ValueError(\n                \"topk_length must be on q's device \"\n                f\"{device}, got {topk_length.device}\"\n            )\n        if not topk_length.is_contiguous():\n            raise ValueError(\"topk_length must be contiguous\")\n        if torch.any(topk_length < 0).item() or torch.any(topk_length > topk).item():\n            raise ValueError(\n                \"topk_length values must satisfy \" f\"0 <= topk_length <= topk ({topk})\"\n            )\n\n    if d_v != 512:\n        raise ValueError(\n            f\"sparse_mla_q8kv8_prefill_fwd only supports d_v=512, got {d_v}\"\n        )\n\n    if attn_sink is not None and topk_length is None:\n        raise ValueError(\"attn_sink requires topk_length to be provided as well\")\n\n    if attn_sink is not None:\n        if attn_sink.shape != (h_q,) or attn_sink.dtype != torch.float32:\n            raise ValueError(\n                f\"attn_sink must be float32 with shape ({h_q},), got \"\n                f\"{tuple(attn_sink.shape)}/{attn_sink.dtype}\"","sourceCodeStart":374,"sourceCodeEnd":410,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/kernels/ops/attention/sparse_mla_q8kv8_prefill_sm90.py#L374-L410","documentation":"topk_length must be contiguous, like the other device tensors: the kernel reads it with raw pointer arithmetic over the (s_q,) int32 vector, so strided views are rejected.","triggerScenarios":"Passing a sliced topk_length (e.g. lengths[keep_mask] or a strided view of a larger buffer) that is non-contiguous.","commonSituations":"Slicing a pooled per-batch lengths buffer; boolean-mask indexing that happened to produce a copy vs. a view inconsistency; interleaving lengths with other metadata in one tensor.","solutions":["topk_length = topk_length.contiguous() before the call","Store lengths in a dedicated dense (s_q,) buffer","Avoid views/strides when assembling the lengths tensor"],"exampleFix":"// before\nout = fwd(q, kv, indices, topk_length=lengths[start:start+s_q])\n// after\ntopk_length = lengths[start:start+s_q].contiguous()\nout = fwd(q, kv, indices, topk_length=topk_length)","handlingStrategy":"validation","validationCode":"if not topk_length.is_contiguous(): topk_length = topk_length.contiguous()","typeGuard":"def dense_lengths(tl: torch.Tensor) -> bool:\n    return tl.is_contiguous()","tryCatchPattern":null,"preventionTips":["Avoid strided views into pooled length buffers","Materialize slices before passing to kernels"],"tags":["contiguity","topk"],"backgroundTag":"non-contiguous-tensor","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}