-
Notifications
You must be signed in to change notification settings - Fork 16
Rectilinear (variable-length) chunk grid #25
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
normanrz
merged 12 commits into
zarr-developers:main
from
d-v-b:feat/rectilinear-chunk-grid
Mar 25, 2026
Merged
Changes from all commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
892e761
initial commit of readme
d-v-b 2c56410
apply feedback from code review
d-v-b 84831bc
expand prior work section
d-v-b bee5f0a
punctuation
d-v-b a9ebbf2
restore single-integer chunk edge length declaration
d-v-b 945853a
fix prose and logic
d-v-b 99ba310
add jsonschema
d-v-b f17e76c
rename variables in schema
d-v-b 595d620
correct array indexing / chunk grid indexing example
d-v-b f71ee0d
disallow chunk edge lengths or repeats less than 1
d-v-b 3856861
Apply suggestion from @ilan-gold
d-v-b 720217b
prose
d-v-b File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,150 @@ | ||
| # Rectilinear chunk grid | ||
|
|
||
|
|
||
| ## Abstract | ||
|
|
||
| This document defines a `chunk_grid` object to support rectilinear chunk grids. A rectilinear grid | ||
| is a grid parametrized by a sequence of elements per axis, where each sequence of elements may be | ||
| irregularly spaced. From a chunking perspective, a rectilinear grid is defined by a sequence of | ||
| (potentially) variable-length intervals, or chunk edge lengths, for each axis of an array. | ||
|
|
||
| ## Indexing | ||
|
|
||
| The following diagram illustrates a rectilinear chunk grid. The chunk edge lengths are not to scale. | ||
|
|
||
| ```bash | ||
| 24 14 | ||
| ┌───────────────────────┬──────────────┐ | ||
| │ │ │ | ||
| │ │ │ | ||
| │ chunk (0,0) │ chunk (0,1) │ | ||
| 16 │ │ │ | ||
| │ │ │ | ||
| │ │ │ | ||
| │ │ │ | ||
| ├───────────────────────┼──────────────┤ | ||
| │ │ │ | ||
| │ │ │ | ||
| 10 │ chunk (1,0) │ chunk (1,1) │ | ||
| │ │ │ | ||
| │ │ │ | ||
| └───────────────────────┴──────────────┘ | ||
| ``` | ||
|
|
||
| Every array index resolves to a specific chunk, which can be identified by its index in the chunk | ||
| grid, and an index *within* that chunk, which we refer to here as the "chunk index". | ||
| In this example, the chunk grid edge lengths are `[[16, 10], [24, 14]]` i.e., the chunk at chunk index `(0,0)` has shape `[16, 24]`, the chunk at chunk index `(0, 1)` has shape `[14, 16]`, etc. | ||
|
|
||
| In this example, the array index `(20, 15)` resolves to the chunk grid index `(1, 0)` and the | ||
| chunk index `(4, 15)`. | ||
|
|
||
| More generally, given a tuple of tuples of edge lengths `L` and an array index `idx`, the `nth` | ||
|
d-v-b marked this conversation as resolved.
|
||
| element of `idx` (denoted `idx[n]`) maps to a chunk grid index by applying the following procedure: | ||
| compute the cumulative sum `C` of the edge lengths in `L[n]`, i.e. | ||
| `C := (L[n][0], L[n][0] + L[n][1], ...)`. The chunk grid index for | ||
| `idx[n]` is given by the index of the first element of `C` that exceeds `idx[n]`. | ||
|
|
||
| Once the chunk grid index `c` is resolved, the chunk index *within* that chunk can be determined by | ||
| subtracting `C[c-1]` from `idx[n]` if `c > 0`, or subtracting 0 otherwise. | ||
|
|
||
| ## Metadata | ||
|
|
||
| | field | type | required | | ||
| | - | - | - | | ||
| | `name` | Literal `"rectilinear"` | yes | | ||
| | `configuration` | [Configuration](#configuration) | yes | | ||
|
|
||
| ### Configuration | ||
|
|
||
| | field | type | required | notes | | ||
| | - | - | - | - | | ||
| | `kind` | Literal `"inline"` | yes | see [kinds of encodings](#kinds-of-encodings) | | ||
| | `chunk_shapes` | array of [Chunk edge lengths](#chunk-edge-lengths) | yes | The length of `chunk_shapes` MUST match the number of dimensions of the array. | ||
|
|
||
| #### Kinds of encodings | ||
|
|
||
| This specification defines a single permitted value for the `kind` field, namely the string | ||
| `"inline"`. Additions to this specification could define new permitted values for the `kind` field | ||
| which could define new semantics for the `chunk_shapes` field. | ||
|
|
||
| #### Chunk edge lengths | ||
|
|
||
| All edge lengths MUST be positive integers (i.e., at least 1). | ||
|
|
||
| The edge lengths of the chunks for an array axis with length `L` can be declared in two ways. | ||
|
|
||
| - as an integer | ||
|
|
||
| A single integer defines the step size of a regular 1-dimensional grid. | ||
|
|
||
| To convert a single integer `m` into a sequence of explicit chunk edge lengths for an array axis | ||
| with length `L`, repeat the integer `m` until it defines a sequence with a sum greater than or equal to `L`. | ||
|
|
||
| For example, if `L` is 10, and `m` is 3, the explicit list of chunk lengths is `[3, 3, 3, 3]`. | ||
|
|
||
| - as an array that can contain two types of elements: | ||
| - an integer that explicitly denotes an edge length. | ||
| - an array that denotes a [run-length encoded](#run-length-encoding) sequence of integers, | ||
| each of which denotes an edge length. | ||
|
|
||
| The sum of the edge lengths MUST equal or exceed `L`. Overflowing `L` by multiple chunks is | ||
|
d-v-b marked this conversation as resolved.
|
||
| permitted. | ||
|
|
||
| #### Run-length encoding | ||
|
|
||
| This specification defines a JSON representation for run-length encoded sequences. | ||
|
|
||
| A run-length encoded sequence of `N` repetitions of some value `V` is denoted by the JSON array `[V, N]`. Both `V` and `N` MUST be positive integers (i.e., at least 1). | ||
|
|
||
| For example, the sequence `[1, 1, 1, 1, 1]` becomes `[1, 5]` after applying this run-length encoding. | ||
|
|
||
| ## Example | ||
|
|
||
| This example demonstrates different ways of declaring the edge lengths for a rectilinear chunk grid | ||
| via the `chunk_shapes` field. | ||
|
|
||
| ```javascript | ||
| { | ||
| ... | ||
| "shape": [6, 6, 6, 6, 6], | ||
| "chunk_grid": { | ||
| "name": "rectilinear", | ||
| "configuration": { | ||
| "kind": "inline", | ||
| "chunk_shapes": [ | ||
| 4, // integer. expands to [4, 4] | ||
| [1, 2, 3], // explicit list of edge lengths. expands to itself. | ||
| [[4, 2]], // run-length encoded. expands to [4, 4]. | ||
| [[1, 3], 3], // run-length encoded and explicit list. expands to [1, 1, 1, 3] | ||
| [4, 4, 4] // explicit list with overflow chunks | ||
| ] | ||
| } | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| ## Compatibility with other chunk grids | ||
|
|
||
| A rectilinear grid is a generalization of a regular grid (a grid of regularly-spaced elements). Any | ||
| [regular chunk grid ](https://zarr-specs.readthedocs.io/en/latest/v3/chunk-grids/regular-grid/index.html) | ||
| can be converted losslessly to a rectilinear chunk grid. | ||
|
|
||
| The simplest procedure is to copy the | ||
| `chunk_shape` field of the regular chunk grid and assign it to the `chunk_shapes` field of the | ||
| rectilinear chunk grid. | ||
|
|
||
| ## Prior work | ||
|
|
||
| A scheme for rectilinear chunking was proposed in a | ||
| Zarr extension proposal (ZEP) called [ZEP 0003](https://zarr.dev/zeps/draft/ZEP0003.html). | ||
| The specification presented here builds on the ZEP 0003 proposal and adapts it to the Zarr V3. | ||
|
|
||
| Key differences between this specification and ZEP 0003: | ||
| - This specification adds run-length encoding for integer sequences | ||
| - This specification uses the field name `"chunk_shapes"` in the `configuration` field, while ZEP 0003 uses the field name `"chunk_shape"`. | ||
|
|
||
| ## Change log | ||
| No changes yet. | ||
|
|
||
| ## Current maintainers | ||
| - Davis Bennett (@d-v-b) | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,84 @@ | ||
| { | ||
| "$schema": "https://json-schema.org/draft/2020-12/schema", | ||
| "title": "RectilinearChunkGridMetadata", | ||
| "type": "object", | ||
| "properties": { | ||
| "configuration": { | ||
| "$ref": "#/$defs/RectilinearChunkGridConfiguration" | ||
| }, | ||
| "name": { | ||
| "$ref": "#/$defs/rectilinear" | ||
| } | ||
| }, | ||
| "required": [ | ||
| "name", | ||
| "configuration" | ||
| ], | ||
| "$defs": { | ||
| "ChunkEdgeLength": { | ||
| "anyOf": [ | ||
| { | ||
| "type": "integer", | ||
| "format": "uint", | ||
| "minimum": 1 | ||
| }, | ||
| { | ||
| "type": "array", | ||
| "items": { | ||
| "$ref": "#/$defs/InnerChunkEdgeLength" | ||
| } | ||
| } | ||
| ] | ||
| }, | ||
| "InnerChunkEdgeLength": { | ||
| "anyOf": [ | ||
| { | ||
| "type": "array", | ||
| "maxItems": 2, | ||
| "minItems": 2, | ||
| "prefixItems": [ | ||
| { | ||
| "type": "integer", | ||
| "format": "uint", | ||
| "minimum": 1 | ||
| }, | ||
| { | ||
| "type": "integer", | ||
| "format": "uint", | ||
| "minimum": 1 | ||
| } | ||
| ] | ||
| }, | ||
| { | ||
| "type": "integer", | ||
| "format": "uint", | ||
| "minimum": 1 | ||
| } | ||
| ] | ||
| }, | ||
| "RectilinearChunkGridConfiguration": { | ||
| "type": "object", | ||
| "properties": { | ||
| "chunk_shapes": { | ||
| "type": "array", | ||
| "items": { | ||
| "$ref": "#/$defs/ChunkEdgeLength" | ||
| } | ||
| }, | ||
| "kind": { | ||
| "$ref": "#/$defs/inline" | ||
| } | ||
| }, | ||
| "required": [ | ||
| "kind", | ||
| "chunk_shapes" | ||
| ] | ||
| }, | ||
| "inline": { | ||
| "const": "inline" | ||
| }, | ||
| "rectilinear": { | ||
| "const": "rectilinear" | ||
| } | ||
| } | ||
| } |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.