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

Updated dpnp.vstack function #1595

Merged
merged 4 commits into from
Oct 16, 2023
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
61 changes: 51 additions & 10 deletions dpnp/dpnp_iface_manipulation.py
Original file line number Diff line number Diff line change
Expand Up @@ -1548,20 +1548,61 @@ def unique(ar, **kwargs):
return call_origin(numpy.unique, ar, **kwargs)


def vstack(tup):
def vstack(tup, *, dtype=None, casting="same_kind"):
"""
Stack arrays in sequence vertically (row wise).

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

"""
Returns
-------
out : dpnp.ndarray
The array formed by stacking the given arrays, will be at least 2-D.

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.

# TODO:
# `call_origin` cannot convert sequence of array to sequence of
# nparray
tup_new = []
for tp in tup:
tpx = dpnp.asnumpy(tp) if not isinstance(tp, numpy.ndarray) else tp
tup_new.append(tpx)
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.hstack` : Stack arrays in sequence horizontally (column wise).
:obj:`dpnp.dstack` : Stack arrays in sequence depth wise (along third axis).
:obj:`dpnp.column_stack` : Stack 1-D arrays as columns into a 2-D array.
: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.
npolina4 marked this conversation as resolved.
Show resolved Hide resolved

return call_origin(numpy.vstack, tup_new)
Examples
--------
>>> import dpnp as np
>>> a = np.array([1, 2, 3])
>>> b = np.array([4, 5, 6])
>>> np.vstack((a, b))
array([[1, 2, 3],
[4, 5, 6]])

>>> a = np.array([[1], [2], [3]])
>>> b = np.array([[4], [5], [6]])
>>> np.vstack((a, b))
array([[1],
[2],
[3],
[4],
[5],
[6]])

"""

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_2d(*tup)
if not isinstance(arrs, list):
arrs = [arrs]
return dpnp.concatenate(arrs, axis=0, dtype=dtype, casting=casting)
4 changes: 1 addition & 3 deletions tests/skipped_tests.tbl
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +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::TestVstack::test_generator

tests/test_linalg.py::test_cond[-1-[[1, 2, 3], [4, 5, 6], [7, 8, 9]]]
tests/test_linalg.py::test_cond[1-[[1, 2, 3], [4, 5, 6], [7, 8, 9]]]
tests/test_linalg.py::test_cond[-2-[[1, 0, -1], [0, 1, 0], [1, 0, 1]]]
Expand Down Expand Up @@ -450,7 +448,6 @@ tests/third_party/cupy/manipulation_tests/test_dims.py::TestBroadcast_param_8_{s
tests/third_party/cupy/manipulation_tests/test_dims.py::TestBroadcast_param_8_{shapes=[(2, 0, 1, 1, 3), (2, 1, 0, 0, 3)]}::test_broadcast_arrays
tests/third_party/cupy/manipulation_tests/test_dims.py::TestBroadcast_param_9_{shapes=[(0, 1, 1, 3), (2, 1, 0, 0, 3)]}::test_broadcast
tests/third_party/cupy/manipulation_tests/test_dims.py::TestBroadcast_param_9_{shapes=[(0, 1, 1, 3), (2, 1, 0, 0, 3)]}::test_broadcast_arrays

tests/third_party/cupy/manipulation_tests/test_dims.py::TestInvalidBroadcast_param_0_{shapes=[(3,), (2,)]}::test_invalid_broadcast
tests/third_party/cupy/manipulation_tests/test_dims.py::TestInvalidBroadcast_param_0_{shapes=[(3,), (2,)]}::test_invalid_broadcast_arrays
tests/third_party/cupy/manipulation_tests/test_dims.py::TestInvalidBroadcast_param_1_{shapes=[(3, 2), (2, 3)]}::test_invalid_broadcast
Expand All @@ -459,6 +456,7 @@ tests/third_party/cupy/manipulation_tests/test_dims.py::TestInvalidBroadcast_par
tests/third_party/cupy/manipulation_tests/test_dims.py::TestInvalidBroadcast_param_2_{shapes=[(3, 2), (3, 4)]}::test_invalid_broadcast_arrays
tests/third_party/cupy/manipulation_tests/test_dims.py::TestInvalidBroadcast_param_3_{shapes=[(0,), (2,)]}::test_invalid_broadcast
tests/third_party/cupy/manipulation_tests/test_dims.py::TestInvalidBroadcast_param_3_{shapes=[(0,), (2,)]}::test_invalid_broadcast_arrays

tests/third_party/cupy/manipulation_tests/test_shape.py::TestRavel::test_ravel2
tests/third_party/cupy/manipulation_tests/test_shape.py::TestRavel::test_ravel3
tests/third_party/cupy/manipulation_tests/test_shape.py::TestRavel::test_external_ravel
Expand Down
1 change: 0 additions & 1 deletion tests/skipped_tests_gpu.tbl
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,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::TestVstack::test_generator

tests/test_linalg.py::test_cond[-1-[[1, 2, 3], [4, 5, 6], [7, 8, 9]]]
tests/test_linalg.py::test_cond[1-[[1, 2, 3], [4, 5, 6], [7, 8, 9]]]
Expand Down
11 changes: 3 additions & 8 deletions tests/test_arraymanipulation.py
Original file line number Diff line number Diff line change
Expand Up @@ -583,35 +583,30 @@ class TestVstack:
def test_non_iterable(self):
assert_raises(TypeError, dpnp.vstack, 1)

@pytest.mark.usefixtures("allow_fall_back_on_numpy")
def test_empty_input(self):
assert_raises(ValueError, dpnp.vstack, ())
assert_raises(TypeError, dpnp.vstack, ())

@pytest.mark.usefixtures("allow_fall_back_on_numpy")
def test_0D_array(self):
a = dpnp.array(1)
b = dpnp.array(2)
res = dpnp.vstack([a, b])
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])
res = dpnp.vstack([a, b])
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]])
res = dpnp.vstack([a, b])
desired = dpnp.array([[1], [2], [1], [2]])
assert_array_equal(res, desired)

@pytest.mark.usefixtures("allow_fall_back_on_numpy")
def test_2D_array2(self):
a = dpnp.array([1, 2])
b = dpnp.array([1, 2])
Expand All @@ -620,8 +615,8 @@ def test_2D_array2(self):
assert_array_equal(res, desired)

def test_generator(self):
with assert_warns(FutureWarning):
dpnp.vstack((numpy.arange(3) for _ in range(2)))
with pytest.raises(TypeError):
dpnp.vstack((dpnp.arange(3) for _ in range(2)))


class TestAtleast1d:
Expand Down
18 changes: 3 additions & 15 deletions tests/third_party/cupy/manipulation_tests/test_join.py
Original file line number Diff line number Diff line change
Expand Up @@ -312,27 +312,24 @@ def test_hstack_casting(self, xp, dtype1, dtype2, casting):
# may raise TypeError or ComplexWarning
return xp.hstack((a, b), dtype=dtype2, casting=casting)

@pytest.mark.skip("dpnp.vstack() is not implemented yet")
@testing.numpy_cupy_array_equal()
def test_vstack_vectors(self, xp):
a = xp.arange(3)
b = xp.arange(2, -1, -1)
return xp.vstack((a, b))

@pytest.mark.skip("dpnp.vstack() is not implemented yet")
@testing.numpy_cupy_array_equal()
def test_vstack_single_element(self, xp):
a = xp.arange(3)
return xp.vstack((a,))

@pytest.mark.skip("dpnp.vstack() is not implemented yet")
def test_vstack_wrong_ndim(self):
a = cupy.empty((3,))
b = cupy.empty((3, 1))
with pytest.raises(ValueError):
cupy.vstack((a, b))

@pytest.mark.skip("dpnp.vstack() 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)
Expand All @@ -341,18 +338,9 @@ def test_vstack_dtype(self, xp, dtype1, dtype2):
b = testing.shaped_arange((3, 4), xp, dtype1)
return xp.vstack((a, b), dtype=dtype2)

@pytest.mark.skip("dpnp.vstack() is not implemented yet")
@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)
Expand Down