jax-ml/jax · error · ValueError

Can't make a multicast reference into a peer reference.

Error message

Can't make a multicast reference into a peer reference.

What it means

remote_ref refuses to wrap a reference that already contains a MulticastRef transform, because a reference cannot be both multicast (fan-out to multiple devices) and a peer (single remote device) simultaneously.

Source

Thrown at jax/_src/pallas/mosaic_gpu/core.py:1056

  def commute_ndindexer(
      self, _: jax_core.AbstractValue, indexer: indexing.NDIndexer
  ) -> tuple[indexing.NDIndexer, MulticastRef]:
    return indexer, self


def remote_ref(
    ref: _Ref,
    device_id: jax.typing.ArrayLike,
    device_id_type: pallas_primitives.DeviceIdType = pallas_primitives.DeviceIdType.MESH,
) -> pallas_core.TransformedRef:
  """Translate memref to a symmetric memref on a peer device."""
  if not isinstance(ref, pallas_core.TransformedRef):
    if not isinstance(jax_core.typeof(ref), state_types.AbstractRef):
      raise TypeError("ref must be a reference")
    ref = pallas_core.TransformedRef(ref, transforms=())
  if any(isinstance(t, MulticastRef) for t in ref.transforms):
    raise ValueError("Can't make a multicast reference into a peer reference.")
  return pallas_core.TransformedRef(
      ref.ref, (*ref.transforms, PeerMemRef(device_id, device_id_type)),
  )


@tree_util.register_dataclass
@dataclasses.dataclass(frozen=True)
class ClusterRefTransform(state_types.Transform):
  dims: tuple[jax_core.AxisName, ...] = jax.tree.static()
  idxs: tuple[Any, ...]

  def __post_init__(self):
    if len(self.dims) != len(self.idxs):
      raise ValueError("dims and idxs must have the same length")

  def transform_type(self, x):
    return x

View on GitHub (pinned to 1e1c6a8fc0)

Solutions

  1. Apply remote_ref to the underlying ref before adding multicast, or use separate refs
  2. Don't compose MulticastRef and PeerMemRef on the same reference; split stores across distinct refs
  3. Reorder the store logic: do the peer store and multicast store on different references

Example fix

// before
m = multicast_ref(out_ref, 'x')
p = remote_ref(m, 1)

// after
p = remote_ref(out_ref, 1)
m = multicast_ref(out_ref, 'x')
Defensive patterns

Strategy: validation

Validate before calling

assert not any(isinstance(t, MulticastRef) for t in ref.transforms), 'already multicast'

Prevention

When it happens

Trigger: Calling remote_ref(multicast_ref(...)) or composing multicast_ref then remote_ref on the same reference in a collective kernel.

Common situations: Writing TPU collective kernels that mix multicast stores and peer-device access on the same output ref.

Related errors


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