From 7653448826a2f7fcad98d2521ace17fd473f31bf Mon Sep 17 00:00:00 2001 From: Natalia Polina Date: Mon, 28 Aug 2023 14:19:06 -0500 Subject: [PATCH 1/7] Implemented dpnp.hstack() and dpnp.atleast_1d() functions. --- dpnp/dpnp_iface_manipulation.py | 98 +++++++++++++++++++++++++++++++-- tests/test_arraymanipulation.py | 13 +++-- 2 files changed, 100 insertions(+), 11 deletions(-) diff --git a/dpnp/dpnp_iface_manipulation.py b/dpnp/dpnp_iface_manipulation.py index a7ce7fb560e5..909c89b5d59d 100644 --- a/dpnp/dpnp_iface_manipulation.py +++ b/dpnp/dpnp_iface_manipulation.py @@ -112,13 +112,51 @@ def atleast_1d(*arys): For full documentation refer to :obj:`numpy.atleast_1d`. - Limitations - ----------- - Input arrays is supported as :obj:`dpnp.ndarray`. + Parameters + ---------- + arys1, arys2, ... : array_like + One or more input arrays. + + Returns + ------- + out : ndarray + An array, or list of arrays, each with ``a.ndim >= 1``. + Copies are made only if necessary. + + See Also + -------- + atleast_2d, atleast_3d + + Examples + -------- + >>> np.atleast_1d(1.0) + array([1.]) + + >>> x = np.arange(9.0).reshape(3,3) + >>> np.atleast_1d(x) + array([[0., 1., 2.], + [3., 4., 5.], + [6., 7., 8.]]) + >>> np.atleast_1d(x) is x + True + + >>> np.atleast_1d(1, [3, 4]) + [array([1]), array([3, 4])] """ - return call_origin(numpy.atleast_1d, *arys) + res = [] + for ary in arys: + ary = dpnp.array(ary, copy=False) + if ary.ndim == 0: + result = ary.reshape(1) + else: + result = ary + res.append(result) + if len(res) == 1: + return res[0] + else: + return res def atleast_2d(*arys): @@ -476,14 +514,62 @@ def expand_dims(a, axis): ) -def hstack(tup): +def hstack(tup, *, dtype=None, casting="same_kind"): """ Stack arrays in sequence horizontally (column wise). For full documentation refer to :obj:`numpy.hstack`. + Returns + ------- + out : dpnp.ndarray + The stacked array which has one more dimension than the input arrays. + + Limitations + ----------- + Each array in `tup` is supported as either :class:`dpnp.ndarray` + or :class:`dpctl.tensor.usm_ndarray`. Otherwise ``TypeError`` exception + will be raised. + Parameters `dtype` and `casting` are supported with default value. + Otherwise the function will be executed sequentially on CPU. + + See Also + -------- + :obj:`dpnp.concatenate` : Join a sequence of arrays along an existing axis. + :obj:`dpnp.stack` : Join a sequence of arrays along a new axis. + :obj:`dpnp.block` : Assemble an nd-array from nested lists of blocks. + :obj:`dpnp.split` : Split array into a list of multiple sub-arrays of equal size. + + Examples + -------- + >>> import dpnp as np + >>> a = np.array((1,2,3)) + >>> b = np.array((4,5,6)) + >>> np.hstack((a,b)) + array([1, 2, 3, 4, 5, 6]) + >>> a = np.array([[1],[2],[3]]) + >>> b = np.array([[4],[5],[6]]) + >>> np.hstack((a,b)) + array([[1, 4], + [2, 5], + [3, 6]]) + """ + if casting != "same_kind": + pass + elif dtype is not None: + pass + else: + arrs = dpnp.atleast_1d(*tup) + if not isinstance(arrs, list): + arrs = [arrs] + # As a special case, dimension 0 of 1-dimensional arrays is "horizontal" + if arrs and arrs[0].ndim == 1: + return dpnp.concatenate(arrs, axis=0) + else: + return dpnp.concatenate(arrs, axis=1) + # TODO: # `call_origin` cannot convert sequence of array to sequence of # nparrays @@ -884,7 +970,7 @@ def stack(arrays, /, *, axis=0, out=None, dtype=None, **kwargs): Each array in `arrays` is supported as either :class:`dpnp.ndarray` or :class:`dpctl.tensor.usm_ndarray`. Otherwise ``TypeError`` exception will be raised. - Parameters `out` and `dtype are supported with default value. + Parameters `out` and `dtype` are supported with default value. Keyword argument ``kwargs`` is currently unsupported. Otherwise the function will be executed sequentially on CPU. diff --git a/tests/test_arraymanipulation.py b/tests/test_arraymanipulation.py index 94f54accbc78..2f87335b69ae 100644 --- a/tests/test_arraymanipulation.py +++ b/tests/test_arraymanipulation.py @@ -335,11 +335,9 @@ class TestHstack: def test_non_iterable(self): assert_raises(TypeError, dpnp.hstack, 1) - @pytest.mark.usefixtures("allow_fall_back_on_numpy") def test_empty_input(self): - assert_raises(ValueError, dpnp.hstack, ()) + assert_raises(TypeError, dpnp.hstack, ()) - @pytest.mark.usefixtures("allow_fall_back_on_numpy") def test_0D_array(self): b = dpnp.array(2) a = dpnp.array(1) @@ -347,7 +345,6 @@ def test_0D_array(self): desired = dpnp.array([1, 2]) assert_array_equal(res, desired) - @pytest.mark.usefixtures("allow_fall_back_on_numpy") def test_1D_array(self): a = dpnp.array([1]) b = dpnp.array([2]) @@ -355,7 +352,6 @@ def test_1D_array(self): desired = dpnp.array([1, 2]) assert_array_equal(res, desired) - @pytest.mark.usefixtures("allow_fall_back_on_numpy") def test_2D_array(self): a = dpnp.array([[1], [2]]) b = dpnp.array([[1], [2]]) @@ -605,3 +601,10 @@ def test_2D_array2(self): def test_generator(self): with assert_warns(FutureWarning): dpnp.vstack((numpy.arange(3) for _ in range(2))) + + +@pytest.mark.parametrize("arys", [1.0, dpnp.arange(9.0).reshape(3, 3), [3, 4]]) +def test_atleast_1d(arys): + expected = numpy.atleast_1d(arys) + result = dpnp.atleast_1d(arys) + assert_array_equal(result, expected) From 7423569ed9f2fc32fea684861744e8e90fb35303 Mon Sep 17 00:00:00 2001 From: Natalia Polina Date: Wed, 30 Aug 2023 10:08:27 -0500 Subject: [PATCH 2/7] Added tests for hstack and atleast_1d functions --- dpnp/dpnp_iface_manipulation.py | 44 ++++++++----------- tests/test_arraymanipulation.py | 41 ++++++++++++++--- .../cupy/manipulation_tests/test_dims.py | 2 - .../cupy/manipulation_tests/test_join.py | 7 +-- 4 files changed, 56 insertions(+), 38 deletions(-) diff --git a/dpnp/dpnp_iface_manipulation.py b/dpnp/dpnp_iface_manipulation.py index 909c89b5d59d..590511517c1f 100644 --- a/dpnp/dpnp_iface_manipulation.py +++ b/dpnp/dpnp_iface_manipulation.py @@ -114,12 +114,12 @@ def atleast_1d(*arys): Parameters ---------- - arys1, arys2, ... : array_like + arys : {dpnp_array, usm_ndarray} One or more input arrays. Returns ------- - out : ndarray + out : dpnp.ndarray An array, or list of arrays, each with ``a.ndim >= 1``. Copies are made only if necessary. @@ -129,6 +129,7 @@ def atleast_1d(*arys): Examples -------- + >>> import dpnp as np >>> np.atleast_1d(1.0) array([1.]) @@ -147,7 +148,7 @@ def atleast_1d(*arys): res = [] for ary in arys: - ary = dpnp.array(ary, copy=False) + ary = dpnp.asanyarray(ary) if ary.ndim == 0: result = ary.reshape(1) else: @@ -275,7 +276,9 @@ def broadcast_to(array, /, shape, subok=False): return call_origin(numpy.broadcast_to, array, shape=shape, subok=subok) -def concatenate(arrays, /, *, axis=0, out=None, dtype=None, **kwargs): +def concatenate( + arrays, /, *, axis=0, out=None, dtype=None, casting="same_kind", **kwargs +): """ Join a sequence of arrays along an existing axis. @@ -332,6 +335,8 @@ def concatenate(arrays, /, *, axis=0, out=None, dtype=None, **kwargs): pass elif dtype is not None: pass + elif casting != "same_kind": + pass else: usm_arrays = [dpnp.get_usm_ndarray(x) for x in arrays] usm_res = dpt.concat(usm_arrays, axis=axis) @@ -537,6 +542,7 @@ def hstack(tup, *, dtype=None, casting="same_kind"): -------- :obj:`dpnp.concatenate` : Join a sequence of arrays along an existing axis. :obj:`dpnp.stack` : Join a sequence of arrays along a new axis. + :obj:`dpnp.vstack` : Stack arrays in sequence vertically (row wise). :obj:`dpnp.block` : Assemble an nd-array from nested lists of blocks. :obj:`dpnp.split` : Split array into a list of multiple sub-arrays of equal size. @@ -547,6 +553,7 @@ def hstack(tup, *, dtype=None, casting="same_kind"): >>> b = np.array((4,5,6)) >>> np.hstack((a,b)) array([1, 2, 3, 4, 5, 6]) + >>> a = np.array([[1],[2],[3]]) >>> b = np.array([[4],[5],[6]]) >>> np.hstack((a,b)) @@ -556,29 +563,14 @@ def hstack(tup, *, dtype=None, casting="same_kind"): """ - if casting != "same_kind": - pass - elif dtype is not None: - pass + arrs = dpnp.atleast_1d(*tup) + if not isinstance(arrs, list): + arrs = [arrs] + # As a special case, dimension 0 of 1-dimensional arrays is "horizontal" + if arrs and arrs[0].ndim == 1: + return dpnp.concatenate(arrs, axis=0, dtype=dtype, casting=casting) else: - arrs = dpnp.atleast_1d(*tup) - if not isinstance(arrs, list): - arrs = [arrs] - # As a special case, dimension 0 of 1-dimensional arrays is "horizontal" - if arrs and arrs[0].ndim == 1: - return dpnp.concatenate(arrs, axis=0) - else: - return dpnp.concatenate(arrs, axis=1) - - # TODO: - # `call_origin` cannot convert sequence of array to sequence of - # nparrays - tup_new = [] - for tp in tup: - tpx = dpnp.asnumpy(tp) if not isinstance(tp, numpy.ndarray) else tp - tup_new.append(tpx) - - return call_origin(numpy.hstack, tup_new) + return dpnp.concatenate(arrs, axis=1, dtype=dtype, casting=casting) def moveaxis(a, source, destination): diff --git a/tests/test_arraymanipulation.py b/tests/test_arraymanipulation.py index 2f87335b69ae..44cd5a6f0d40 100644 --- a/tests/test_arraymanipulation.py +++ b/tests/test_arraymanipulation.py @@ -603,8 +603,39 @@ def test_generator(self): dpnp.vstack((numpy.arange(3) for _ in range(2))) -@pytest.mark.parametrize("arys", [1.0, dpnp.arange(9.0).reshape(3, 3), [3, 4]]) -def test_atleast_1d(arys): - expected = numpy.atleast_1d(arys) - result = dpnp.atleast_1d(arys) - assert_array_equal(result, expected) +class TestAtleast1d: + def test_0D_array(self): + a = dpnp.array(1) + b = dpnp.array(2) + res = [dpnp.atleast_1d(a), dpnp.atleast_1d(b)] + desired = [dpnp.array([1]), dpnp.array([2])] + assert_array_equal(res, desired) + + def test_1D_array(self): + a = dpnp.array([1, 2]) + b = dpnp.array([2, 3]) + res = [dpnp.atleast_1d(a), dpnp.atleast_1d(b)] + desired = [dpnp.array([1, 2]), dpnp.array([2, 3])] + assert_array_equal(res, desired) + + def test_2D_array(self): + a = dpnp.array([[1, 2], [1, 2]]) + b = dpnp.array([[2, 3], [2, 3]]) + res = [dpnp.atleast_1d(a), dpnp.atleast_1d(b)] + desired = [a, b] + assert_array_equal(res, desired) + + def test_3D_array(self): + a = dpnp.array([[1, 2], [1, 2]]) + b = dpnp.array([[2, 3], [2, 3]]) + a = dpnp.array([a, a]) + b = dpnp.array([b, b]) + res = [dpnp.atleast_1d(a), dpnp.atleast_1d(b)] + desired = [a, b] + assert_array_equal(res, desired) + + def test_r1array(self): + assert dpnp.atleast_1d(3).shape == (1,) + assert dpnp.atleast_1d(3j).shape == (1,) + assert dpnp.atleast_1d(3.0).shape == (1,) + assert dpnp.atleast_1d([[2, 3], [4, 5]]).shape == (2, 2) diff --git a/tests/third_party/cupy/manipulation_tests/test_dims.py b/tests/third_party/cupy/manipulation_tests/test_dims.py index 6d59f0640512..461c0bb2ec2b 100644 --- a/tests/third_party/cupy/manipulation_tests/test_dims.py +++ b/tests/third_party/cupy/manipulation_tests/test_dims.py @@ -18,12 +18,10 @@ def check_atleast(self, func, xp): f = numpy.float32(1) return func(a, b, c, d, e, f) - @pytest.mark.usefixtures("allow_fall_back_on_numpy") @testing.numpy_cupy_array_equal() def test_atleast_1d1(self, xp): return self.check_atleast(xp.atleast_1d, xp) - @pytest.mark.usefixtures("allow_fall_back_on_numpy") @testing.numpy_cupy_array_equal() def test_atleast_1d2(self, xp): a = testing.shaped_arange((1, 3, 2), xp) diff --git a/tests/third_party/cupy/manipulation_tests/test_join.py b/tests/third_party/cupy/manipulation_tests/test_join.py index 054ada455aee..039471faab36 100644 --- a/tests/third_party/cupy/manipulation_tests/test_join.py +++ b/tests/third_party/cupy/manipulation_tests/test_join.py @@ -270,14 +270,12 @@ def test_dstack_single_element_3(self, xp): a = testing.shaped_arange((1,), xp) return xp.dstack((a,)) - @pytest.mark.skip("dpnp.hstack() is not implemented yet") @testing.numpy_cupy_array_equal() def test_hstack_vectors(self, xp): a = xp.arange(3) b = xp.arange(2, -1, -1) return xp.hstack((a, b)) - @pytest.mark.skip("dpnp.hstack() is not implemented yet") @testing.numpy_cupy_array_equal() def test_hstack_scalars(self, xp): a = testing.shaped_arange((), xp) @@ -285,7 +283,6 @@ def test_hstack_scalars(self, xp): c = testing.shaped_arange((), xp) return xp.hstack((a, b, c)) - @pytest.mark.skip("dpnp.hstack() is not implemented yet") @testing.numpy_cupy_array_equal() def test_hstack(self, xp): a = testing.shaped_arange((2, 1), xp) @@ -293,7 +290,7 @@ def test_hstack(self, xp): c = testing.shaped_arange((2, 3), xp) return xp.hstack((a, b, c)) - @pytest.mark.skip("dpnp.hstack() is not implemented yet") + @pytest.mark.usefixtures("allow_fall_back_on_numpy") @testing.with_requires("numpy>=1.24.0") @testing.for_all_dtypes_combination(names=["dtype1", "dtype2"]) @testing.numpy_cupy_array_equal(accept_error=TypeError) @@ -302,7 +299,7 @@ def test_hstack_dtype(self, xp, dtype1, dtype2): b = testing.shaped_arange((3, 4), xp, dtype1) return xp.hstack((a, b), dtype=dtype2) - @pytest.mark.skip("dpnp.hstack() is not implemented yet") + @pytest.mark.usefixtures("allow_fall_back_on_numpy") @testing.with_requires("numpy>=1.24.0") @pytest.mark.parametrize( "casting", From de5d85748cf03a93344c83999f56b9fe6c407cce Mon Sep 17 00:00:00 2001 From: Natalia Polina Date: Thu, 31 Aug 2023 05:34:22 -0500 Subject: [PATCH 3/7] Fixed test for hstack. --- dpnp/dpnp_iface_manipulation.py | 5 +++++ tests/skipped_tests.tbl | 1 - tests/skipped_tests_gpu.tbl | 1 - tests/test_arraymanipulation.py | 4 ++-- .../third_party/cupy/manipulation_tests/test_join.py | 11 +---------- 5 files changed, 8 insertions(+), 14 deletions(-) diff --git a/dpnp/dpnp_iface_manipulation.py b/dpnp/dpnp_iface_manipulation.py index 40d35365e6b7..246a601ad1c7 100644 --- a/dpnp/dpnp_iface_manipulation.py +++ b/dpnp/dpnp_iface_manipulation.py @@ -353,6 +353,7 @@ def concatenate( axis=axis, out=out, dtype=dtype, + casting=casting, **kwargs, ) @@ -746,6 +747,10 @@ def hstack(tup, *, dtype=None, casting="same_kind"): """ + if not hasattr(tup, "__getitem__"): + raise TypeError( + "Arrays to stack must be passed as a sequence type such as list or tuple." + ) arrs = dpnp.atleast_1d(*tup) if not isinstance(arrs, list): arrs = [arrs] diff --git a/tests/skipped_tests.tbl b/tests/skipped_tests.tbl index 9c5b855f3631..10f167653eab 100644 --- a/tests/skipped_tests.tbl +++ b/tests/skipped_tests.tbl @@ -34,7 +34,6 @@ tests/third_party/cupy/fft_tests/test_fft.py::TestFftn_param_23_{axes=None, norm tests/third_party/intel/test_zero_copy_test1.py::test_dpnp_interaction_with_dpctl_memory -tests/test_arraymanipulation.py::TestHstack::test_generator tests/test_arraymanipulation.py::TestVstack::test_generator tests/test_linalg.py::test_cond[-1-[[1, 2, 3], [4, 5, 6], [7, 8, 9]]] diff --git a/tests/skipped_tests_gpu.tbl b/tests/skipped_tests_gpu.tbl index f82c6107a4c6..081f0b72350b 100644 --- a/tests/skipped_tests_gpu.tbl +++ b/tests/skipped_tests_gpu.tbl @@ -216,7 +216,6 @@ tests/third_party/cupy/random_tests/test_distributions.py::TestDistributionsMult tests/third_party/cupy/random_tests/test_distributions.py::TestDistributionsMultivariateNormal_param_3_{d=4, shape=(3, 2)}::test_normal tests/third_party/intel/test_zero_copy_test1.py::test_dpnp_interaction_with_dpctl_memory -tests/test_arraymanipulation.py::TestHstack::test_generator tests/test_arraymanipulation.py::TestVstack::test_generator tests/test_linalg.py::test_cond[-1-[[1, 2, 3], [4, 5, 6], [7, 8, 9]]] diff --git a/tests/test_arraymanipulation.py b/tests/test_arraymanipulation.py index 7603879457d3..32b5e84ac38e 100644 --- a/tests/test_arraymanipulation.py +++ b/tests/test_arraymanipulation.py @@ -360,9 +360,9 @@ def test_2D_array(self): assert_array_equal(res, desired) def test_generator(self): - with assert_warns(FutureWarning): + with pytest.raises(TypeError): dpnp.hstack((numpy.arange(3) for _ in range(2))) - with assert_warns(FutureWarning): + with pytest.raises(TypeError): dpnp.hstack(map(lambda x: x, numpy.ones((3, 2)))) diff --git a/tests/third_party/cupy/manipulation_tests/test_join.py b/tests/third_party/cupy/manipulation_tests/test_join.py index 039471faab36..8bffce98d875 100644 --- a/tests/third_party/cupy/manipulation_tests/test_join.py +++ b/tests/third_party/cupy/manipulation_tests/test_join.py @@ -301,16 +301,7 @@ def test_hstack_dtype(self, xp, dtype1, dtype2): @pytest.mark.usefixtures("allow_fall_back_on_numpy") @testing.with_requires("numpy>=1.24.0") - @pytest.mark.parametrize( - "casting", - [ - "no", - "equiv", - "safe", - "same_kind", - "unsafe", - ], - ) + @testing.for_castings() @testing.for_all_dtypes_combination(names=["dtype1", "dtype2"]) @testing.numpy_cupy_array_equal( accept_error=(TypeError, numpy.ComplexWarning) From a63746b3ab769eed557967664b991a5ecc450167 Mon Sep 17 00:00:00 2001 From: Anton <100830759+antonwolfy@users.noreply.github.com> Date: Thu, 31 Aug 2023 13:02:08 +0200 Subject: [PATCH 4/7] Update tests/test_arraymanipulation.py --- tests/test_arraymanipulation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_arraymanipulation.py b/tests/test_arraymanipulation.py index 32b5e84ac38e..7c77e3885346 100644 --- a/tests/test_arraymanipulation.py +++ b/tests/test_arraymanipulation.py @@ -361,7 +361,7 @@ def test_2D_array(self): def test_generator(self): with pytest.raises(TypeError): - dpnp.hstack((numpy.arange(3) for _ in range(2))) + dpnp.hstack((dpnp.arange(3) for _ in range(2))) with pytest.raises(TypeError): dpnp.hstack(map(lambda x: x, numpy.ones((3, 2)))) From a1f7fcf16d9fb04b3d8183ed3fcbf8f096f7d314 Mon Sep 17 00:00:00 2001 From: Anton <100830759+antonwolfy@users.noreply.github.com> Date: Thu, 31 Aug 2023 13:02:17 +0200 Subject: [PATCH 5/7] Update tests/test_arraymanipulation.py --- tests/test_arraymanipulation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_arraymanipulation.py b/tests/test_arraymanipulation.py index 7c77e3885346..048bbe1c709d 100644 --- a/tests/test_arraymanipulation.py +++ b/tests/test_arraymanipulation.py @@ -363,7 +363,7 @@ def test_generator(self): with pytest.raises(TypeError): dpnp.hstack((dpnp.arange(3) for _ in range(2))) with pytest.raises(TypeError): - dpnp.hstack(map(lambda x: x, numpy.ones((3, 2)))) + dpnp.hstack(map(lambda x: x, dpnp.ones((3, 2)))) class TestStack: From 9066770008f86cf2186209ae291a1be5ae11d225 Mon Sep 17 00:00:00 2001 From: Natalia Polina Date: Thu, 31 Aug 2023 11:15:09 -0500 Subject: [PATCH 6/7] Fixed test coverage for concatenate and hstack functions. --- dpnp/dpnp_iface_manipulation.py | 7 ++----- tests/test_arraymanipulation.py | 22 ++++++++++++++++++++++ 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/dpnp/dpnp_iface_manipulation.py b/dpnp/dpnp_iface_manipulation.py index 246a601ad1c7..59bae9b30fec 100644 --- a/dpnp/dpnp_iface_manipulation.py +++ b/dpnp/dpnp_iface_manipulation.py @@ -282,7 +282,7 @@ def broadcast_to(array, /, shape, subok=False): def concatenate( - arrays, /, *, axis=0, out=None, dtype=None, casting="same_kind", **kwargs + arrays, /, *, axis=0, out=None, dtype=None, casting="same_kind" ): """ Join a sequence of arrays along an existing axis. @@ -334,9 +334,7 @@ def concatenate( """ - if kwargs: - pass - elif out is not None: + if out is not None: pass elif dtype is not None: pass @@ -354,7 +352,6 @@ def concatenate( out=out, dtype=dtype, casting=casting, - **kwargs, ) diff --git a/tests/test_arraymanipulation.py b/tests/test_arraymanipulation.py index 048bbe1c709d..3dcfeac72a0f 100644 --- a/tests/test_arraymanipulation.py +++ b/tests/test_arraymanipulation.py @@ -330,6 +330,23 @@ def test_concatenate_out(self, dtype): assert_array_equal(dp_out.asnumpy(), np_out) assert_array_equal(dp_res.asnumpy(), np_res) + @pytest.mark.usefixtures("allow_fall_back_on_numpy") + @pytest.mark.parametrize( + "dtype", get_all_dtypes(no_bool=True, no_none=True) + ) + @pytest.mark.parametrize( + "casting", ["no", "equiv", "safe", "same_kind", "unsafe"] + ) + def test_concatenate_casting(self, dtype, casting): + np_a = numpy.arange(2 * 3 * 7, dtype=dtype).reshape((2, 3, 7)) + + dp_a = dpnp.arange(2 * 3 * 7, dtype=dtype).reshape((2, 3, 7)) + + np_res = numpy.concatenate((np_a, np_a), axis=2, casting=casting) + dp_res = dpnp.concatenate((dp_a, dp_a), axis=2, casting=casting) + + assert_array_equal(dp_res.asnumpy(), np_res) + class TestHstack: def test_non_iterable(self): @@ -365,6 +382,11 @@ def test_generator(self): with pytest.raises(TypeError): dpnp.hstack(map(lambda x: x, dpnp.ones((3, 2)))) + def test_one_element(self): + a = dpnp.array([1]) + res = dpnp.hstack(a) + assert_array_equal(res, a) + class TestStack: def test_non_iterable_input(self): From 2429a6f2210fec0ec055bd30f54025865aa86a34 Mon Sep 17 00:00:00 2001 From: Natalia Polina Date: Wed, 6 Sep 2023 00:30:17 -0700 Subject: [PATCH 7/7] Fixed limitation description for concatenate function --- dpnp/dpnp_iface_manipulation.py | 1 - 1 file changed, 1 deletion(-) diff --git a/dpnp/dpnp_iface_manipulation.py b/dpnp/dpnp_iface_manipulation.py index 59bae9b30fec..207d51636eb5 100644 --- a/dpnp/dpnp_iface_manipulation.py +++ b/dpnp/dpnp_iface_manipulation.py @@ -300,7 +300,6 @@ def concatenate( or :class:`dpctl.tensor.usm_ndarray`. Otherwise ``TypeError`` exception will be raised. Parameters `out` and `dtype are supported with default value. - Keyword argument ``kwargs`` is currently unsupported. Otherwise the function will be executed sequentially on CPU. See Also