diff --git a/changes/4531.feature.md b/changes/4531.feature.md new file mode 100644 index 0000000000..693d339e46 --- /dev/null +++ b/changes/4531.feature.md @@ -0,0 +1 @@ +Expose `blosc.use_threads` via `zarr.config`, allowing users to enable Blosc's internal threading for faster decoding of large single chunks. diff --git a/src/zarr/core/config.py b/src/zarr/core/config.py index c0ebb31353..564a7fbcfc 100644 --- a/src/zarr/core/config.py +++ b/src/zarr/core/config.py @@ -28,6 +28,7 @@ """ from __future__ import annotations +import importlib from typing import TYPE_CHECKING, Any, Literal, cast @@ -57,6 +58,19 @@ class Config(DConfig): # type: ignore[misc] """ + + def set(self, arg=None, **kwargs): + result = super().set(arg, **kwargs) + numcodecs = importlib.import_module("numcodecs") + numcodecs.blosc.use_threads = self.get("blosc.use_threads", False) + return result + + def refresh(self, *args, **kwargs): + result = super().refresh(*args, **kwargs) + numcodecs = importlib.import_module("numcodecs") + numcodecs.blosc.use_threads = self.get("blosc.use_threads", False) + return result + def reset(self) -> None: self.clear() self.refresh() @@ -107,6 +121,9 @@ def enable_gpu(self) -> ConfigSet: "async": {"concurrency": 10, "timeout": None}, "threading": {"max_workers": None}, "json_indent": 2, + "blosc": { + "use_threads": False, + }, "codec_pipeline": { # FusedCodecPipeline is the faster synchronous pipeline, but it stays # opt-in for now so behavior is unchanged for existing users. Early diff --git a/tests/test_config.py b/tests/test_config.py index 47f71a798e..4d3e0ff254 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -483,3 +483,11 @@ def test_deprecated_config(key: str) -> None: with pytest.raises(ValueError): with zarr.config.set({key: "foo"}): pass + + +def test_blosc_use_threads_config() -> None: + import numcodecs + + assert numcodecs.blosc.use_threads is False + with config.set({"blosc.use_threads": True}): + assert numcodecs.blosc.use_threads is True