jax-ml/jax · error · ValueError

ref must be scalar.

Error message

ref must be scalar.

What it means

atomic_cas in Pallas Triton operates on a single scalar memory location, so the Ref passed in must be scalar (shape ()). A Ref with a non-empty shape means an array location was given, which the Triton compare-and-swap lowering cannot handle.

Source

Thrown at jax/_src/pallas/triton/primitives.py:623

    mask: TO BE DOCUMENTED.

  Returns:
    The value at the given index prior to the atomic operation.
  """
  return _atomic_rmw(
      x_ref_or_view, idx, val, mask=mask, atomic_type=AtomicOpType.XOR
  )


atomic_cas_p = jax_core.Primitive("atomic_cas")


@atomic_cas_p.def_effectful_abstract_eval
def _atomic_cas_abstract_eval(ref_aval, cmp_aval, val_aval):
  if cmp_aval.dtype != val_aval.dtype or cmp_aval.shape != val_aval.shape:
    raise ValueError("cmp and val must have identical dtypes and shapes")
  if ref_aval.shape:
    raise ValueError("ref must be scalar.")
  if cmp_aval.shape:
    raise ValueError("cmp must be scalar.")
  if val_aval.shape:
    raise ValueError("val must be scalar.")
  return jax_core.ShapedArray(val_aval.shape, val_aval.dtype), {
      state.WriteEffect(0)
  }


def atomic_cas(ref, cmp, val):
  """Performs an atomic compare-and-swap of the value in the ref with the

  given value.

  Args:
    ref: The ref to operate on.
    cmp: The expected value to compare against.
    val: The value to swap in.

View on GitHub (pinned to 1e1c6a8fc0)

Solutions

  1. Index the ref down to a scalar first: p.atomic_cas(ref[idx], cmp, val)
  2. If you need CAS over multiple elements, put it inside a loop over indices with scalar refs

Example fix

# before
p.atomic_cas(ref, cmp, val)  # ref has shape (8,)
# after
p.atomic_cas(ref[3], cmp, val)  # scalar location
Defensive patterns

Strategy: validation

Validate before calling

assert ref_aval.shape == (), 'index the ref down to a scalar before atomic_cas'

Prevention

When it happens

Trigger: Passing a block Ref or an array-shaped Ref as the first argument to atomic_cas, e.g. p.atomic_cas(block_ref, 0, 1) where block_ref has shape (128,).

Common situations: Indexing the Ref first with a scalar index to get a scalar view is forgotten; assuming atomic_cas works elementwise over a whole block like atomic_add with a mask.

Related errors


AI-assisted analysis of jax-ml/jax@1e1c6a8fc0 (2026-08-27). Data as JSON: /api/errors/b20ba85bdeaf7dfb. Report an issue: GitHub.