Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ This release is compatible with NumPy 2.5.
* Fixed `dpnp.interp` returning `nan` when querying at an exact knot point whose adjacent `fp` value is `inf` [#2986](https://github.com/IntelPython/dpnp/pull/2986)
* Fixed missing strides validation in `dpnp.tensor.usm_ndarray` constructor when allocating new memory [#2927](https://github.com/IntelPython/dpnp/pull/2927)
* Fixed `dpnp.bincount` raising a `ValueError` on an empty input array instead of returning an empty `intp` array [#3018](https://github.com/IntelPython/dpnp/pull/3018)
* Fixed `dpnp.all` and `dpnp.any` aborting when reducing over an empty axis (e.g. an array with a zero-length dimension) [#3021](https://github.com/IntelPython/dpnp/pull/3021)

### Security

Expand Down
79 changes: 45 additions & 34 deletions dpnp/tensor/_utility_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
)


def _boolean_reduction(x, axis, keepdims, func):
def _boolean_reduction(x, axis, keepdims, func, identity):
if not isinstance(x, dpt.usm_ndarray):
raise TypeError(f"Expected dpnp.tensor.usm_ndarray, got {type(x)}")

Expand Down Expand Up @@ -77,37 +77,48 @@ def _boolean_reduction(x, axis, keepdims, func):
exec_q = x.sycl_queue
res_usm_type = x.usm_type

_manager = du.SequentialOrderManager[exec_q]
dep_evs = _manager.submitted_events
# always allocate the temporary as
# int32 and usm-device to ensure that atomic updates
# are supported
res_tmp = dpt.empty(
res_shape,
dtype=dpt.int32,
usm_type="device",
sycl_queue=exec_q,
)
hev0, ev0 = func(
src=x_tmp,
trailing_dims_to_reduce=red_nd,
dst=res_tmp,
sycl_queue=exec_q,
depends=dep_evs,
)
_manager.add_event_pair(hev0, ev0)

# copy to boolean result array
res = dpt.empty(
res_shape,
dtype=dpt.bool,
usm_type=res_usm_type,
sycl_queue=exec_q,
)
hev1, ev1 = ti._copy_usm_ndarray_into_usm_ndarray(
src=res_tmp, dst=res, sycl_queue=exec_q, depends=[ev0]
)
_manager.add_event_pair(hev1, ev1)
if x_tmp.size == 0:
# nothing to reduce over: the result is either empty (a non-reduced
# dimension is zero) or filled with the reduction identity (a reduced
# dimension is zero, e.g. all([]) is True and any([]) is False)
res = dpt.full(
res_shape,
identity,
dtype=dpt.bool,
usm_type=res_usm_type,
sycl_queue=exec_q,
)
else:
_manager = du.SequentialOrderManager[exec_q]
dep_evs = _manager.submitted_events
# always allocate the temporary as int32 and usm-device to ensure
# that atomic updates are supported
res_tmp = dpt.empty(
res_shape,
dtype=dpt.int32,
usm_type="device",
sycl_queue=exec_q,
)
hev0, ev0 = func(
src=x_tmp,
trailing_dims_to_reduce=red_nd,
dst=res_tmp,
sycl_queue=exec_q,
depends=dep_evs,
)
_manager.add_event_pair(hev0, ev0)

# copy to boolean result array
res = dpt.empty(
res_shape,
dtype=dpt.bool,
usm_type=res_usm_type,
sycl_queue=exec_q,
)
hev1, ev1 = ti._copy_usm_ndarray_into_usm_ndarray(
src=res_tmp, dst=res, sycl_queue=exec_q, depends=[ev0]
)
_manager.add_event_pair(hev1, ev1)

if keepdims:
res_shape = res_shape + (1,) * red_nd
Expand Down Expand Up @@ -142,7 +153,7 @@ def all(x, /, *, axis=None, keepdims=False):
An array with a data type of `bool`
containing the results of the logical AND reduction.
"""
return _boolean_reduction(x, axis, keepdims, tri._all)
return _boolean_reduction(x, axis, keepdims, tri._all, True)


def any(x, /, *, axis=None, keepdims=False):
Expand Down Expand Up @@ -171,7 +182,7 @@ def any(x, /, *, axis=None, keepdims=False):
An array with a data type of `bool`
containing the results of the logical OR reduction.
"""
return _boolean_reduction(x, axis, keepdims, tri._any)
return _boolean_reduction(x, axis, keepdims, tri._any, False)


def _validate_diff_shape(sh1, sh2, axis):
Expand Down
Loading