sgl-project/sglang · error · RuntimeError

LPLB fused solver requires float32; got A.dtype={A.dtype}.

Error message

LPLB fused solver requires float32; got A.dtype={A.dtype}.

What it means

The fused IPM kernel is compiled for float32 only; A (and by extension the problem) must be float32. Other dtypes raise before launch because no fp16/bf16 variant exists for this solver.

Source

Thrown at python/sglang/kernels/ops/lplb/torch_solver.py:133

        num_iters: Number of barrier iterations (default 5).

    Returns:
        x: Solution vector, shape (NV,), float32. The kernel writes 0.5
        for every entry on non-convergence.
    """
    nc, nv = A.shape
    assert b.shape == (nc,), f"b shape mismatch: {b.shape} vs ({nc},)"
    assert c.shape == (nv,), f"c shape mismatch: {c.shape} vs ({nv},)"

    _init_fused_backend()
    if not _FUSED_AVAILABLE:
        raise RuntimeError(f"LPLB fused solver unavailable: {_unavailable_reason()}")
    if not A.is_cuda:
        raise RuntimeError(
            f"LPLB fused solver requires CUDA tensors; got A on {A.device}."
        )
    if A.dtype != torch.float32:
        raise RuntimeError(
            f"LPLB fused solver requires float32; got A.dtype={A.dtype}."
        )
    return _FUSED_SOLVE_IPM(A, b, c, num_iters=num_iters)


def solve_ipm_torch_reference(
    A: torch.Tensor,
    b: torch.Tensor,
    c: torch.Tensor,
    num_iters: int = 5,
) -> torch.Tensor:
    """Pure-torch reference for the fused IPM kernel — testing only.

    Mirrors the barrier-method iteration in ``csrc/lplb/ipm.cuh``
    step-for-step so the two can be compared numerically:

      x <- 1
      for _ in range(num_iters):

View on GitHub (pinned to 0132848349)

Solutions

  1. Cast inputs: A = A.float(); b = b.float(); c = c.float() before solve_ipm
  2. Ensure upstream conversion code uses torch.float32 when building A, b, c
  3. If you need fp16 results, solve in fp32 then cast the outputs

Example fix

// before
x, y, s = solve_ipm(A.double(), b, c)

// after
x, y, s = solve_ipm(A.float(), b.float(), c.float())
Defensive patterns

Strategy: type-guard

Validate before calling

A, b, c = (t.to(torch.float32) for t in (A, b, c))

Type guard

def is_fp32(*ts: torch.Tensor) -> bool:
    return all(t.dtype is torch.float32 for t in ts)

Prevention

When it happens

Trigger: Calling solve_ipm with A in float64 (e.g. after numpy conversion default), float16, or bfloat16.

Common situations: Data round-tripped through numpy (np.float64) then back to torch; mixed-precision model weights fed directly; explicit .half() pipelines.

Related errors


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