Skip to content
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

Reuse dpctl.tensor.moveaxis for dpnp.moveaxis #1382

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
41 changes: 15 additions & 26 deletions dpnp/dpnp_iface_manipulation.py
Original file line number Diff line number Diff line change
Expand Up @@ -388,17 +388,25 @@ def hstack(tup):
return call_origin(numpy.hstack, tup_new)


def moveaxis(x1, source, destination):
def moveaxis(x, source, destination):
"""
Move axes of an array to new positions. Other axes remain in their original order.

For full documentation refer to :obj:`numpy.moveaxis`.

Returns
-------
out : dpnp.ndarray
Array with moved axes.
The returned array must has the same data type as `x`,
is created on the same device as `x` and has the same
USM allocation type as `x`.
antonwolfy marked this conversation as resolved.
Show resolved Hide resolved

Limitations
-----------
Input array ``x1`` is supported as :obj:`dpnp.ndarray`.
Parameters `x` is supported as either :class:`dpnp.ndarray`
or :class:`dpctl.tensor.usm_ndarray`.
Otherwise the function will be executed sequentially on CPU.
Sizes of normalized input arrays are supported to be equal.
Input array data types are limited by supported DPNP :ref:`Data types`.

See Also
Expand All @@ -417,30 +425,11 @@ def moveaxis(x1, source, destination):

"""

x1_desc = dpnp.get_dpnp_descriptor(x1, copy_when_nondefault_queue=False)
if x1_desc:
source_norm = normalize_axis(source, x1_desc.ndim)
destination_norm = normalize_axis(destination, x1_desc.ndim)

if len(source_norm) != len(destination_norm):
pass
else:
# 'do nothing' pattern for transpose() with no elements in 'source'
input_permute = []
for i in range(x1_desc.ndim):
if i not in source_norm:
input_permute.append(i)

# insert moving axes into proper positions
for destination_id, source_id in sorted(zip(destination_norm, source_norm)):
# if destination_id in input_permute:
# pytest tests/third_party/cupy/manipulation_tests/test_transpose.py::TestTranspose::test_moveaxis_invalid5_3
# checker_throw_value_error("swapaxes", "source_id exists", source_id, input_permute)
input_permute.insert(destination_id, source_id)

return transpose(x1_desc.get_pyobj(), axes=input_permute)
if isinstance(x, dpnp_array) or isinstance(x, dpt.usm_ndarray):
dpt_array = x.get_array() if isinstance(x, dpnp_array) else x
return dpnp_array._create_from_usm_ndarray(dpt.moveaxis(dpt_array, source, destination))

return call_origin(numpy.moveaxis, x1, source, destination)
return call_origin(numpy.moveaxis, x, source, destination)


def ravel(x1, order='C'):
Expand Down
2 changes: 0 additions & 2 deletions tests/skipped_tests.tbl
Original file line number Diff line number Diff line change
Expand Up @@ -747,8 +747,6 @@ tests/third_party/cupy/manipulation_tests/test_tiling.py::TestTile_param_2_{reps
tests/third_party/cupy/manipulation_tests/test_tiling.py::TestTile_param_3_{reps=(0, 1)}::test_array_tile
tests/third_party/cupy/manipulation_tests/test_tiling.py::TestTile_param_4_{reps=(2, 3)}::test_array_tile
tests/third_party/cupy/manipulation_tests/test_tiling.py::TestTile_param_5_{reps=(2, 3, 4, 5)}::test_array_tile
tests/third_party/cupy/manipulation_tests/test_transpose.py::TestTranspose::test_moveaxis_invalid5_2
tests/third_party/cupy/manipulation_tests/test_transpose.py::TestTranspose::test_moveaxis_invalid5_3
tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticBinary2_param_455_{arg1=array([[1, 2, 3], [4, 5, 6]], dtype=int32), arg2=array([[0, 1, 2], [3, 4, 5]], dtype=int32), dtype=float64, name='floor_divide', use_dtype=False}::test_binary
tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticBinary2_param_457_{arg1=array([[1, 2, 3], [4, 5, 6]], dtype=int32), arg2=array([[0, 1, 2], [3, 4, 5]], dtype=int32), dtype=float64, name='fmod', use_dtype=False}::test_binary
tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticBinary2_param_459_{arg1=array([[1, 2, 3], [4, 5, 6]], dtype=int32), arg2=array([[0, 1, 2], [3, 4, 5]], dtype=int32), dtype=float64, name='remainder', use_dtype=False}::test_binary
Expand Down
2 changes: 0 additions & 2 deletions tests/skipped_tests_gpu.tbl
Original file line number Diff line number Diff line change
Expand Up @@ -908,8 +908,6 @@ tests/third_party/cupy/manipulation_tests/test_tiling.py::TestTile_param_2_{reps
tests/third_party/cupy/manipulation_tests/test_tiling.py::TestTile_param_3_{reps=(0, 1)}::test_array_tile
tests/third_party/cupy/manipulation_tests/test_tiling.py::TestTile_param_4_{reps=(2, 3)}::test_array_tile
tests/third_party/cupy/manipulation_tests/test_tiling.py::TestTile_param_5_{reps=(2, 3, 4, 5)}::test_array_tile
tests/third_party/cupy/manipulation_tests/test_transpose.py::TestTranspose::test_moveaxis_invalid5_2
tests/third_party/cupy/manipulation_tests/test_transpose.py::TestTranspose::test_moveaxis_invalid5_3

tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticBinary2_param_279_{arg1=array([[1., 2., 3.], [4., 5., 6.]], dtype=float32), arg2=array([[0., 1., 2.], [3., 4., 5.]], dtype=float32), dtype=float64, name='floor_divide', use_dtype=False}::test_binary
tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticBinary2_param_287_{arg1=array([[1., 2., 3.], [4., 5., 6.]], dtype=float32), arg2=array([[0., 1., 2.], [3., 4., 5.]]), dtype=float64, name='floor_divide', use_dtype=False}::test_binary
Expand Down
7 changes: 0 additions & 7 deletions tests/third_party/cupy/manipulation_tests/test_transpose.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,53 +41,46 @@ def test_moveaxis6(self, xp):
return xp.moveaxis(a, [0, 2, 1], [3, 4, 0])

# dim is too large
@pytest.mark.usefixtures("allow_fall_back_on_numpy")
def test_moveaxis_invalid1_1(self):
for xp in (numpy, cupy):
a = testing.shaped_arange((2, 3, 4), xp)
with pytest.raises(numpy.AxisError):
xp.moveaxis(a, [0, 1], [1, 3])

@pytest.mark.usefixtures("allow_fall_back_on_numpy")
def test_moveaxis_invalid1_2(self):
for xp in (numpy, cupy):
a = testing.shaped_arange((2, 3, 4), xp)
with pytest.raises(numpy.AxisError):
xp.moveaxis(a, [0, 1], [1, 3])

# dim is too small
@pytest.mark.usefixtures("allow_fall_back_on_numpy")
def test_moveaxis_invalid2_1(self):
for xp in (numpy, cupy):
a = testing.shaped_arange((2, 3, 4), xp)
with pytest.raises(numpy.AxisError):
xp.moveaxis(a, [0, -4], [1, 2])

@pytest.mark.usefixtures("allow_fall_back_on_numpy")
def test_moveaxis_invalid2_2(self):
for xp in (numpy, cupy):
a = testing.shaped_arange((2, 3, 4), xp)
with pytest.raises(numpy.AxisError):
xp.moveaxis(a, [0, -4], [1, 2])

# len(source) != len(destination)
@pytest.mark.usefixtures("allow_fall_back_on_numpy")
def test_moveaxis_invalid3(self):
for xp in (numpy, cupy):
a = testing.shaped_arange((2, 3, 4), xp)
with pytest.raises(ValueError):
xp.moveaxis(a, [0, 1, 2], [1, 2])

# len(source) != len(destination)
@pytest.mark.usefixtures("allow_fall_back_on_numpy")
def test_moveaxis_invalid4(self):
for xp in (numpy, cupy):
a = testing.shaped_arange((2, 3, 4), xp)
with pytest.raises(ValueError):
xp.moveaxis(a, [0, 1], [1, 2, 0])

# Use the same axis twice
@pytest.mark.usefixtures("allow_fall_back_on_numpy")
def test_moveaxis_invalid5_1(self):
for xp in (numpy, cupy):
a = testing.shaped_arange((2, 3, 4), xp)
Expand Down