sgl-project/sglang · error · ValueError

{name} must be contiguous

Error message

{name} must be contiguous

What it means

The SM90 kernel indexes output buffers with raw contiguous pointers, so _check_out_buffer rejects non-contiguous tensors (e.g. transposed views or strided slices) with ValueError '{name} must be contiguous'.

Source

Thrown at python/sglang/kernels/ops/attention/sparse_mla_q8kv8_prefill_sm90.py:120


# Module-level cache for kernel-write-only output tensors. The active s_q rows
# are overwritten every call; buffers grow monotonically by device/head shape.
def _check_out_buffer(
    t: torch.Tensor,
    name: str,
    shape: tuple,
    dtype: torch.dtype,
    device: torch.device,
) -> None:
    if tuple(t.shape) != tuple(shape):
        raise ValueError(f"{name} must have shape {tuple(shape)}, got {tuple(t.shape)}")
    if t.dtype != dtype:
        raise ValueError(f"{name} must have dtype {dtype}, got {t.dtype}")
    if t.device != device:
        raise ValueError(f"{name} must be on device {device}, got {t.device}")
    if not t.is_contiguous():
        raise ValueError(f"{name} must be contiguous")


# Internal custom-op wrappers so the JIT kernel calls participate in
# torch.library / torch.compile tracing and kernel-API debug logging.
# The dispatch_full variant carries the optional attn_sink / topk_length
# tensors as required args; the public API chooses which op to call.
@register_custom_op(
    op_name="sparse_mla_q8kv8_prefill",
    mutates_args=["out", "max_logits", "lse"],
)
def _sparse_mla_q8kv8_prefill_op(
    q: torch.Tensor,
    kv: torch.Tensor,
    indices: torch.Tensor,
    q_scale: torch.Tensor,
    kv_scale: torch.Tensor,
    out: torch.Tensor,
    max_logits: torch.Tensor,

View on GitHub (pinned to 0132848349)

Solutions

  1. Pass freshly allocated contiguous buffers or call .contiguous() on the buffer before the call
  2. If slicing a workspace, copy into a contiguous buffer instead

Example fix

# before
out = workspace[:s_q]  # non-contiguous view
# after
out = torch.empty(s_q, h_q, d_v, dtype=torch.bfloat16, device=q.device)
sparse_mla_q8kv8_prefill_fwd(..., out=out, ...)
Defensive patterns

Strategy: validation

Validate before calling

if not out.is_contiguous():
    out = out.contiguous()  # or reallocate

Type guard

def is_contiguous_cuda(t: torch.Tensor) -> bool:
    return t.is_cuda and t.is_contiguous()

Prevention

When it happens

Trigger: Passing an out buffer that is a transpose/slice/expand of another tensor, or a torch.empty with non-default strides.

Common situations: Reusing a slice of a larger workspace buffer as an output; passing .t() views; buffers created via as_strided or narrow.

Related errors


AI-assisted analysis of sgl-project/sglang@0132848349 (2026-08-28). Data as JSON: /api/errors/48917e4b0e6bd180. Report an issue: GitHub.