jax-ml/jax · error · NotImplementedError

Commuting a `UntilingTransform` with a `ReshapeTransform` is

Error message

Commuting a `UntilingTransform` with a `ReshapeTransform` is not supported when the tiling is empty

What it means

Raised when commuting an UntilingTransform with a ReshapeTransform while the untiling's tiling tuple is empty. An empty tiling means there is nothing to untile, so the commutation algorithm has no dimensions to redistribute across the reshape and bails out.

Source

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

        *(a // b for a, b in zip(untiled_shape, self.tiling)),
        *self.tiling,
    ]
    new_indexer = indexing.NDIndexer.from_indices_shape(
        indices=(*untiled_idxs, *idxs_after_tiling),
        shape=(*leading_shape, *tiled_shape)
    )
    return new_indexer, self

  def commute_reshape(
      self, aval: jax_core.ShapedArray, transform: state_types.ReshapeTransform
  ) -> tuple[state_types.ReshapeTransform, UntilingTransform]:
    if not transform.shape:
      raise NotImplementedError(
          "Commuting a `UntilingTransform` with a `ReshapeTransform` is not "
          "supported when the target shape has 0 dimensions"
      )
    if not self.tiling:
      raise NotImplementedError(
          "Commuting a `UntilingTransform` with a `ReshapeTransform` is not "
          "supported when the tiling is empty"
      )
    untiled_aval = self.transform_type(aval)
    assert isinstance(untiled_aval, jax_core.ShapedArray)
    components = [[]]
    # We assume that we support only folds here for the moment. Therefore, we
    # can gather a number of consecutive dimensions such that their product
    # equals the dimension currently being processed in the reshaped shape.
    for d in untiled_aval.shape:
      reshaped_dim_size = transform.shape[len(components) - 1]
      components[-1].append(d)
      component_size = math.prod(components[-1])
      if component_size == reshaped_dim_size:
        components.append([])
      elif component_size > reshaped_dim_size:
        raise NotImplementedError(
            "Unfolding dimensions is not supported when commuting an "

View on GitHub (pinned to 1e1c6a8fc0)

Solutions

  1. Don't construct UntilingTransform with an empty tiling; skip adding it when tiling is ()
  2. Check ref.transforms and drop no-op untile transforms before reshaping
  3. Update JAX — empty-tiling transforms may indicate a stale pipeline bug; report upstream if produced internally

Example fix

// before
transforms = (*ref.transforms, UntilingTransform(()))

// after
transforms = tuple(t for t in ref.transforms if getattr(t, 'tiling', None))
Defensive patterns

Strategy: validation

Validate before calling

assert untile.tiling, 'empty tiling: skip the UntilingTransform instead'

Type guard

def is_valid_untile(t): return isinstance(t, UntilingTransform) and bool(t.tiling)

Prevention

When it happens

Trigger: commute_reshape invoked with self.tiling == () — an UntilingTransform constructed with an empty tiling tuple, typically via pallas_core.untile or an internal pipeline pass.

Common situations: Programmatically building transform stacks (e.g. custom lowering or transforms applied to non-tiled refs) that accidentally create UntilingTransform(()) instead of skipping the transform.

Related errors


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