jax-ml/jax · error · ValueError

varying and unreduced cannot have common mesh axes. Got vary

Error message

varying and unreduced cannot have common mesh axes. Got varying={varying} and unreduced={unreduced}

What it means

_check_mat validates a ManualAxisType: a mesh axis cannot simultaneously be 'varying' (array differs across that axis) and 'unreduced' (kept un-reduced after a collective). The two states are mutually exclusive per axis.

Source

Thrown at jax/_src/core.py:2345

  if config.remove_size_one_mesh_axis_from_type.value:
    varying = frozenset(i for i in mat.varying
                        if in_axis_env(i) or mesh.shape[i] != 1)
    unreduced = frozenset(u for u in mat.unreduced if mesh.shape[u] != 1)
    reduced = frozenset(r for r in mat.reduced if mesh.shape[r] != 1)
    u_kind = mat.unreduced_kind if unreduced else None
    return mat.update(varying=varying, unreduced=unreduced, reduced=reduced,
                      unreduced_kind=u_kind)
  return mat


def get_memory_space(memory_space):
  assert memory_space is not None
  return memory_space


def _check_mat(varying, unreduced, reduced, unreduced_kind):
  if varying & unreduced:
    raise ValueError(
        "varying and unreduced cannot have common mesh axes. Got"
        f" varying={varying} and unreduced={unreduced}")
  if varying & reduced:
    raise ValueError(
        "varying and reduced cannot have common mesh axes. Got"
        f" varying={varying} and reduced={reduced}")
  assert not (varying & unreduced & reduced)

  if unreduced_kind is not None and not isinstance(unreduced_kind, UnreducedKind):
    raise TypeError(
        "Expected unreduced_kind to be of type `jax.sharding.UnreducedKind`"
        f" but got {type(unreduced_kind)}")
  if not unreduced and unreduced_kind is not None:
    raise ValueError(
        "`unreduced_kind` should be `None` when `unreduced` is an empty set."
        f" Got {unreduced_kind=} and {unreduced=}")

def _canonicalize_mat(name, val):

View on GitHub (pinned to 1e1c6a8fc0)

Solutions

  1. Remove the axis from one of the two sets based on intended semantics
  2. If the axis should vary, drop it from unreduced; if it must stay unreduced across a reduction, drop it from varying
  3. Recompute mat from the primitive's output sharding instead of hand-writing it

Example fix

// before
mat = ManualAxisType(varying={'x'}, unreduced={'x'})

// after
mat = ManualAxisType(varying={'x'})  # or unreduced={'x'} if semantically unreduced
Defensive patterns

Strategy: validation

Validate before calling

if varying & unreduced:
    raise ValueError('axis in both varying and unreduced')

Type guard

def disjoint_mat(varying, unreduced, reduced): return not (varying & unreduced) and not (varying & reduced)

Prevention

When it happens

Trigger: Building ManualAxisType(varying={'x'}, unreduced={'x'}) or updating an aval's mat so the same axis lands in both sets; usually via internal aval update_manual_axis_type calls or spmd primitives.

Common situations: Hand-constructed mats in custom collectives or shard_map plumbing; incorrect psum/ppermute wrappers tagging outputs unreduced on axes the input already varies on.

Related errors


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