Skip to content

Commit

Permalink
dpnp.unique returns reshaped unique_inverse when axis is None (#1999
Browse files Browse the repository at this point in the history
)

* Remove alias on numpy.complex_

* Remove alias on numpy.cfloat

* Remove alias on numpy.float and numpy.float_

* Remove alias on numpy.float and numpy.singlecomplex

* Remove aliases on numpy.Inf, numpy.Infinity and numpy.infty constants

* Get rid of dpnp.float in the code

* Remove aliases on numpy.NAN and numpy.NaN constants

* Remove aliases on numpy.NINF and numpy.PINF constants

* Remove aliases on numpy.NZERO and numpy.PZERO constants

* Remove use of removed numpy.longcomplex dtype

* Use proper import of numpy exceptions

* Applied pre-commit hooks

* Remove dpnp.issubsctype per numpy 2.0 migration guide

* Skip tests for asfarray with numpy 2.0

* Mute CFD relating tests

* Applied pre-commit hooks

* Add skip fixture in test_arraymanipulation.py::test_asfarray2

* Mute tests for new umaths from numpy 2.0

* dpnp.unique returns reshaped unique_inverse

* Corrected note sentense

* Update test_sycl_queue.py::test_unique
  • Loading branch information
antonwolfy authored Aug 19, 2024
1 parent 202bc1e commit 5c9752b
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 4 deletions.
7 changes: 6 additions & 1 deletion dpnp/dpnp_iface_manipulation.py
Original file line number Diff line number Diff line change
Expand Up @@ -2229,6 +2229,12 @@ def unique(
This is done by making the specified axis the first dimension of the array
(move the axis to the first dimension to keep the order of the other axes)
and then flattening the subarrays in C order.
For complex arrays all NaN values are considered equivalent (no matter
whether the NaN is in the real or imaginary part). As the representant for
the returned array the smallest one in the lexicographical order is chosen.
For multi-dimensional inputs, `unique_inverse` is reshaped such that the
input can be reconstructed using
``dpnp.take(unique, unique_inverse, axis=axis)``.
Examples
--------
Expand Down Expand Up @@ -2272,7 +2278,6 @@ def unique(
"""

if axis is None:
ar = dpnp.ravel(ar)
return _unique_1d(
ar, return_index, return_inverse, return_counts, equal_nan
)
Expand Down
27 changes: 27 additions & 0 deletions tests/test_manipulation.py
Original file line number Diff line number Diff line change
Expand Up @@ -629,6 +629,17 @@ def test_2d_axis(self, dt, axis_kwd, return_kwds):
if len(return_kwds) == 0:
assert_array_equal(result, expected)
else:
if (
len(axis_kwd) == 0
and numpy.lib.NumpyVersion(numpy.__version__) < "2.0.1"
):
# gh-26961: numpy.unique(..., return_inverse=True, axis=None)
# returned flatten unique_inverse till 2.0.1 version
expected = (
expected[:2]
+ (expected[2].reshape(a.shape),)
+ expected[3:]
)
for iv, v in zip(result, expected):
assert_array_equal(iv, v)

Expand Down Expand Up @@ -665,6 +676,11 @@ def test_2d_axis_inverse(self, axis):

result = dpnp.unique(ia, return_inverse=True, axis=axis)
expected = numpy.unique(a, return_inverse=True, axis=axis)
if axis is None and numpy.lib.NumpyVersion(numpy.__version__) < "2.0.1":
# gh-26961: numpy.unique(..., return_inverse=True, axis=None)
# returned flatten unique_inverse till 2.0.1 version
expected = expected[:1] + (expected[1].reshape(a.shape),)

for iv, v in zip(result, expected):
assert_array_equal(iv, v)

Expand Down Expand Up @@ -776,5 +792,16 @@ def test_2d_axis_nans(self, dt, axis_kwd, return_kwds, row):
if len(return_kwds) == 0:
assert_array_equal(result, expected)
else:
if (
len(axis_kwd) == 0
and numpy.lib.NumpyVersion(numpy.__version__) < "2.0.1"
):
# gh-26961: numpy.unique(..., return_inverse=True, axis=None)
# returned flatten unique_inverse till 2.0.1 version
expected = (
expected[:2]
+ (expected[2].reshape(a.shape),)
+ expected[3:]
)
for iv, v in zip(result, expected):
assert_array_equal(iv, v)
4 changes: 4 additions & 0 deletions tests/test_sycl_queue.py
Original file line number Diff line number Diff line change
Expand Up @@ -2408,6 +2408,10 @@ def test_unique(axis, device):

result = dpnp.unique(ia, True, True, True, axis=axis)
expected = numpy.unique(a, True, True, True, axis=axis)
if axis is None and numpy.lib.NumpyVersion(numpy.__version__) < "2.0.1":
# gh-26961: numpy.unique(..., return_inverse=True, axis=None)
# returned flatten unique_inverse till 2.0.1 version
expected = expected[:2] + (expected[2].reshape(a.shape),) + expected[3:]
for iv, v in zip(result, expected):
assert_array_equal(iv, v)

Expand Down
21 changes: 18 additions & 3 deletions tests/third_party/cupy/manipulation_tests/test_add_remove.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,12 @@ def test_unique_index(self, xp, dtype):
@testing.numpy_cupy_array_equal()
def test_unique_inverse_no_axis(self, xp, dtype):
a = testing.shaped_random((100, 100), xp, dtype)
return xp.unique(a, return_inverse=True)[1]
result = xp.unique(a, return_inverse=True)[1]
if xp is numpy and numpy.lib.NumpyVersion(numpy.__version__) < "2.0.1":
# gh-26961: numpy.unique(..., return_inverse=True, axis=None)
# returned flatten unique_inverse till 2.0.1 version
result = result.reshape(a.shape)
return result

@testing.for_all_dtypes(no_float16=True, no_bool=True, no_complex=True)
@testing.numpy_cupy_array_equal()
Expand All @@ -208,9 +213,14 @@ def test_unique_counts(self, xp, dtype):
@testing.numpy_cupy_array_equal()
def test_unique_return_all_no_axis(self, xp, dtype):
a = testing.shaped_random((100, 100), xp, dtype)
return xp.unique(
result = xp.unique(
a, return_index=True, return_inverse=True, return_counts=True
)
if xp is numpy and numpy.lib.NumpyVersion(numpy.__version__) < "2.0.1":
# gh-26961: numpy.unique(..., return_inverse=True, axis=None)
# returned flatten unique_inverse till 2.0.1 version
result = result[:2] + (result[2].reshape(a.shape),) + result[3:]
return result

@testing.for_all_dtypes(no_float16=True, no_bool=True, no_complex=True)
@testing.numpy_cupy_array_equal()
Expand Down Expand Up @@ -240,9 +250,14 @@ def test_unique_empty(self, xp, dtype):
@testing.numpy_cupy_array_equal()
def test_unique_empty_return_all_no_axis(self, xp, dtype):
a = xp.empty((3, 0, 2), dtype=dtype)
return xp.unique(
result = xp.unique(
a, return_index=True, return_inverse=True, return_counts=True
)
if xp is numpy and numpy.lib.NumpyVersion(numpy.__version__) < "2.0.1":
# gh-26961: numpy.unique(..., return_inverse=True, axis=None)
# returned flatten unique_inverse till 2.0.1 version
result = result[:2] + (result[2].reshape(a.shape),) + result[3:]
return result

@testing.for_all_dtypes(no_float16=True, no_bool=True, no_complex=True)
@testing.numpy_cupy_array_equal()
Expand Down

0 comments on commit 5c9752b

Please sign in to comment.