{"record":{"id":"f8b70120f192b69e","repo":"jax-ml/jax","slug":"offset-i-is-not-divisible-by-tile-size-t","errorCode":null,"errorMessage":"Offset {i} is not divisible by tile size {t}","messagePattern":"Offset (.+?) is not divisible by tile size (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"jax/experimental/mosaic/gpu/dialect_lowering.py","lineNumber":1006,"sourceCode":"  return tuple(gmem_transforms)\n\n\ndef tile_offset(\n    offsets: tuple[int, ...], tiling: tuple[int, ...]\n) -> tuple[int, ...]:\n  \"\"\"Tiles the trailing offsets in `offsets` according to `tiling`.\n\n  Raises if the offsets are not aligned with the start of a tile.\n  \"\"\"\n  if len(offsets) < len(tiling):\n    raise ValueError(f\"Offsets {offsets} have lower rank than tiling {tiling}\")\n  untiled_offsets, tiled_offsets = (\n      offsets[: -len(tiling)],\n      offsets[-len(tiling) :],\n  )\n  for i, t in zip(tiled_offsets, tiling, strict=True):\n    if i % t != 0:\n      raise ValueError(f\"Offset {i} is not divisible by tile size {t}\")\n  return (\n      *untiled_offsets,\n      *[i // t for i, t in zip(tiled_offsets, tiling, strict=True)],\n      *[0] * len(tiling),\n  )\n\n\ndef tile_strides(\n    strides: tuple[int, ...], tiling: tuple[int, ...]\n) -> tuple[int, ...]:\n  \"\"\"Tiles the trailing strides in `strides` according to `tiling`.\n\n  The `len(tiling)` trailing strides in `strides` must be the `len(tiling)`\n  smallest strides in `strides`. The same property holds in the result, i.e.,\n  given two tiles with indices i and j (i < j) with strides tiled according to\n  this function, then all the elements in tile i are physically ordered before\n  all the elements in tile j.\n","sourceCodeStart":988,"sourceCodeEnd":1024,"githubUrl":"https://github.com/jax-ml/jax/blob/1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb/jax/experimental/mosaic/gpu/dialect_lowering.py#L988-L1024","documentation":"Tiling requires offsets to be aligned to tile boundaries; an offset not divisible by the corresponding tile size cannot be expressed in the tiled index space.","triggerScenarios":"tile_offset where any trailing offset % tile_size != 0, e.g. offset 5 with tile size 8.","commonSituations":"Slicing a tiled buffer at a non-tile-aligned offset (e.g. slicing at element 16 in tiles of 32).","solutions":["Round offsets down/up to the nearest multiple of the tile size","Adjust the tile size so offsets align","Do the fine-grained offsetting with arithmetic on the loaded tile instead"],"exampleFix":"// before\ntile_offset((0, 5), (8, 8))\n// after\ntile_offset((0, 8), (8, 8))  # aligned; handle +5 within the tile","handlingStrategy":"validation","validationCode":"assert all(o % t == 0 for o, t in zip(offsets[-len(tiling):], tiling)), 'offsets must be tile-aligned'","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Align slice offsets to tile boundaries","Handle intra-tile offsets with arithmetic after loading the tile"],"tags":["jax","mosaic","gpu","tiling","alignment"],"backgroundTag":"offset-not-tile-aligned","analyzedSha":"1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb","analyzedAt":"2026-08-27T09:53:25.647Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}