jax-ml/jax · error · ValueError

accumulate only supported for binary ufuncs

Error message

accumulate only supported for binary ufuncs

What it means

The ufunc .accumulate() API folds a binary operation across the input, so it only exists for ufuncs with exactly two inputs. The method fires when called on a ufunc whose nin != 2 (e.g. a unary ufunc).

Solutions

  1. Use only binary ufuncs with .accumulate
  2. For cumulative unary effects, express them with jax.lax.scan or apply the op before accumulating

Example fix

// before
jnp.negative.accumulate(x)
// after
jnp.add.accumulate(-x)
Defensive patterns

Strategy: validation

Validate before calling

assert ufunc.nin == 2 before ufunc.accumulate(...)

Type guard

def is_binary_ufunc(u): return u.nin == 2

Prevention

When it happens

Trigger: jnp.negative.accumulate(x) or .accumulate on any ufunc with a single input.

Common situations: Generic code that reflects over ufuncs; mistaking accumulate for a general scan over unary ops.

Related errors


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

Appendix: source

Thrown at jax/_src/numpy/ufunc_api.py:372

      :func:`jax.numpy.cumprod` along the specified axis:

      >>> jnp.multiply.accumulate(x, axis=1)
      Array([[  1,   2,   6],
             [  4,  20, 120]], dtype=int32)
      >>> jnp.cumprod(x, axis=1)
      Array([[  1,   2,   6],
             [  4,  20, 120]], dtype=int32)

      For other binary ufuncs, the accumulation is an operation not available
      via standard APIs. For example, :meth:`jax.numpy.bitwise_or.accumulate`
      is essentially a bitwise cumulative ``any``:

      >>> jnp.bitwise_or.accumulate(x, axis=1)
      Array([[1, 3, 3],
             [4, 5, 7]], dtype=int32)
    """
    if self.nin != 2:
      raise ValueError("accumulate only supported for binary ufuncs")
    if self.nout != 1:
      raise ValueError("accumulate only supported for functions returning a single value")
    if out is not None:
      raise NotImplementedError(f"out argument of {self.__name__}.accumulate()")
    accumulate = self.__static_props['accumulate'] or self._accumulate_via_scan
    return accumulate(a, axis=axis, dtype=dtype)

  def _accumulate_via_scan(self, arr: ArrayLike, axis: int = 0,
                           dtype: DTypeLike | None = None) -> Array:
    assert self.nin == 2 and self.nout == 1
    check_arraylike(f"{self.__name__}.accumulate", arr)
    arr = lax.asarray(arr)

    if dtype is None:
      dtype = api.eval_shape(self._func, lax._one(arr), lax._one(arr)).dtype

    if axis is None or isinstance(axis, tuple):
      raise ValueError("accumulate does not allow multiple axes")

View on GitHub (pinned to 1e1c6a8fc0)