Skip to content

Commit 5cc0c03

Browse files
Merge pull request #698 from Zentrik/fix-asarray-overhanging-chunks
Fix asarray when chunk dims are greater than shape dims
2 parents 9632981 + 3a29061 commit 5cc0c03

2 files changed

Lines changed: 24 additions & 21 deletions

File tree

src/blosc2/ndarray.py

Lines changed: 5 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -315,28 +315,12 @@ def are_partitions_behaved(shape, chunks, blocks):
315315
bool
316316
True if the partitions are well-behaved, False otherwise.
317317
"""
318+
def check_contiguity(container, part):
319+
if container and container[-1] != part[-1]:
320+
return False
321+
return builtins.all(size % unit == 0 for size, unit in zip(container[:-1], part[:-1], strict=True))
318322

319-
# Check C-contiguity among partitions
320-
def check_contiguity(shape, part):
321-
ndims = len(shape)
322-
inner_dim = ndims - 1
323-
for i, size, unit in zip(reversed(range(ndims)), reversed(shape), reversed(part), strict=True):
324-
if size > unit:
325-
if i < inner_dim:
326-
if size % unit != 0:
327-
return False
328-
else:
329-
if size != unit:
330-
return False
331-
inner_dim = i
332-
return True
333-
334-
# Check C-contiguity for blocks inside chunks
335-
if not check_contiguity(chunks, blocks):
336-
return False
337-
338-
# Check C-contiguity for chunks inside shape
339-
return check_contiguity(shape, chunks)
323+
return check_contiguity(chunks, blocks) and check_contiguity(shape, chunks)
340324

341325

342326
def get_flat_slices_orig(shape: tuple[int], s: tuple[slice, ...]) -> list[slice]:

tests/ndarray/test_ndarray.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,25 @@ def test_asarray(a):
103103
np.testing.assert_allclose(a, b[:])
104104

105105

106+
@pytest.mark.parametrize(
107+
("shape", "chunks", "blocks"),
108+
[
109+
((146, 23802), (147, 23802), (1, 23802)),
110+
((2200, 1000), (1100, 1024), (10, 1024)),
111+
((20, 300, 500), (21, 300, 500), (1, 300, 500)),
112+
],
113+
)
114+
def test_asarray_chunks_larger_than_shape(shape, chunks, blocks):
115+
# Above 16 MB, asarray fills chunk by chunk; padded chunks must skip update_data
116+
a = np.arange(math.prod(shape), dtype=np.float64).reshape(shape)
117+
assert a.nbytes > 2**24
118+
119+
b = blosc2.asarray(a, chunks=chunks, blocks=blocks)
120+
121+
np.testing.assert_array_equal(b[:], a)
122+
assert not blosc2.are_partitions_behaved(shape, chunks, blocks)
123+
124+
106125
def test_asarray_persists_copy_with_urlpath(tmp_path):
107126
array = blosc2.asarray(np.arange(10, dtype=np.int64), chunks=(5,), blocks=(2,))
108127
path = tmp_path / "persisted_copy.b2nd"

0 commit comments

Comments
 (0)