@@ -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
0 commit comments