Skip to content

Commit c5097e2

Browse files
committed
Fix ZarrAvgMerger under zarr 3.3: map chunks=True to auto-chunking
zarr 3.3 removed boolean chunk arguments, so ZarrAvgMerger's documented default chunks=True raised ValueError on every construction. Map True to None (zarr 3.3's spelling of auto-chunking) when zarr >= 3.3.0; the substitution is version-gated because on zarr 3.0 None means a single whole-shape chunk, not auto-chunking. chunks=False and explicit shapes still work on every version and pass through unchanged. zarr 3.3 also requires the bytes codec to specify endianness for multi-byte dtypes, so the test fixtures' {"name": "bytes", "configuration": {}} configs now set endian little; this form is accepted from zarr 3.0 on. Adds a regression test asserting the default produces auto-chunking rather than one whole-shape chunk. Verified with the full test_zarr_avg_merger suite on zarr 3.0.0, 3.2.0 and 3.3.0. The zarr 2 paths are untouched: the mapping is gated on the zarr version, and the fixture change only affects v3-selected configs. Signed-off-by: Dante Rigo <dhillrigo@gmail.com>
1 parent 56f0bd9 commit c5097e2

2 files changed

Lines changed: 32 additions & 6 deletions

File tree

‎monai/inferers/merger.py‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,13 @@ def __init__(
307307
self.value_store = zarr.storage.TempStore() if value_store is None else value_store # type: ignore
308308
self.count_store = zarr.storage.TempStore() if count_store is None else count_store # type: ignore
309309

310-
self.chunks = chunks
310+
# zarr 3.3 rejects boolean chunk arguments; `None` there means auto-chunking,
311+
# which is what `chunks=True` meant before. On zarr < 3.3 `None` instead means
312+
# a single whole-shape chunk, so the substitution must not be applied there.
313+
if chunks is True and version_geq(get_package_version("zarr"), "3.3.0"):
314+
self.chunks: Sequence[int] | bool | None = None
315+
else:
316+
self.chunks = chunks
311317

312318
# Initialize codecs/compressor attributes with proper types
313319
self.codecs: list | None = None

‎tests/inferers/test_zarr_avg_merger.py‎

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -195,11 +195,20 @@
195195
]
196196

197197
# Define zarr v3 codec configurations with proper bytes codec
198-
ZARR_V3_LZ4_CODECS = [{"name": "bytes", "configuration": {}}, {"name": "blosc", "configuration": {"cname": "lz4"}}]
198+
ZARR_V3_LZ4_CODECS = [
199+
{"name": "bytes", "configuration": {"endian": "little"}},
200+
{"name": "blosc", "configuration": {"cname": "lz4"}},
201+
]
199202

200-
ZARR_V3_PICKLE_CODECS = [{"name": "bytes", "configuration": {}}, {"name": "blosc", "configuration": {"cname": "zstd"}}]
203+
ZARR_V3_PICKLE_CODECS = [
204+
{"name": "bytes", "configuration": {"endian": "little"}},
205+
{"name": "blosc", "configuration": {"cname": "zstd"}},
206+
]
201207

202-
ZARR_V3_LZMA_CODECS = [{"name": "bytes", "configuration": {}}, {"name": "blosc", "configuration": {"cname": "zlib"}}]
208+
ZARR_V3_LZMA_CODECS = [
209+
{"name": "bytes", "configuration": {"endian": "little"}},
210+
{"name": "blosc", "configuration": {"cname": "zlib"}},
211+
]
203212

204213
# test for LZ4 compressor (zarr v2) or codecs (zarr v3)
205214
TEST_CASE_13_COMPRESSOR_LZ4 = [
@@ -289,7 +298,10 @@
289298
TEST_CASE_19_VALUE_CODECS = [
290299
dict(
291300
merged_shape=TENSOR_4x4.shape,
292-
value_codecs=[{"name": "bytes", "configuration": {}}, {"name": "blosc", "configuration": {"cname": "zstd"}}],
301+
value_codecs=[
302+
{"name": "bytes", "configuration": {"endian": "little"}},
303+
{"name": "blosc", "configuration": {"cname": "zstd"}},
304+
],
293305
),
294306
[
295307
(TENSOR_4x4[..., :2, :2], (0, 0)),
@@ -304,7 +316,10 @@
304316
TEST_CASE_20_COUNT_CODECS = [
305317
dict(
306318
merged_shape=TENSOR_4x4.shape,
307-
count_codecs=[{"name": "bytes", "configuration": {}}, {"name": "blosc", "configuration": {"cname": "zlib"}}],
319+
count_codecs=[
320+
{"name": "bytes", "configuration": {"endian": "little"}},
321+
{"name": "blosc", "configuration": {"cname": "zlib"}},
322+
],
308323
),
309324
[
310325
(TENSOR_4x4[..., :2, :2], (0, 0)),
@@ -449,6 +464,11 @@ def test_zarr_avg_merge_none_merged_shape_error(self):
449464
with self.assertRaises(ValueError):
450465
ZarrAvgMerger(merged_shape=None, store=self.merged_name)
451466

467+
def test_zarr_avg_merger_default_chunks_auto(self):
468+
"""chunks=True must mean auto-chunking, not one whole-shape chunk (zarr 3.3 removed boolean chunks)."""
469+
merger = ZarrAvgMerger(merged_shape=(4096, 4096), store=self.merged_name)
470+
self.assertNotEqual(merger.output.chunks, (4096, 4096))
471+
452472

453473
if __name__ == "__main__":
454474
unittest.main()

0 commit comments

Comments
 (0)