{"record":{"id":"58c554958bbabbc0","repo":"jax-ml/jax","slug":"stride-s-is-not-divisible-by-d-tile-size-t","errorCode":null,"errorMessage":"Stride {s} is not divisible by {d} (tile size = {t}). Strides: {strides}, tiling: {tiling}","messagePattern":"Stride (.+?) is not divisible by (.+?) \\(tile size = (.+?)\\)\\. Strides: (.+?), tiling: (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"jax/experimental/mosaic/gpu/dialect_lowering.py","lineNumber":1060,"sourceCode":"  tiled_ordered_strides_and_tiling = sorted(\n      tiled_strides_and_tiling, reverse=True)\n\n  to_ordered = lambda i: tiled_ordered_strides_and_tiling.index(tiled_strides_and_tiling[i])\n  from_ordered = lambda i: tiled_strides_and_tiling.index(tiled_ordered_strides_and_tiling[i])\n\n  ordered_tiling = [tiling[from_ordered(i)] for i in range(len(tiling))]\n  ordered_tiled_strides = [tiled_strides[from_ordered(i)] for i in range(len(tiling))]\n\n  ordered_tiled_tiling_strides = [1]\n  for t in reversed(ordered_tiling):\n    ordered_tiled_tiling_strides.append(ordered_tiled_tiling_strides[-1] * t)\n\n  prev_s = ordered_tiled_strides[-1]\n  for s, t in zip(ordered_tiled_strides[:-1][::-1], ordered_tiling[1:][::-1], strict=True):\n    d = prev_s * t\n    prev_s = s\n    if s % d != 0:\n      raise ValueError(\n          f\"Stride {s} is not divisible by {d} (tile size = {t}). \"\n          f\"Strides: {strides}, tiling: {tiling}\"\n      )\n    ordered_tiled_tiling_strides.append(s // d * ordered_tiled_tiling_strides[-1])\n\n  ordered_tiled_tiling_strides.reverse()\n\n  return (\n      *untiled_strides,\n      *[ordered_tiled_tiling_strides[to_ordered(i)] for i in range(len(tiling))],\n      *[ordered_tiled_tiling_strides[len(tiling) + to_ordered(i)] for i in range(len(tiling))]\n  )\n\n\ndef transform_type(\n    ref_ty: ir.MemRefType,\n    transforms: tuple[lc.MemRefTransform, ...] | ir.ArrayAttr,\n) -> ir.MemRefType:","sourceCodeStart":1042,"sourceCodeEnd":1078,"githubUrl":"https://github.com/jax-ml/jax/blob/1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb/jax/experimental/mosaic/gpu/dialect_lowering.py#L1042-L1078","documentation":"For nested tiles the stride of each dimension must be divisible by (previous stride * next tile size); otherwise the tiles overlap non-uniformly and the tiled layout cannot be built.","triggerScenarios":"tile_strides where an inner tiled stride is not a multiple of the enclosing stride times tile size, e.g. strides (2048, 48, 1) with tiling (8, 4) since 48 % (1*4) != 0.","commonSituations":"Padding a tensor so inner dims are not multiples of the tile size (stride 48 with tile 4), producing misaligned nested tiles.","solutions":["Pad dimensions so strides are products of tile sizes (contiguous nested tiles)","Choose tile sizes that divide the dimension strides","Avoid interleaving untiled/padding elements inside tiled dimensions"],"exampleFix":"// before\ntile_strides((2048, 48, 1), (8, 4))  # 48 not divisible by 4\n// after\npad dim to 64 -> tile_strides((2048, 64, 1), (8, 4))","handlingStrategy":"validation","validationCode":"# check nested tile stride divisibility before calling\n# each inner stride must be divisible by (prev_stride * next_tile)\nassert all(s % (ps * t) == 0 for s, ps, t in zip(inner_strides[:-1][::-1], inner_strides[1:][::-1], tiling[1:][::-1]))","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Pad tensor dims to multiples of tile sizes so strides stay products of tile sizes","Avoid padding inside tiled dimensions"],"tags":["jax","mosaic","gpu","tiling","strides","alignment"],"backgroundTag":"size-alignment-violation","analyzedSha":"1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb","analyzedAt":"2026-08-27T09:53:25.647Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}