Skip to content

Commit e0d5a4e

Browse files
authored
Merge pull request #518 from Blosc/squeeze_view
Squeeze view
2 parents b6bbe99 + ef97cc3 commit e0d5a4e

File tree

6 files changed

+39
-39
lines changed

6 files changed

+39
-39
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ else()
5050
include(FetchContent)
5151
FetchContent_Declare(blosc2
5252
GIT_REPOSITORY https://github.com/Blosc/c-blosc2
53-
GIT_TAG 0c853a639ba97997e33e29db9eed202459ebc6f0 # v2.21.3
53+
GIT_TAG 77ab4b583eb7e03a6f2a411e1a728500e269540c # v2.22.0
5454
)
5555
FetchContent_MakeAvailable(blosc2)
5656
include_directories("${blosc2_SOURCE_DIR}/include")

src/blosc2/blosc2_ext.pyx

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -503,8 +503,8 @@ cdef extern from "b2nd.h":
503503
int b2nd_to_cframe(const b2nd_array_t *array, uint8_t ** cframe, int64_t *cframe_len,
504504
c_bool *needs_free);
505505

506-
int b2nd_squeeze(b2nd_array_t *array)
507-
int b2nd_squeeze_index(b2nd_array_t *array, const c_bool *index)
506+
int b2nd_squeeze(b2nd_array_t *array, b2nd_array_t **view)
507+
int b2nd_squeeze_index(b2nd_array_t *array, b2nd_array_t **view, const c_bool *index)
508508
int b2nd_resize(b2nd_array_t *array, const int64_t *new_shape, const int64_t *start)
509509
int b2nd_copy(b2nd_context_t *ctx, b2nd_array_t *src, b2nd_array_t **array)
510510
int b2nd_concatenate(b2nd_context_t *ctx, b2nd_array_t *src1, b2nd_array_t *src2,
@@ -2530,7 +2530,7 @@ cdef class NDArray:
25302530
cdef c_bool mask_[B2ND_MAX_DIM]
25312531
for i in range(ndim):
25322532
mask_[i] = mask[i]
2533-
_check_rc(b2nd_squeeze_index(array, mask_), "Error while squeezing sliced array")
2533+
_check_rc(b2nd_squeeze_index(array, &array, mask_), "Error while squeezing sliced array")
25342534
ndarray = blosc2.NDArray(_schunk=PyCapsule_New(array.sc, <char *> "blosc2_schunk*", NULL),
25352535
_array=PyCapsule_New(array, <char *> "b2nd_array_t*", NULL))
25362536

@@ -2604,19 +2604,6 @@ cdef class NDArray:
26042604
_check_rc(b2nd_resize(self.array, new_shape_, NULL),
26052605
"Error while resizing the array")
26062606

2607-
def squeeze(self, mask=None):
2608-
cdef c_bool mask_[B2ND_MAX_DIM]
2609-
if mask is None:
2610-
_check_rc(b2nd_squeeze(self.array), "Error while performing the squeeze")
2611-
else:
2612-
for i in range(self.ndim):
2613-
mask_[i] = mask[i]
2614-
_check_rc(b2nd_squeeze_index(self.array, mask_), "Error while squeezing array")
2615-
2616-
#this squeezes even if not asked for by mask - may have to use in future though
2617-
#if self.array.shape[0] == 1 and self.ndim == 1:
2618-
# self.array.ndim = 0
2619-
26202607
def as_ffi_ptr(self):
26212608
return PyCapsule_New(self.array, <char *> "b2nd_array_t*", NULL)
26222609

@@ -3001,3 +2988,22 @@ def expand_dims(arr1: NDArray, axis_mask: list[bool], final_dims: int) -> blosc2
30012988
new_base = arr1 if arr1.base is None else arr1.base
30022989
return blosc2.NDArray(_schunk=PyCapsule_New(view.sc, <char *> "blosc2_schunk*", NULL),
30032990
_array=PyCapsule_New(view, <char *> "b2nd_array_t*", NULL), _base=new_base)
2991+
2992+
def squeeze(arr1: NDArray, axis_mask: list[bool]) -> blosc2.NDArray:
2993+
"""
2994+
Remove axis from NDArray object at specified dimensions.
2995+
"""
2996+
cdef b2nd_array_t *view
2997+
cdef c_bool mask_[B2ND_MAX_DIM]
2998+
for i in range(arr1.ndim):
2999+
mask_[i] = axis_mask[i]
3000+
_check_rc(b2nd_squeeze_index(arr1.array, &view, mask_), "Error while squeezing array")
3001+
3002+
# this squeezes even if not asked for by mask - may have to use in future though
3003+
# if arr1.array.shape[0] == 1 and arr1.ndim == 1:
3004+
# arr1.array.ndim = 0
3005+
3006+
# create view with reference to self to hold onto
3007+
new_base = arr1 if arr1.base is None else arr1.base
3008+
return blosc2.NDArray(_schunk=PyCapsule_New(view.sc, <char *> "blosc2_schunk*", NULL),
3009+
_array=PyCapsule_New(view, <char *> "b2nd_array_t*", NULL), _base=new_base)

src/blosc2/linalg.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,9 +127,9 @@ def matmul(x1: blosc2.Array, x2: blosc2.NDArray, **kwargs: Any) -> blosc2.NDArra
127127
result[chunk + (slice(row, row_end), slice(col, col_end))] += np.matmul(bx1, bx2)
128128

129129
if x1_is_vector:
130-
result.squeeze(axis=-2)
130+
result = result.squeeze(axis=-2)
131131
if x2_is_vector:
132-
result.squeeze(axis=-1)
132+
result = result.squeeze(axis=-1)
133133

134134
return result
135135

src/blosc2/ndarray.py

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4681,8 +4681,7 @@ def slice(self, key: int | slice | Sequence[slice], **kwargs: Any) -> NDArray:
46814681
for order, nchunk in enumerate(aligned_chunks):
46824682
chunk = self.schunk.get_chunk(nchunk)
46834683
newarr.schunk.update_chunk(order, chunk)
4684-
newarr.squeeze(axis=np.where(mask)[0]) # remove any dummy dims introduced
4685-
return newarr
4684+
return newarr.squeeze(axis=np.where(mask)[0]) # remove any dummy dims introduced
46864685

46874686
key = (start, stop)
46884687
ndslice = super().get_slice(key, mask, **kwargs)
@@ -4724,16 +4723,7 @@ def squeeze(self, axis: int | Sequence[int]) -> NDArray:
47244723
>>> a.shape
47254724
(23, 11)
47264725
"""
4727-
axis = [axis] if isinstance(axis, int) else axis
4728-
mask = [False for i in range(self.ndim)]
4729-
for a in axis:
4730-
if a < 0:
4731-
a += self.ndim # Adjust axis to be within the array's dimensions
4732-
if mask[a]:
4733-
raise ValueError("Axis values must be unique.")
4734-
mask[a] = True
4735-
super().squeeze(mask=mask)
4736-
return self
4726+
return blosc2.squeeze(self, axis=axis)
47374727

47384728
def indices(self, order: str | list[str] | None = None, **kwargs: Any) -> NDArray:
47394729
"""
@@ -4797,8 +4787,15 @@ def squeeze(x: Array, axis: int | Sequence[int]) -> NDArray:
47974787
>>> b.shape
47984788
(23, 11)
47994789
"""
4800-
# TODO: implement squeeze as a view
4801-
return x.squeeze(axis)
4790+
axis = [axis] if isinstance(axis, int) else axis
4791+
mask = [False for i in range(x.ndim)]
4792+
for a in axis:
4793+
if a < 0:
4794+
a += x.ndim # Adjust axis to be within the array's dimensions
4795+
if mask[a]:
4796+
raise ValueError("Axis values must be unique.")
4797+
mask[a] = True
4798+
return blosc2_ext.squeeze(x, axis_mask=mask)
48024799

48034800

48044801
def array_from_ffi_ptr(array_ptr) -> NDArray:

tests/ndarray/test_lazyexpr.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1714,9 +1714,6 @@ def test_lazylinalg():
17141714
npres = np.squeeze(npD, -1)
17151715
assert out.shape == npres.shape
17161716
np.testing.assert_array_almost_equal(out[()], npres)
1717-
# refresh D since squeeze is in-place
1718-
s = shapes["D"]
1719-
D = blosc2.linspace(0, np.prod(s), shape=s)
17201717
out = blosc2.lazyexpr("D.squeeze(axis=-1)")
17211718
npres = np.squeeze(npD, -1)
17221719
assert out.shape == npres.shape

tests/ndarray/test_squeeze.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ def test_squeeze(shape, chunks, blocks, fill_value, axis):
2525
a = blosc2.full(shape, fill_value=fill_value, chunks=chunks, blocks=blocks)
2626

2727
b = np.squeeze(a[...], axis)
28-
a_ = a.squeeze(axis)
28+
a_ = blosc2.squeeze(a, axis)
2929

3030
assert a_.shape == b.shape
31-
# TODO: this would work if squeeze returns a view
32-
# assert a_.shape != a.shape
31+
# Confirm squeeze returns a view (does not modify original array)
32+
assert a_.shape != a.shape

0 commit comments

Comments
 (0)