1717
1818The variables in MDIO data model can represent different types of chunk grids.
1919These grids are essential for managing multi-dimensional data arrays efficiently.
20- In this breakdown, we will explore four distinct data models within the MDIO schema,
20+ In this breakdown, we will explore the chunk grid data models within the MDIO schema,
2121each serving a specific purpose in data handling and organization.
2222
2323MDIO implements data models following the guidelines of the Zarr v3 spec and ZEPs:
2424
2525- [ Zarr core specification (version 3)] ( https://zarr-specs.readthedocs.io/en/latest/v3/core/v3.0.html )
2626- [ ZEP 1 — Zarr specification version 3] ( https://zarr.dev/zeps/accepted/ZEP0001.html )
27+ - [ ZEP 2 — Sharding codec] ( https://zarr.dev/zeps/accepted/ZEP0002.html )
2728- [ ZEP 3 — Variable chunking] ( https://zarr.dev/zeps/draft/ZEP0003.html )
2829
2930## Regular Grid
@@ -126,6 +127,100 @@ conceptual and visually not to scale.
126127└──────────┴─────┴───────┴───┘
127128```
128129
130+ ## Sharded Grid
131+
132+ The [ ShardedChunkGrid] ( ShardedChunkGrid ) model implements Zarr v3 sharding, which
133+ organizes data in a two-level hierarchy for improved I/O performance:
134+
135+ - ** Shards** : Outer containers stored as individual files/objects
136+ - ** Chunks** : Inner units within each shard for compression and fine-grained access
137+
138+ Sharding is particularly beneficial for cloud storage where reducing the number of
139+ objects improves performance while still maintaining efficient partial reads.
140+
141+ ``` {eval-rst}
142+ .. autosummary::
143+ ShardedChunkGrid
144+ ShardedChunkShape
145+ ```
146+
147+ :::{note}
148+ Sharding is only supported with Zarr v3 format. The ` shardShape ` must be evenly
149+ divisible by ` chunkShape ` along all dimensions.
150+ :::
151+
152+ :::{important}
153+ ** Non-shardable dtype limitation** : Sharding is only applied to simple scalar-type
154+ variables (e.g., ` amplitude ` , ` cdp_x ` , ` cdp_y ` ). Variables with structured dtypes
155+ (e.g., ` headers ` ) or void/bytes types (e.g., ` raw_headers ` ) will automatically use
156+ regular chunking instead, as Zarr's sharding codec does not support these dtypes.
157+ However, these variables will use the ** shard shape as their chunk shape** to maintain
158+ consistent I/O patterns across all variables.
159+ :::
160+
161+ For a 2D array with shape ` rows, cols = (256, 512) ` {l=python}, we can configure
162+ sharding with shard size ` (128, 128) ` and chunk size ` (32, 32) ` :
163+
164+ ` { "name": "sharded", "configuration": { "shardShape": [128, 128], "chunkShape": [32, 32] } } ` {l=json}
165+
166+ This creates a two-level structure where each shard contains multiple chunks:
167+
168+ ``` bash
169+ ←────────── 128 ──────────→ ←────────── 128 ──────────→ ...
170+ ┌─────────────────────────────────────────────────────────┐
171+ │ ┌─────┬─────┬─────┬─────┐ ┌─────┬─────┬─────┬─────┐ │ ↑
172+ │ │ 32 │ 32 │ 32 │ 32 │ │ 32 │ 32 │ 32 │ 32 │ │ │
173+ │ ├─────┼─────┼─────┼─────┤ ├─────┼─────┼─────┼─────┤ │ │
174+ │ │ 32 │ 32 │ 32 │ 32 │ │ 32 │ 32 │ 32 │ 32 │ │ 128
175+ │ ├─────┼─────┼─────┼─────┤ ├─────┼─────┼─────┼─────┤ │ │
176+ │ │ 32 │ 32 │ 32 │ 32 │ │ 32 │ 32 │ 32 │ 32 │ │ │
177+ │ ├─────┼─────┼─────┼─────┤ ├─────┼─────┼─────┼─────┤ │ │
178+ │ │ 32 │ 32 │ 32 │ 32 │ │ 32 │ 32 │ 32 │ 32 │ │ ↓
179+ │ └─────┴─────┴─────┴─────┘ └─────┴─────┴─────┴─────┘ │
180+ │ Shard (0,0) Shard (0,1) │
181+ ├─────────────────────────────────────────────────────────┤
182+ │ Shard (1,0) Shard (1,1) ... │
183+ └─────────────────────────────────────────────────────────┘
184+ ```
185+
186+ ### Using Sharding with Templates
187+
188+ By default, MDIO templates do not use sharding. To enable sharding on a template,
189+ set both ` full_chunk_shape ` and ` full_shard_shape ` :
190+
191+ ``` python
192+ from mdio.builder.templates.seismic_3d_poststack import Seismic3DPostStackTemplate
193+
194+ # Create template with default chunking (no sharding)
195+ template = Seismic3DPostStackTemplate(data_domain = ' depth' )
196+ print (template.full_shard_shape) # None - sharding disabled
197+
198+ # Enable sharding by setting both chunk and shard shapes
199+ template.full_chunk_shape = (32 , 32 , 128 ) # Inner chunk sizes
200+ template.full_shard_shape = (128 , 128 , 512 ) # Outer shard sizes
201+
202+ # Build dataset - will use ShardedChunkGrid for scalar variables (amplitude, coordinates)
203+ # Note: headers array will use RegularChunkGrid (structured dtypes don't support sharding)
204+ dataset = template.build_dataset(' Seismic3D' , sizes = (256 , 512 , 1024 ))
205+ ```
206+
207+ ### Ingestion with Sharding
208+
209+ When sharding is enabled, the SEG-Y ingestion process automatically iterates at the
210+ shard level instead of the chunk level. This reduces the number of I/O operations
211+ and improves performance, especially for cloud storage backends.
212+
213+ - ** With sharding** : Ingestion iterates over shards (larger units)
214+ - ** Without sharding** : Ingestion iterates over chunks (default behavior)
215+
216+ During ingestion, sharding is applied only to simple scalar-type arrays (e.g., ` amplitude ` ).
217+ Arrays with non-shardable dtypes use regular chunking with the shard shape as their chunk
218+ size. For example, with ` full_chunk_shape=(32, 32, 32) ` and ` full_shard_shape=(256, 256, 256) ` :
219+
220+ - ` amplitude ` array: chunks=(32, 32, 32), shards=(256, 256, 256)
221+ - ` headers ` array (structured dtype): chunks=(256, 256), no sharding
222+ - ` raw_headers ` array (void/bytes dtype): chunks=(256, 256), no sharding
223+
129224## Model Reference
130225
131226:::{dropdown} RegularChunkGrid
@@ -152,3 +247,15 @@ conceptual and visually not to scale.
152247```
153248
154249:::
250+ :::{dropdown} ShardedChunkGrid
251+ :animate: fade-in-slide-down
252+
253+ ``` {eval-rst}
254+ .. autopydantic_model:: ShardedChunkGrid
255+
256+ ----------
257+
258+ .. autopydantic_model:: ShardedChunkShape
259+ ```
260+
261+ :::
0 commit comments