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
- Don't construct UntilingTransform with an empty tiling; skip adding it when tiling is ()
- Check ref.transforms and drop no-op untile transforms before reshaping
- 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
- Filter no-op transforms out of transform stacks before reshaping
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
- Transpose cannot be moved before a tiling transform when it
- Commuting a `UntilingTransform` with a `ReshapeTransform` is
- Folding tiled dimensions into untiled dimensions is not supp
- Cannot commute `UntilingTransform` with `ReshapeTransform` w
- Unsupported transform: {type(transform)}
AI-assisted analysis of jax-ml/jax@1e1c6a8fc0 (2026-08-27).
Data as JSON: /api/errors/cbd56acb20bf82d0.
Report an issue: GitHub.