Skip to content

Commit b5c1c3e

Browse files
committed
Optimisation for lazyexpr reductions
1 parent 45359b2 commit b5c1c3e

1 file changed

Lines changed: 10 additions & 3 deletions

File tree

src/blosc2/lazyexpr.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1800,18 +1800,19 @@ def reduce_slices( # noqa: C901
18001800
# Note: we could have expr = blosc2.lazyexpr('numpy_array + 1') (i.e. no choice for chunks)
18011801
blosc2_arrs = tuple(o for o in operands.values() if hasattr(o, "chunks"))
18021802
fast_path = False
1803+
chunks = None
18031804
if blosc2_arrs: # fast path only relevant if there are blosc2 arrays
18041805
operand = max(blosc2_arrs, key=lambda x: len(x.shape))
1805-
chunks = operand.chunks
18061806

18071807
# Check if the partitions are aligned (i.e. all operands have the same shape,
18081808
# chunks and blocks, and have no padding). This will allow us to take the fast path.
18091809
same_shape = all(operand.shape == o.shape for o in operands.values() if hasattr(o, "shape"))
18101810
same_chunks = all(operand.chunks == o.chunks for o in operands.values() if hasattr(o, "chunks"))
18111811
same_blocks = all(operand.blocks == o.blocks for o in operands.values() if hasattr(o, "blocks"))
1812-
fast_path = same_shape and same_chunks and same_blocks and (0 not in chunks)
1812+
fast_path = same_shape and same_chunks and same_blocks and (0 not in operand.chunks)
18131813
aligned, iter_disk = False, False
18141814
if fast_path:
1815+
chunks = operand.chunks
18151816
# Check that all operands are NDArray for fast path
18161817
all_ndarray = all(
18171818
isinstance(value, blosc2.NDArray) and value.shape != () for value in operands.values()
@@ -1835,7 +1836,12 @@ def reduce_slices( # noqa: C901
18351836
else:
18361837
# WebAssembly does not support threading, so we cannot use the iter_disk option
18371838
iter_disk = False
1838-
else: # have to calculate chunks (this is cheap as empty just creates a thin metalayer)
1839+
else:
1840+
for arr in blosc2_arrs:
1841+
if arr.shape == shape:
1842+
chunks = arr.chunks
1843+
break
1844+
if chunks is None: # have to calculate chunks (this is cheap as empty just creates a thin metalayer)
18391845
temp = blosc2.empty(shape, dtype=dtype)
18401846
chunks = temp.chunks
18411847
del temp
@@ -1934,6 +1940,7 @@ def reduce_slices( # noqa: C901
19341940
if reduce_op == ReduceOp.SUM and result[()] == 0:
19351941
# Avoid a reduction when result is a zero scalar. Faster for sparse data.
19361942
continue
1943+
# Note that chunks_ refers to slice of operand chunks, not reduced_slice
19371944
result = np.full(chunks_, result[()])
19381945
if reduce_op == ReduceOp.ANY:
19391946
result = np.any(result, **reduce_args)

0 commit comments

Comments
 (0)