jax-ml/jax · error · ValueError
strides={ref_ty.get_strides_and_offset()[0]}, {ref_ty.shape=
Error message
strides={ref_ty.get_strides_and_offset()[0]}, {ref_ty.shape=}, {dim=}, {fold_rank=} What it means
memref_fold can only merge dimensions whose memory layout is compatible: either the folded slice is contiguous, or the special layout case above applies. If the strides of dims [dim, dim+fold_rank) are neither contiguous nor the foldable pattern, JAX Mosaic refuses to build the new strided layout. This protects against silently producing a memref whose linearization no longer matches memory.
Source
Thrown at jax/experimental/mosaic/gpu/utils.py:837
f"Folding {fold_rank} dimensions starting from {dim} is out of bounds"
f" for shape {new_shape}"
)
new_shape[dim : dim + fold_rank] = [
math.prod(new_shape[dim : dim + fold_rank])
]
identity = ir.AffineMapAttr.get(ir.AffineMap.get_identity(ref_ty.rank))
contig_strided_1d = ir.Attribute.parse("strided<[1]>")
# Not sure why but MLIR expects the strided 1D layout to disappear in this op.
if ref_ty.layout == identity or ref_ty.layout == contig_strided_1d:
new_layout = ir.AffineMapAttr.get(
ir.AffineMap.get_identity(ref_ty.rank - fold_rank + 1)
)
elif _is_contiguous_shape_slice(ref_ty, slice(dim, dim + fold_rank)):
new_strides, offset = ref_ty.get_strides_and_offset()
new_strides[dim : dim + fold_rank] = [new_strides[dim + fold_rank - 1]]
new_layout = ir.StridedLayoutAttr.get(offset, new_strides)
else:
raise ValueError(
f"strides={ref_ty.get_strides_and_offset()[0]}, {ref_ty.shape=},"
f" {dim=}, {fold_rank=}"
)
new_ty = ir.MemRefType.get(
new_shape, ref_ty.element_type, new_layout, ref_ty.memory_space
)
assoc = [[d] for d in range(dim)]
assoc.append([dim + i for i in range(fold_rank)])
assoc.extend([d] for d in range(dim + fold_rank, ref_ty.rank))
assert len(assoc) == new_ty.rank
return memref.collapse_shape(new_ty, ref, assoc)
def memref_unfold(ref: ir.Value, dim, factors) -> ir.Value:
"""Unfolds dim into two dimensions, the size of leading one given be major_factor."""
ref_ty = ir.MemRefType(ref.type)
new_shape = list(ref_ty.shape)View on GitHub (pinned to 1e1c6a8fc0)
Solutions
- Make the region contiguous first: copy or materialize the data into a contiguous memref (e.g. via memref.copy into an alloca) before folding
- Fold a different, contiguous set of dimensions that matches the stride pattern
- Inspect ref_ty.get_strides_and_offset() (as the message prints) and adjust the layout or choose dims whose strides are nested multiples
Example fix
// before folded = utils.memref_fold(sliced_ref, dim=1, fold_rank=2) # sliced_ref has gaps // after contig = memref.alloca(ir.MemRefType.get(sliced_shape, elem_ty), [], []) memref.copy(sliced_ref, contig) folded = utils.memref_fold(contig, dim=1, fold_rank=2)
Defensive patterns
Strategy: validation
Validate before calling
ref_ty = ir.MemRefType(ref.type)
strides, _ = ref_ty.get_strides_and_offset()
# foldable iff slice is contiguous; quick check for the common row-major case:
def contiguous(dim, fold_rank, shape, strides):
expected = 1
for i in reversed(range(dim, dim + fold_rank)):
if strides[i] != expected:
return False
expected *= shape[i]
return True
assert contiguous(dim, fold_rank, ref_ty.shape, strides) Prevention
- Materialize slices into fresh contiguous allocas before folding dims
- Print get_strides_and_offset() when a fold fails to spot non-contiguous views
When it happens
Trigger: Calling memref_fold on a memref with a strided/non-contiguous layout (e.g. a slice of a larger buffer, a transposed view, or views with padded strides) where new_shape folding succeeds but _is_contiguous_shape_slice and the preceding layout branch both fail.
Common situations: Folding dims of a memref produced by memref_slice, memref_reinterpret_cast, or TMA/async-copy views with non-unit leading strides; feeding an arbitrary layout from a lower-level MLIR builder.
Related errors
- Only unit strides are supported but got {op.static_strides}.
- CollapseShapeOp with non-contiguous strides is not supported
- packed cannot be specified if layout is specified.
- Cannot commute `UntilingTransform` with `ReshapeTransform` w
- Swizzle {self.swizzle} requires the trailing dimension to be
AI-assisted analysis of jax-ml/jax@1e1c6a8fc0 (2026-08-27).
Data as JSON: /api/errors/920627c194c8244e.
Report an issue: GitHub.