{"record":{"id":"648a0e792cb28725","repo":"jax-ml/jax","slug":"tiles-must-not-be-empty","errorCode":null,"errorMessage":"Tiles must not be empty","messagePattern":"Tiles must not be empty","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"jax/experimental/mosaic/gpu/fragmented_array.py","lineNumber":81,"sourceCode":"  size. Then, all newly unfolded minor dimensions are transposed to appear at\n  the end.\n\n  This expression describes multi-level tiling, by applying each element of\n  `tiles` in sequence to the array.\n\n  See https://openxla.org/xla/tiled_layout for a more detailed explanation.\n  \"\"\"\n  tiles: tuple[tuple[int, ...], ...]\n\n  def __post_init__(self):\n    if not self.tiles:\n      return\n    last_tile_rank = len(self.tiles[0])\n    for tile in self.tiles:\n      if len(tile) > last_tile_rank:\n        raise ValueError(\"Tiles must have a decreasing rank\")\n      if not tile:\n        raise ValueError(\"Tiles must not be empty\")\n      if any(d <= 0 for d in tile):\n        raise ValueError(f\"Tile shape must only have positive sizes, got: {self.tiles}\")\n      last_tile_rank = len(tile)\n\n  def __str__(self):\n    return f\"Tiling({''.join(map(str, self.tiles))})\"\n\n  def tile_shape(self, shape: tuple[int, ...]) -> tuple[int, ...]:\n    \"\"\"Computes the shape of an array after tiling.\"\"\"\n    orig_shape = shape\n    def fail():\n      raise ValueError(f\"Tiling {self.tiles} does not apply to shape {orig_shape}\")\n    for tile in self.tiles:\n      if len(tile) > len(shape):\n        fail()\n      untiled_dims, tiled_dims = shape[:-len(tile)], shape[-len(tile):]\n      if any(s % t != 0 for s, t in zip(tiled_dims, tile)):\n        fail()","sourceCodeStart":63,"sourceCodeEnd":99,"githubUrl":"https://github.com/jax-ml/jax/blob/1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb/jax/experimental/mosaic/gpu/fragmented_array.py#L63-L99","documentation":"Each tile tuple inside a Tiling must be non-empty; an empty tuple () cannot split any dimensions. Validated in Tiling.__post_init__.","triggerScenarios":"Passing a tiles list containing an empty tuple, e.g. Tiling([(), (4, 4)]), often from a programmatically generated list with a leftover ().","commonSituations":"Generated layout specs where a rank-0 fragment was appended; refactoring code that used to filter empty dims.","solutions":["Filter out empty tuples before constructing: Tiling([t for t in tiles if t])","Fix the generator so it never emits empty tile tuples"],"exampleFix":"// before\nTiling(tiles_list)  # tiles_list contains ()\n// after\nTiling([t for t in tiles_list if t])","handlingStrategy":"validation","validationCode":"assert all(len(t) > 0 for t in tiles), 'no empty tiles'","typeGuard":"def has_no_empty_tiles(tiles) -> bool:\n    return all(len(t) > 0 for t in tiles)","tryCatchPattern":null,"preventionTips":["Filter generated tile lists for empty tuples before constructing Tiling"],"tags":["mosaic","fragmented-array","tiling","validation"],"backgroundTag":"invalid-layout-spec","analyzedSha":"1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb","analyzedAt":"2026-08-27T09:53:25.647Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}