From a2b534a31514a40e81e82b3ab5e6788b30546ee8 Mon Sep 17 00:00:00 2001 From: Natalia Polina Date: Tue, 10 Oct 2023 19:06:20 -0500 Subject: [PATCH 1/2] Implemented dpnp.tile function. --- dpnp/dpnp_iface_manipulation.py | 77 +++++++++++++++++++++++++++++++++ tests/skipped_tests.tbl | 8 ---- tests/skipped_tests_gpu.tbl | 8 ---- 3 files changed, 77 insertions(+), 16 deletions(-) diff --git a/dpnp/dpnp_iface_manipulation.py b/dpnp/dpnp_iface_manipulation.py index a9de67e965b5..9f8ffa2c5388 100644 --- a/dpnp/dpnp_iface_manipulation.py +++ b/dpnp/dpnp_iface_manipulation.py @@ -73,6 +73,7 @@ "squeeze", "stack", "swapaxes", + "tile", "transpose", "unique", "vstack", @@ -1332,6 +1333,82 @@ def swapaxes(a, axis1, axis2): ) +def tile(A, reps): + """ + Construct an array by repeating `A` the number of times given by reps. + + If `reps` has length ``d``, the result will have dimension of + ``max(d, A.ndim)``. + + If ``A.ndim < d``, `A` is promoted to be d-dimensional by prepending new + axes. So a shape (3,) array is promoted to (1, 3) for 2-D replication, + or shape (1, 1, 3) for 3-D replication. If this is not the desired + behavior, promote `A` to d-dimensions manually before calling this + function. + + If ``A.ndim > d``, `reps` is promoted to `A`.ndim by prepending 1's to it. + Thus for an `A` of shape (2, 3, 4, 5), a `reps` of (2, 2) is treated as + (1, 1, 2, 2). + + Note : Although tile may be used for broadcasting, it is strongly + recommended to use numpy's broadcasting operations and functions. + + Parameters + ---------- + A : dpnp_array + The input array. + reps : array_like + The number of repetitions of `A` along each axis. + + Returns + ------- + c : dpnp_array + The tiled output array. + + See Also + -------- + :obj:`dpnp.repeat` : Repeat elements of an array. + :obj:`dpnp.broadcast_to` : Broadcast an array to a new shape + + Examples + -------- + >>> import dpnp as np + >>> a = np.array([0, 1, 2]) + >>> np.tile(a, 2) + array([0, 1, 2, 0, 1, 2]) + + >>> np.tile(a, (2, 2)) + array([[0, 1, 2, 0, 1, 2], + [0, 1, 2, 0, 1, 2]]) + + >>> np.tile(a, (2, 1, 2)) + array([[[0, 1, 2, 0, 1, 2]], + [[0, 1, 2, 0, 1, 2]]]) + + >>> b = np.array([[1, 2], [3, 4]]) + >>> np.tile(b, 2) + array([[1, 2, 1, 2], + [3, 4, 3, 4]]) + + >>> np.tile(b, (2, 1)) + array([[1, 2], + [3, 4], + [1, 2], + [3, 4]]) + + >>> c = np.array([1, 2, 3, 4]) + >>> np.tile(c, (4, 1)) + array([[1, 2, 3, 4], + [1, 2, 3, 4], + [1, 2, 3, 4], + [1, 2, 3, 4]]) + + """ + + dpt_array = dpnp.get_usm_ndarray(A) + return dpnp_array._create_from_usm_ndarray(dpt.tile(dpt_array, reps)) + + def transpose(a, axes=None): """ Returns an array with axes transposed. diff --git a/tests/skipped_tests.tbl b/tests/skipped_tests.tbl index ccf926dc7700..62a244843a2e 100644 --- a/tests/skipped_tests.tbl +++ b/tests/skipped_tests.tbl @@ -472,14 +472,6 @@ tests/third_party/cupy/manipulation_tests/test_shape.py::TestReshape::test_resha tests/third_party/cupy/manipulation_tests/test_tiling.py::TestRepeatRepeatsNdarray::test_func tests/third_party/cupy/manipulation_tests/test_tiling.py::TestRepeatRepeatsNdarray::test_method -tests/third_party/cupy/manipulation_tests/test_tiling.py::TestTileFailure_param_0_{reps=-1}::test_tile_failure -tests/third_party/cupy/manipulation_tests/test_tiling.py::TestTileFailure_param_1_{reps=(-1, -2)}::test_tile_failure -tests/third_party/cupy/manipulation_tests/test_tiling.py::TestTile_param_0_{reps=0}::test_array_tile -tests/third_party/cupy/manipulation_tests/test_tiling.py::TestTile_param_1_{reps=1}::test_array_tile -tests/third_party/cupy/manipulation_tests/test_tiling.py::TestTile_param_2_{reps=2}::test_array_tile -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/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_465_{arg1=array([[1, 2, 3], [4, 5, 6]], dtype=int32), arg2=array([[0, 1, 2], [3, 4, 5]]), dtype=float64, name='fmod', use_dtype=False}::test_binary tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticBinary2_param_537_{arg1=array([[1, 2, 3], [4, 5, 6]]), arg2=array([[0, 1, 2], [3, 4, 5]], dtype=int32), dtype=float64, name='fmod', use_dtype=False}::test_binary diff --git a/tests/skipped_tests_gpu.tbl b/tests/skipped_tests_gpu.tbl index e36491861a48..6a105b50cba5 100644 --- a/tests/skipped_tests_gpu.tbl +++ b/tests/skipped_tests_gpu.tbl @@ -612,14 +612,6 @@ tests/third_party/cupy/manipulation_tests/test_shape.py::TestReshape::test_resha tests/third_party/cupy/manipulation_tests/test_tiling.py::TestRepeatRepeatsNdarray::test_func tests/third_party/cupy/manipulation_tests/test_tiling.py::TestRepeatRepeatsNdarray::test_method -tests/third_party/cupy/manipulation_tests/test_tiling.py::TestTileFailure_param_0_{reps=-1}::test_tile_failure -tests/third_party/cupy/manipulation_tests/test_tiling.py::TestTileFailure_param_1_{reps=(-1, -2)}::test_tile_failure -tests/third_party/cupy/manipulation_tests/test_tiling.py::TestTile_param_0_{reps=0}::test_array_tile -tests/third_party/cupy/manipulation_tests/test_tiling.py::TestTile_param_1_{reps=1}::test_array_tile -tests/third_party/cupy/manipulation_tests/test_tiling.py::TestTile_param_2_{reps=2}::test_array_tile -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/math_tests/test_arithmetic.py::TestArithmeticRaisesWithNumpyInput_param_3_{name='angle', nargs=1}::test_raises_with_numpy_input From 5a821f3a2f39cc41b77bea6e69f5c7523e557d6c Mon Sep 17 00:00:00 2001 From: Natalia Polina Date: Wed, 11 Oct 2023 12:02:09 -0500 Subject: [PATCH 2/2] address comments --- dpnp/dpnp_iface_manipulation.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/dpnp/dpnp_iface_manipulation.py b/dpnp/dpnp_iface_manipulation.py index 9f8ffa2c5388..a4c78630c6d3 100644 --- a/dpnp/dpnp_iface_manipulation.py +++ b/dpnp/dpnp_iface_manipulation.py @@ -891,7 +891,7 @@ def reshape(a, /, newshape, order="C", copy=None): Parameters ---------- - a : {dpnp_array, usm_ndarray} + a : {dpnp.ndarray, usm_ndarray} Array to be reshaped. newshape : int or tuple of ints The new shape should be compatible with the original shape. If @@ -1351,18 +1351,20 @@ def tile(A, reps): (1, 1, 2, 2). Note : Although tile may be used for broadcasting, it is strongly - recommended to use numpy's broadcasting operations and functions. + recommended to use dpnp's broadcasting operations and functions. + + For full documentation refer to :obj:`numpy.tile`. Parameters ---------- - A : dpnp_array + A : dpnp.ndarray The input array. reps : array_like The number of repetitions of `A` along each axis. Returns ------- - c : dpnp_array + c : dpnp.ndarray The tiled output array. See Also