Skip to content

Commit

Permalink
Merge branch 'master' into bool_bitwise_ops
Browse files Browse the repository at this point in the history
  • Loading branch information
antonwolfy authored Mar 7, 2023
2 parents b1654cf + 684f393 commit a5ca19b
Show file tree
Hide file tree
Showing 6 changed files with 201 additions and 50 deletions.
44 changes: 44 additions & 0 deletions dpnp/dpnp_iface_manipulation.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,18 @@
from dpnp.dpnp_iface_arraycreation import array

import dpnp
from dpnp.dpnp_array import dpnp_array

import numpy
import dpctl.tensor as dpt


__all__ = [
"asfarray",
"atleast_1d",
"atleast_2d",
"atleast_3d",
"broadcast_to",
"concatenate",
"copyto",
"expand_dims",
Expand Down Expand Up @@ -190,6 +194,46 @@ def atleast_3d(*arys):
return call_origin(numpy.atleast_3d, *arys)


def broadcast_to(x, /, shape, subok=False):
"""
Broadcast an array to a new shape.
For full documentation refer to :obj:`numpy.broadcast_to`.
Returns
-------
y : dpnp.ndarray
An array having a specified shape. Must have the same data type as `x`.
Limitations
-----------
Parameter `x` is supported as either :class:`dpnp.ndarray`
or :class:`dpctl.tensor.usm_ndarray`.
Parameter `subok` is supported with default value.
Otherwise the function will be executed sequentially on CPU.
Input array data types of `x` is limited by supported DPNP :ref:`Data types`.
Examples
--------
>>> import dpnp as dp
>>> x = dp.array([1, 2, 3])
>>> dp.broadcast_to(x, (3, 3))
array([[1, 2, 3],
[1, 2, 3],
[1, 2, 3]])
"""

if subok is not False:
pass
elif isinstance(x, dpnp_array) or isinstance(x, dpt.usm_ndarray):
dpt_array = x.get_array() if isinstance(x, dpnp_array) else x
new_array = dpt.broadcast_to(dpt_array, shape)
return dpnp_array._create_from_usm_ndarray(new_array)

return call_origin(numpy.broadcast_to, x, shape=shape, subok=subok)


def concatenate(arrs, axis=0, out=None, dtype=None, casting="same_kind"):
"""
Join a sequence of arrays along an existing axis.
Expand Down
7 changes: 1 addition & 6 deletions tests/skipped_tests.tbl
Original file line number Diff line number Diff line change
Expand Up @@ -643,12 +643,7 @@ 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::TestDims::test_broadcast_to
tests/third_party/cupy/manipulation_tests/test_dims.py::TestDims::test_broadcast_to_fail
tests/third_party/cupy/manipulation_tests/test_dims.py::TestDims::test_broadcast_to_fail_numpy19
tests/third_party/cupy/manipulation_tests/test_dims.py::TestDims::test_broadcast_to_numpy19
tests/third_party/cupy/manipulation_tests/test_dims.py::TestDims::test_broadcast_to_short_shape
tests/third_party/cupy/manipulation_tests/test_dims.py::TestDims::test_broadcast_to_short_shape_numpy19

tests/third_party/cupy/manipulation_tests/test_dims.py::TestDims::test_squeeze_int_axis_failure1
tests/third_party/cupy/manipulation_tests/test_dims.py::TestDims::test_squeeze_int_axis_failure2
tests/third_party/cupy/manipulation_tests/test_dims.py::TestDims::test_squeeze_scalar_failure1
Expand Down
7 changes: 1 addition & 6 deletions tests/skipped_tests_gpu.tbl
Original file line number Diff line number Diff line change
Expand Up @@ -848,12 +848,7 @@ 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::TestDims::test_broadcast_to
tests/third_party/cupy/manipulation_tests/test_dims.py::TestDims::test_broadcast_to_fail
tests/third_party/cupy/manipulation_tests/test_dims.py::TestDims::test_broadcast_to_fail_numpy19
tests/third_party/cupy/manipulation_tests/test_dims.py::TestDims::test_broadcast_to_numpy19
tests/third_party/cupy/manipulation_tests/test_dims.py::TestDims::test_broadcast_to_short_shape
tests/third_party/cupy/manipulation_tests/test_dims.py::TestDims::test_broadcast_to_short_shape_numpy19

tests/third_party/cupy/manipulation_tests/test_dims.py::TestDims::test_squeeze_int_axis_failure1
tests/third_party/cupy/manipulation_tests/test_dims.py::TestDims::test_squeeze_int_axis_failure2
tests/third_party/cupy/manipulation_tests/test_dims.py::TestDims::test_squeeze_scalar_failure1
Expand Down
173 changes: 137 additions & 36 deletions tests/test_arraymanipulation.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,16 @@
from .helper import get_all_dtypes

import dpnp

import numpy
from numpy.testing import (
assert_,
assert_allclose,
assert_array_equal,
assert_equal,
assert_raises,
assert_warns
)


@pytest.mark.usefixtures("allow_fall_back_on_numpy")
Expand All @@ -14,7 +23,7 @@ def test_asfarray(dtype, data):
expected = numpy.asfarray(data, dtype)
result = dpnp.asfarray(data, dtype)

numpy.testing.assert_array_equal(result, expected)
assert_array_equal(result, expected)


@pytest.mark.parametrize("dtype", get_all_dtypes())
Expand All @@ -24,7 +33,99 @@ def test_asfarray2(dtype, data, data_dtype):
expected = numpy.asfarray(numpy.array(data, dtype=data_dtype), dtype)
result = dpnp.asfarray(dpnp.array(data, dtype=data_dtype), dtype)

numpy.testing.assert_array_equal(result, expected)
assert_array_equal(result, expected)


class TestDims:
@pytest.mark.parametrize("dt", get_all_dtypes())
@pytest.mark.parametrize("sh",
[(0,), (1,), (3,)],
ids=['(0,)', '(1,)', '(3,)'])
def test_broadcast_array(self, sh, dt):
np_a = numpy.array(0, dtype=dt)
dp_a = dpnp.array(0, dtype=dt)
func = lambda xp, a: xp.broadcast_to(a, sh)

assert_allclose(func(numpy, np_a), func(dpnp, dp_a))

@pytest.mark.parametrize("dt", get_all_dtypes())
@pytest.mark.parametrize("sh",
[(1,), (2,), (1, 2, 3)],
ids=['(1,)', '(2,)', '(1, 2, 3)'])
def test_broadcast_ones(self, sh, dt):
np_a = numpy.ones(1, dtype=dt)
dp_a = dpnp.ones(1, dtype=dt)
func = lambda xp, a: xp.broadcast_to(a, sh)

assert_allclose(func(numpy, np_a), func(dpnp, dp_a))

@pytest.mark.parametrize("dt", get_all_dtypes(no_bool=True))
@pytest.mark.parametrize("sh",
[(3,), (1, 3), (2, 3)],
ids=['(3,)', '(1, 3)', '(2, 3)'])
def test_broadcast_arange(self, sh, dt):
np_a = numpy.arange(3, dtype=dt)
dp_a = dpnp.arange(3, dtype=dt)
func = lambda xp, a: xp.broadcast_to(a, sh)

assert_allclose(func(numpy, np_a), func(dpnp, dp_a))

@pytest.mark.parametrize("dt", get_all_dtypes())
@pytest.mark.parametrize(
"sh1, sh2",
[
pytest.param([0], [0], id="(0)"),
pytest.param([1], [1], id="(1)"),
pytest.param([1], [2], id="(2)"),
],
)
def test_broadcast_not_tuple(self, sh1, sh2, dt):
np_a = numpy.ones(sh1, dtype=dt)
dp_a = dpnp.ones(sh1, dtype=dt)
func = lambda xp, a: xp.broadcast_to(a, sh2)

assert_allclose(func(numpy, np_a), func(dpnp, dp_a))

@pytest.mark.parametrize("dt", get_all_dtypes())
@pytest.mark.parametrize(
"sh1, sh2",
[
pytest.param([1], (0,), id="(0,)"),
pytest.param((1, 2), (0, 2), id="(0, 2)"),
pytest.param((2, 1), (2, 0), id="(2, 0)"),
],
)
def test_broadcast_zero_shape(self, sh1, sh2, dt):
np_a = numpy.ones(sh1, dtype=dt)
dp_a = dpnp.ones(sh1, dtype=dt)
func = lambda xp, a: xp.broadcast_to(a, sh2)

assert_allclose(func(numpy, np_a), func(dpnp, dp_a))

@pytest.mark.parametrize(
"sh1, sh2",
[
pytest.param((0,), (), id="(0,)-()"),
pytest.param((1,), (), id="(1,)-()"),
pytest.param((3,), (), id="(3,)-()"),
pytest.param((3,), (1,), id="(3,)-(1,)"),
pytest.param((3,), (2,), id="(3,)-(2,)"),
pytest.param((3,), (4,), id="(3,)-(4,)"),
pytest.param((1, 2), (2, 1), id="(1, 2)-(2, 1)"),
pytest.param((1, 2), (1,), id="(1, 2)-(1,)"),
pytest.param((1,), -1, id="(1,)--1"),
pytest.param((1,), (-1,), id="(1,)-(-1,)"),
pytest.param((1, 2), (-1, 2), id="(1, 2)-(-1, 2)"),
],
)
def test_broadcast_raise(self, sh1, sh2):
np_a = numpy.zeros(sh1)
dp_a = dpnp.zeros(sh1)
func = lambda xp, a: xp.broadcast_to(a, sh2)

with pytest.raises(ValueError):
func(numpy, np_a)
func(dpnp, dp_a)


@pytest.mark.usefixtures("allow_fall_back_on_numpy")
Expand All @@ -38,134 +139,134 @@ def test_returns_copy(self):
def test_large_concatenate_axis_None(self):
x = dpnp.arange(1, 100)
r = dpnp.concatenate(x, None)
numpy.testing.assert_array_equal(x, r)
assert_array_equal(x, r)
r = dpnp.concatenate(x, 100)
numpy.testing.assert_array_equal(x, r)
assert_array_equal(x, r)

def test_concatenate(self):
# Test concatenate function
# One sequence returns unmodified (but as array)
r4 = list(range(4))
numpy.testing.assert_array_equal(dpnp.concatenate((r4,)), r4)
assert_array_equal(dpnp.concatenate((r4,)), r4)
# Any sequence
numpy.testing.assert_array_equal(dpnp.concatenate((tuple(r4),)), r4)
numpy.testing.assert_array_equal(dpnp.concatenate((dpnp.array(r4),)), r4)
assert_array_equal(dpnp.concatenate((tuple(r4),)), r4)
assert_array_equal(dpnp.concatenate((dpnp.array(r4),)), r4)
# 1D default concatenation
r3 = list(range(3))
numpy.testing.assert_array_equal(dpnp.concatenate((r4, r3)), r4 + r3)
assert_array_equal(dpnp.concatenate((r4, r3)), r4 + r3)
# Mixed sequence types
numpy.testing.assert_array_equal(dpnp.concatenate((tuple(r4), r3)), r4 + r3)
numpy.testing.assert_array_equal(
assert_array_equal(dpnp.concatenate((tuple(r4), r3)), r4 + r3)
assert_array_equal(
dpnp.concatenate((dpnp.array(r4), r3)), r4 + r3
)
# Explicit axis specification
numpy.testing.assert_array_equal(dpnp.concatenate((r4, r3), 0), r4 + r3)
assert_array_equal(dpnp.concatenate((r4, r3), 0), r4 + r3)
# Including negative
numpy.testing.assert_array_equal(dpnp.concatenate((r4, r3), -1), r4 + r3)
assert_array_equal(dpnp.concatenate((r4, r3), -1), r4 + r3)
# 2D
a23 = dpnp.array([[10, 11, 12], [13, 14, 15]])
a13 = dpnp.array([[0, 1, 2]])
res = dpnp.array([[10, 11, 12], [13, 14, 15], [0, 1, 2]])
numpy.testing.assert_array_equal(dpnp.concatenate((a23, a13)), res)
numpy.testing.assert_array_equal(dpnp.concatenate((a23, a13), 0), res)
numpy.testing.assert_array_equal(dpnp.concatenate((a23.T, a13.T), 1), res.T)
numpy.testing.assert_array_equal(dpnp.concatenate((a23.T, a13.T), -1), res.T)
assert_array_equal(dpnp.concatenate((a23, a13)), res)
assert_array_equal(dpnp.concatenate((a23, a13), 0), res)
assert_array_equal(dpnp.concatenate((a23.T, a13.T), 1), res.T)
assert_array_equal(dpnp.concatenate((a23.T, a13.T), -1), res.T)
# Arrays much match shape
numpy.testing.assert_raises(ValueError, dpnp.concatenate, (a23.T, a13.T), 0)
assert_raises(ValueError, dpnp.concatenate, (a23.T, a13.T), 0)
# 3D
res = dpnp.reshape(dpnp.arange(2 * 3 * 7), (2, 3, 7))
a0 = res[..., :4]
a1 = res[..., 4:6]
a2 = res[..., 6:]
numpy.testing.assert_array_equal(dpnp.concatenate((a0, a1, a2), 2), res)
numpy.testing.assert_array_equal(dpnp.concatenate((a0, a1, a2), -1), res)
numpy.testing.assert_array_equal(dpnp.concatenate((a0.T, a1.T, a2.T), 0), res.T)
assert_array_equal(dpnp.concatenate((a0, a1, a2), 2), res)
assert_array_equal(dpnp.concatenate((a0, a1, a2), -1), res)
assert_array_equal(dpnp.concatenate((a0.T, a1.T, a2.T), 0), res.T)

out = dpnp.copy(res)
rout = dpnp.concatenate((a0, a1, a2), 2, out=out)
numpy.testing.assert_(out is rout)
numpy.testing.assert_equal(res, rout)
assert_(out is rout)
assert_equal(res, rout)


class TestHstack:
def test_non_iterable(self):
numpy.testing.assert_raises(TypeError, dpnp.hstack, 1)
assert_raises(TypeError, dpnp.hstack, 1)

@pytest.mark.usefixtures("allow_fall_back_on_numpy")
def test_empty_input(self):
numpy.testing.assert_raises(ValueError, dpnp.hstack, ())
assert_raises(ValueError, dpnp.hstack, ())

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

def test_generator(self):
with numpy.testing.assert_warns(FutureWarning):
with assert_warns(FutureWarning):
dpnp.hstack((numpy.arange(3) for _ in range(2)))
with numpy.testing.assert_warns(FutureWarning):
with assert_warns(FutureWarning):
dpnp.hstack(map(lambda x: x, numpy.ones((3, 2))))


class TestVstack:
def test_non_iterable(self):
numpy.testing.assert_raises(TypeError, dpnp.vstack, 1)
assert_raises(TypeError, dpnp.vstack, 1)

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

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

0 comments on commit a5ca19b

Please sign in to comment.