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
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,22 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.22.0] - 2027-MM-DD

### Added

* Added support for boolean input in `dpnp.positive` and the `+` operator of `dpnp.ndarray` [#3128](https://github.com/IntelPython/dpnp/pull/3128)

### Changed

### Deprecated

### Removed

### Fixed

### Security

## [0.21.0] - 2026-MM-DD

This release achieves 100% compliance with Python Array API specification (revision [2025.12](https://data-apis.org/array-api/2025.12/)).
Expand Down
12 changes: 0 additions & 12 deletions dpnp/dpnp_algo/dpnp_elementwise_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,6 @@
"DPNPUnaryTwoOutputsFunc",
"acceptance_fn_gcd_lcm",
"acceptance_fn_negative",
"acceptance_fn_positive",
"acceptance_fn_sign",
"acceptance_fn_subtract",
"resolve_weak_types_2nd_arg_int",
Expand Down Expand Up @@ -1386,17 +1385,6 @@ def acceptance_fn_negative(arg_dtype, buf_dt, res_dt, sycl_dev):
return True


def acceptance_fn_positive(arg_dtype, buf_dt, res_dt, sycl_dev):
# positive is not defined for boolean data type
if arg_dtype.char == "?":
raise TypeError(
"The `positive` function is not supported for inputs of data type "
"bool"
)
else:
return True


def acceptance_fn_sign(arg_dtype, buf_dt, res_dt, sycl_dev):
# sign is not defined for boolean data type
if arg_dtype.char == "?":
Expand Down
25 changes: 20 additions & 5 deletions dpnp/dpnp_iface_mathematical.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@
DPNPUnaryTwoOutputsFunc,
acceptance_fn_gcd_lcm,
acceptance_fn_negative,
acceptance_fn_positive,
acceptance_fn_sign,
acceptance_fn_subtract,
resolve_weak_types_2nd_arg_int,
Expand Down Expand Up @@ -267,6 +266,23 @@ def _gradient_num_diff_edges(
)


def _positive(src, dst, sycl_queue, depends=None):
"""Call positive kernel, using abs one for boolean input."""

# dpnp.tensor.positive has no boolean loop, abs is identity on bool
if src.dtype.char == "?":
return ti._abs(src, dst, sycl_queue, depends)
return ti._positive(src, dst, sycl_queue, depends)


def _positive_result_type(dtype):
"""Get the result data type of positive, including boolean input."""

if dtype.char == "?":
return ti._abs_result_type(dtype)
return ti._positive_result_type(dtype)


def _process_ediff1d_args(arg, arg_name, ary_dtype, ary_sycl_queue, usm_type):
"""Process the argument for ediff1d."""
if not dpnp.is_supported_array_type(arg):
Expand Down Expand Up @@ -3901,7 +3917,7 @@ def _check_nan_inf(val, val_dt):
Parameters
----------
x : {dpnp.ndarray, usm_ndarray}
Input array, expected to have a numeric data type.
Input array, expected to have a boolean or numeric data type.
out : {None, dpnp.ndarray, usm_ndarray, tuple of ndarray}, optional
Output array to populate.
Array must have the correct shape and the expected data type.
Expand Down Expand Up @@ -3951,10 +3967,9 @@ def _check_nan_inf(val, val_dt):

positive = DPNPUnaryFunc(
"positive",
ti._positive_result_type,
ti._positive,
_positive_result_type,
_positive,
_POSITIVE_DOCSTRING,
acceptance_fn=acceptance_fn_positive,
)


Expand Down
23 changes: 10 additions & 13 deletions dpnp/tests/test_mathematical.py
Original file line number Diff line number Diff line change
Expand Up @@ -2376,32 +2376,29 @@ def test_negative_boolean():
@pytest.mark.parametrize(
"data", [[[1.0, -1.0], [0.1, -0.1]], [-2, -1, 0, 1, 2]], ids=["2D", "1D"]
)
@pytest.mark.parametrize("dtype", get_all_dtypes(no_none=True, no_bool=True))
@pytest.mark.parametrize("dtype", get_all_dtypes(no_none=True))
def test_positive(data, dtype):
a = get_abs_array(data, dtype=dtype)
ia = dpnp.array(a)

# numpy < 2.6 raises TypeError for boolean input
if dtype == dpnp.bool and numpy_version() < "2.6.0.dev0":
expected = a.copy()
else:
expected = numpy.positive(a)

result = dpnp.positive(ia)
expected = numpy.positive(a)
assert_allclose(result, expected)
assert_dtype_allclose(result, expected)

result = +ia
expected = +a
assert_allclose(result, expected)
assert_dtype_allclose(result, expected)

# out keyword
if dtype is not None:
iout = dpnp.empty(expected.shape, dtype=dtype)
result = dpnp.positive(ia, out=iout)
assert result is iout
assert_allclose(result, expected)


def test_positive_boolean():
ia = dpnp.array([True, False])

with pytest.raises(TypeError):
dpnp.positive(ia)
assert_dtype_allclose(result, expected)


@pytest.mark.parametrize("dtype", get_float_dtypes(no_float16=False))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ def test_pos_array(self, xp, dtype):
return +a

@pytest.mark.skip(
"dpnp boolean positive, the `+` operator, is not supported"
"dpnp boolean positive, the `+` operator, emits no DeprecationWarning"
)
@testing.with_requires("numpy<1.25")
def test_pos_boolarray(self):
Expand Down
Loading