Skip to content

Align with numpy 2.2 #2226

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Dec 9, 2024
Merged
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
23 changes: 8 additions & 15 deletions dpnp/dpnp_iface_manipulation.py
Original file line number Diff line number Diff line change
Expand Up @@ -2170,11 +2170,12 @@ def insert(arr, obj, values, axis=None):
----------
arr : array_like
Input array.
obj : {slice, int, array-like of ints}
obj : {slice, int, array-like of ints or bools}
Object that defines the index or indices before which `values` is
inserted. It supports multiple insertions when `obj` is a single
scalar or a sequence with one element (similar to calling insert
multiple times).
Boolean indices are treated as a mask of elements to insert.
values : array_like
Values to insert into `arr`. If the type of `values` is different
from that of `arr`, `values` is converted to the type of `arr`.
Expand Down Expand Up @@ -2266,20 +2267,12 @@ def insert(arr, obj, values, axis=None):
obj, sycl_queue=params.exec_q, usm_type=params.usm_type
)
if indices.dtype == dpnp.bool:
warnings.warn(
"In the future insert will treat boolean arrays and array-likes"
" as a boolean index instead of casting it to integers",
FutureWarning,
stacklevel=2,
)
indices = indices.astype(dpnp.intp)
# TODO: Code after warning period:
# if indices.ndim != 1:
# raise ValueError(
# "boolean array argument `obj` to insert must be "
# "one-dimensional"
# )
# indices = dpnp.nonzero(indices)[0]
if indices.ndim != 1:
raise ValueError(
"boolean array argument obj to insert "
"must be one dimensional"
)
indices = dpnp.flatnonzero(indices)
elif indices.ndim > 1:
raise ValueError(
"index array argument `obj` to insert must be one-dimensional "
Expand Down
2 changes: 1 addition & 1 deletion dpnp/dpnp_utils/dpnp_utils_statistics.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ def _get_2dmin_array(x, dtype):
elif x.ndim == 1:
x = x[dpnp.newaxis, :]

if not rowvar and x.shape[0] != 1:
if not rowvar and x.ndim != 1:
x = x.T

if x.dtype != dtype:
Expand Down
31 changes: 28 additions & 3 deletions dpnp/tests/test_manipulation.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@
import numpy
import pytest
from dpctl.tensor._numpy_helper import AxisError
from numpy.testing import assert_array_equal, assert_equal, assert_raises
from numpy.testing import (
assert_array_equal,
assert_equal,
assert_raises,
)

import dpnp

Expand Down Expand Up @@ -573,16 +577,34 @@ def test_ndarray_obj_values(self, obj, values):
result = dpnp.insert(ia, obj, values)
assert_equal(result, expected)

@pytest.mark.filterwarnings("ignore::FutureWarning")
@testing.with_requires("numpy>=2.2")
@pytest.mark.parametrize(
"obj",
[True, [False], numpy.array([True] * 4), [True, False, True, False]],
[[False], numpy.array([True] * 4), [True, False, True, False]],
)
def test_boolean_obj(self, obj):
if not isinstance(obj, numpy.ndarray):
# numpy.insert raises exception
# TODO: remove once NumPy resolves that
obj = numpy.array(obj)

a = numpy.array([1, 2, 3])
ia = dpnp.array(a)
assert_equal(dpnp.insert(ia, obj, 9), numpy.insert(a, obj, 9))

@testing.with_requires("numpy>=2.2")
@pytest.mark.parametrize("xp", [dpnp, numpy])
@pytest.mark.parametrize(
"obj_data",
[True, [[True, False], [True, False]]],
ids=["0d", "2d"],
)
def test_boolean_obj_error(self, xp, obj_data):
a = xp.array([1, 2, 3])
obj = xp.array(obj_data)
with pytest.raises(ValueError):
xp.insert(a, obj, 9)

def test_1D_array(self):
a = numpy.array([1, 2, 3])
ia = dpnp.array(a)
Expand Down Expand Up @@ -1394,6 +1416,9 @@ def test_overflow(self, a):
expected = numpy.trim_zeros(a)
assert_array_equal(result, expected)

# TODO: modify once SAT-7616
# numpy 2.2 validates trim rules
@testing.with_requires("numpy<2.2")
def test_trim_no_rule(self):
a = numpy.array([0, 0, 1, 0, 2, 3, 4, 0])
ia = dpnp.array(a)
Expand Down
46 changes: 31 additions & 15 deletions dpnp/tests/test_statistics.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
get_float_complex_dtypes,
has_support_aspect64,
)
from .third_party.cupy.testing import with_requires


class TestAverage:
Expand Down Expand Up @@ -682,23 +683,38 @@ def test_correlate_another_sycl_queue(self):
dpnp.correlate(a, v)


@pytest.mark.parametrize(
"dtype", get_all_dtypes(no_bool=True, no_none=True, no_complex=True)
)
def test_cov_rowvar(dtype):
a = dpnp.array([[0, 2], [1, 1], [2, 0]], dtype=dtype)
b = numpy.array([[0, 2], [1, 1], [2, 0]], dtype=dtype)
assert_allclose(dpnp.cov(a.T), dpnp.cov(a, rowvar=False))
assert_allclose(numpy.cov(b, rowvar=False), dpnp.cov(a, rowvar=False))
class TestCov:
@pytest.mark.parametrize(
"dtype", get_all_dtypes(no_bool=True, no_none=True, no_complex=True)
)
def test_false_rowvar_dtype(self, dtype):
a = numpy.array([[0, 2], [1, 1], [2, 0]], dtype=dtype)
ia = dpnp.array(a)

assert_allclose(dpnp.cov(ia.T), dpnp.cov(ia, rowvar=False))
assert_allclose(dpnp.cov(ia, rowvar=False), numpy.cov(a, rowvar=False))

@pytest.mark.parametrize(
"dtype", get_all_dtypes(no_bool=True, no_none=True, no_complex=True)
)
def test_cov_1D_rowvar(dtype):
a = dpnp.array([[0, 1, 2]], dtype=dtype)
b = numpy.array([[0, 1, 2]], dtype=dtype)
assert_allclose(numpy.cov(b, rowvar=False), dpnp.cov(a, rowvar=False))
# numpy 2.2 properly transposes 2d array when rowvar=False
@with_requires("numpy>=2.2")
@pytest.mark.filterwarnings("ignore::RuntimeWarning")
def test_false_rowvar_1x3(self):
a = numpy.array([[0, 1, 2]])
ia = dpnp.array(a)

expected = numpy.cov(a, rowvar=False)
result = dpnp.cov(ia, rowvar=False)
assert_allclose(expected, result)

# numpy 2.2 properly transposes 2d array when rowvar=False
@with_requires("numpy>=2.2")
@pytest.mark.usefixtures("allow_fall_back_on_numpy")
def test_true_rowvar(self):
a = numpy.ones((3, 1))
ia = dpnp.array(a)

expected = numpy.cov(a, ddof=0, rowvar=True)
result = dpnp.cov(ia, ddof=0, rowvar=True)
assert_allclose(expected, result)


@pytest.mark.parametrize("axis", [None, 0, 1])
Expand Down
5 changes: 3 additions & 2 deletions dpnp/tests/test_umath.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,10 @@ def get_id(val):


# implement missing umaths and to remove the list
# SAT-7323 bitwise_count
new_umaths_numpy_20 = [
"bitwise_count",
"bitwise_count", # SAT-7323
"matvec", # SAT-7615
"vecmat", # SAT-7615
]


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -387,13 +387,17 @@ def test_trim_back_zeros(self, xp, dtype):
a = xp.array([1, 0, 2, 3, 0, 5, 0, 0, 0], dtype=dtype)
return xp.trim_zeros(a, trim=self.trim)

# TODO: remove once SAT-7616
@testing.with_requires("numpy<2.2")
@testing.for_all_dtypes()
def test_trim_zero_dim(self, dtype):
for xp in (numpy, cupy):
a = testing.shaped_arange((), xp, dtype)
with pytest.raises(TypeError):
xp.trim_zeros(a, trim=self.trim)

# TODO: remove once SAT-7616
@testing.with_requires("numpy<2.2")
@testing.for_all_dtypes()
def test_trim_ndim(self, dtype):
for xp in (numpy, cupy):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import pytest

import dpnp as cupy
from dpnp.tests.helper import has_support_aspect64
from dpnp.tests.helper import has_support_aspect64, numpy_version
from dpnp.tests.third_party.cupy import testing


Expand Down Expand Up @@ -127,10 +127,14 @@ def check_raises(
)

@pytest.mark.usefixtures("allow_fall_back_on_numpy")
@pytest.mark.filterwarnings("ignore::RuntimeWarning")
def test_cov(self):
self.check((2, 3))
self.check((2,), (2,))
self.check((1, 3), (1, 3), rowvar=False)
if numpy_version() >= "2.2.0":
# TODO: enable once numpy 2.2 resolves ValueError
# self.check((1, 3), (1, 3), rowvar=False)
self.check((1, 3), (1, 1), rowvar=False) # TODO: remove
self.check((2, 3), (2, 3), rowvar=False)
self.check((2, 3), bias=True)
self.check((2, 3), ddof=2)
Expand Down
Loading