Skip to content

Commit 065a456

Browse files
committed
Re-enable STUNE for some codecs (and see if that helps with windows CI recent failure)
1 parent 83b1dc9 commit 065a456

2 files changed

Lines changed: 41 additions & 23 deletions

File tree

src/blosc2/core.py

Lines changed: 34 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1586,25 +1586,40 @@ def compute_chunks_blocks( # noqa: C901
15861586

15871587
if blocks is None:
15881588
# Get the default blocksize for the compression params
1589-
# compress2 is used just to provide a hint on the blocksize
1590-
# However, it does not work well with filters that are not shuffle or bitshuffle,
1591-
# so let's get rid of them
1592-
# filters = cparams.get("filters", None)
1593-
# if filters:
1594-
# cparams2 = copy.deepcopy(cparams)
1595-
# for i, filter in enumerate(filters):
1596-
# if filter not in (blosc2.Filter.SHUFFLE, blosc2.Filter.BITSHUFFLE):
1597-
# cparams2["filters"][i] = blosc2.Filter.NOFILTER
1598-
# else:
1599-
# cparams2 = cparams
1600-
# Force STUNE to get a hint on the blocksize
1601-
# aux_tuner = cparams2.get("tuner", blosc2.Tuner.STUNE)
1602-
# cparams2["tuner"] = blosc2.Tuner.STUNE
1603-
# src = blosc2.compress2(np.zeros(nitems, dtype=f"V{itemsize}"), **cparams2)
1604-
# _, _, blocksize = blosc2.get_cbuffer_sizes(src)
1605-
# We disable internal STUNE path as it is a bit costly, specially for small arrays.
1606-
# The heuristic below should be good enough in general.
1607-
blocksize = 32 * 1024
1589+
# Check if we need STUNE for lossy codecs/filters that have specific blocksize requirements
1590+
codec = cparams.get("codec")
1591+
filters = cparams.get("filters", None)
1592+
needs_stune = codec in (
1593+
blosc2.Codec.ZFP_RATE,
1594+
blosc2.Codec.ZFP_PREC,
1595+
blosc2.Codec.ZFP_ACC,
1596+
blosc2.Codec.NDLZ,
1597+
) or (filters and any(f in (blosc2.Filter.NDMEAN, blosc2.Filter.NDCELL) for f in filters))
1598+
1599+
if needs_stune:
1600+
# Lossy codecs need proper blocksize calculation via STUNE
1601+
# Using an 8 MB buffer should be enough for detecting the whole range of blocksizes
1602+
nitems = 2**23 // itemsize
1603+
# compress2 is used just to provide a hint on the blocksize
1604+
# However, it does not work well with filters that are not shuffle or bitshuffle,
1605+
# so let's get rid of them
1606+
if filters:
1607+
cparams2 = copy.deepcopy(cparams)
1608+
for i, filter in enumerate(filters):
1609+
if filter not in (blosc2.Filter.SHUFFLE, blosc2.Filter.BITSHUFFLE):
1610+
cparams2["filters"][i] = blosc2.Filter.NOFILTER
1611+
else:
1612+
cparams2 = cparams
1613+
# Force STUNE to get a hint on the blocksize
1614+
aux_tuner = cparams2.get("tuner", blosc2.Tuner.STUNE)
1615+
cparams2["tuner"] = blosc2.Tuner.STUNE
1616+
src = blosc2.compress2(np.zeros(nitems, dtype=f"V{itemsize}"), **cparams2)
1617+
_, _, blocksize = blosc2.get_cbuffer_sizes(src)
1618+
cparams2["tuner"] = aux_tuner
1619+
else:
1620+
# We disable internal STUNE path for regular codecs as it is a bit costly, specially for small arrays.
1621+
# The heuristic below should be good enough in general.
1622+
blocksize = 32 * 1024
16081623
# Minimum blocksize calculation
16091624
min_blocksize = blocksize
16101625
if platform.machine() == "x86_64":
@@ -1634,10 +1649,6 @@ def compute_chunks_blocks( # noqa: C901
16341649
# Fix for #364
16351650
if blocksize < itemsize:
16361651
blocksize = itemsize
1637-
1638-
# We disable internal STUNE path as it is a bit costly, specially for small arrays.
1639-
# See above.
1640-
# cparams2["tuner"] = aux_tuner
16411652
else:
16421653
blocksize = math.prod(blocks) * itemsize
16431654

tests/ndarray/test_lossy.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,13 @@
6464
)
6565
def test_lossy(shape, cparams, dtype, urlpath, contiguous):
6666
cparams_dict = cparams if isinstance(cparams, dict) else asdict(cparams)
67+
codec = cparams_dict.get("codec")
68+
if codec is not None:
69+
# Skip if the codec library is not available in this build (e.g. some Windows builds).
70+
try:
71+
blosc2.clib_info(codec)
72+
except ValueError:
73+
pytest.skip(f"codec {codec} is not supported in this build")
6774
if cparams_dict.get("codec") == blosc2.Codec.NDLZ:
6875
dtype = np.uint8
6976
array = np.linspace(0, np.prod(shape), np.prod(shape), dtype=dtype).reshape(shape)

0 commit comments

Comments
 (0)