Skip to content

Commit a5ca19b

Browse files
authored
Merge branch 'master' into bool_bitwise_ops
2 parents b1654cf + 684f393 commit a5ca19b

File tree

6 files changed

+201
-50
lines changed

6 files changed

+201
-50
lines changed

dpnp/dpnp_iface_manipulation.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,14 +47,18 @@
4747
from dpnp.dpnp_iface_arraycreation import array
4848

4949
import dpnp
50+
from dpnp.dpnp_array import dpnp_array
51+
5052
import numpy
53+
import dpctl.tensor as dpt
5154

5255

5356
__all__ = [
5457
"asfarray",
5558
"atleast_1d",
5659
"atleast_2d",
5760
"atleast_3d",
61+
"broadcast_to",
5862
"concatenate",
5963
"copyto",
6064
"expand_dims",
@@ -190,6 +194,46 @@ def atleast_3d(*arys):
190194
return call_origin(numpy.atleast_3d, *arys)
191195

192196

197+
def broadcast_to(x, /, shape, subok=False):
198+
"""
199+
Broadcast an array to a new shape.
200+
201+
For full documentation refer to :obj:`numpy.broadcast_to`.
202+
203+
Returns
204+
-------
205+
y : dpnp.ndarray
206+
An array having a specified shape. Must have the same data type as `x`.
207+
208+
Limitations
209+
-----------
210+
Parameter `x` is supported as either :class:`dpnp.ndarray`
211+
or :class:`dpctl.tensor.usm_ndarray`.
212+
Parameter `subok` is supported with default value.
213+
Otherwise the function will be executed sequentially on CPU.
214+
Input array data types of `x` is limited by supported DPNP :ref:`Data types`.
215+
216+
Examples
217+
--------
218+
>>> import dpnp as dp
219+
>>> x = dp.array([1, 2, 3])
220+
>>> dp.broadcast_to(x, (3, 3))
221+
array([[1, 2, 3],
222+
[1, 2, 3],
223+
[1, 2, 3]])
224+
225+
"""
226+
227+
if subok is not False:
228+
pass
229+
elif isinstance(x, dpnp_array) or isinstance(x, dpt.usm_ndarray):
230+
dpt_array = x.get_array() if isinstance(x, dpnp_array) else x
231+
new_array = dpt.broadcast_to(dpt_array, shape)
232+
return dpnp_array._create_from_usm_ndarray(new_array)
233+
234+
return call_origin(numpy.broadcast_to, x, shape=shape, subok=subok)
235+
236+
193237
def concatenate(arrs, axis=0, out=None, dtype=None, casting="same_kind"):
194238
"""
195239
Join a sequence of arrays along an existing axis.

tests/skipped_tests.tbl

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -643,12 +643,7 @@ tests/third_party/cupy/manipulation_tests/test_dims.py::TestBroadcast_param_8_{s
643643
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
644644
tests/third_party/cupy/manipulation_tests/test_dims.py::TestBroadcast_param_9_{shapes=[(0, 1, 1, 3), (2, 1, 0, 0, 3)]}::test_broadcast
645645
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
646-
tests/third_party/cupy/manipulation_tests/test_dims.py::TestDims::test_broadcast_to
647-
tests/third_party/cupy/manipulation_tests/test_dims.py::TestDims::test_broadcast_to_fail
648-
tests/third_party/cupy/manipulation_tests/test_dims.py::TestDims::test_broadcast_to_fail_numpy19
649-
tests/third_party/cupy/manipulation_tests/test_dims.py::TestDims::test_broadcast_to_numpy19
650-
tests/third_party/cupy/manipulation_tests/test_dims.py::TestDims::test_broadcast_to_short_shape
651-
tests/third_party/cupy/manipulation_tests/test_dims.py::TestDims::test_broadcast_to_short_shape_numpy19
646+
652647
tests/third_party/cupy/manipulation_tests/test_dims.py::TestDims::test_squeeze_int_axis_failure1
653648
tests/third_party/cupy/manipulation_tests/test_dims.py::TestDims::test_squeeze_int_axis_failure2
654649
tests/third_party/cupy/manipulation_tests/test_dims.py::TestDims::test_squeeze_scalar_failure1

tests/skipped_tests_gpu.tbl

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -848,12 +848,7 @@ tests/third_party/cupy/manipulation_tests/test_dims.py::TestBroadcast_param_8_{s
848848
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
849849
tests/third_party/cupy/manipulation_tests/test_dims.py::TestBroadcast_param_9_{shapes=[(0, 1, 1, 3), (2, 1, 0, 0, 3)]}::test_broadcast
850850
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
851-
tests/third_party/cupy/manipulation_tests/test_dims.py::TestDims::test_broadcast_to
852-
tests/third_party/cupy/manipulation_tests/test_dims.py::TestDims::test_broadcast_to_fail
853-
tests/third_party/cupy/manipulation_tests/test_dims.py::TestDims::test_broadcast_to_fail_numpy19
854-
tests/third_party/cupy/manipulation_tests/test_dims.py::TestDims::test_broadcast_to_numpy19
855-
tests/third_party/cupy/manipulation_tests/test_dims.py::TestDims::test_broadcast_to_short_shape
856-
tests/third_party/cupy/manipulation_tests/test_dims.py::TestDims::test_broadcast_to_short_shape_numpy19
851+
857852
tests/third_party/cupy/manipulation_tests/test_dims.py::TestDims::test_squeeze_int_axis_failure1
858853
tests/third_party/cupy/manipulation_tests/test_dims.py::TestDims::test_squeeze_int_axis_failure2
859854
tests/third_party/cupy/manipulation_tests/test_dims.py::TestDims::test_squeeze_scalar_failure1

tests/test_arraymanipulation.py

Lines changed: 137 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,16 @@
22
from .helper import get_all_dtypes
33

44
import dpnp
5+
56
import numpy
7+
from numpy.testing import (
8+
assert_,
9+
assert_allclose,
10+
assert_array_equal,
11+
assert_equal,
12+
assert_raises,
13+
assert_warns
14+
)
615

716

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

17-
numpy.testing.assert_array_equal(result, expected)
26+
assert_array_equal(result, expected)
1827

1928

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

27-
numpy.testing.assert_array_equal(result, expected)
36+
assert_array_equal(result, expected)
37+
38+
39+
class TestDims:
40+
@pytest.mark.parametrize("dt", get_all_dtypes())
41+
@pytest.mark.parametrize("sh",
42+
[(0,), (1,), (3,)],
43+
ids=['(0,)', '(1,)', '(3,)'])
44+
def test_broadcast_array(self, sh, dt):
45+
np_a = numpy.array(0, dtype=dt)
46+
dp_a = dpnp.array(0, dtype=dt)
47+
func = lambda xp, a: xp.broadcast_to(a, sh)
48+
49+
assert_allclose(func(numpy, np_a), func(dpnp, dp_a))
50+
51+
@pytest.mark.parametrize("dt", get_all_dtypes())
52+
@pytest.mark.parametrize("sh",
53+
[(1,), (2,), (1, 2, 3)],
54+
ids=['(1,)', '(2,)', '(1, 2, 3)'])
55+
def test_broadcast_ones(self, sh, dt):
56+
np_a = numpy.ones(1, dtype=dt)
57+
dp_a = dpnp.ones(1, dtype=dt)
58+
func = lambda xp, a: xp.broadcast_to(a, sh)
59+
60+
assert_allclose(func(numpy, np_a), func(dpnp, dp_a))
61+
62+
@pytest.mark.parametrize("dt", get_all_dtypes(no_bool=True))
63+
@pytest.mark.parametrize("sh",
64+
[(3,), (1, 3), (2, 3)],
65+
ids=['(3,)', '(1, 3)', '(2, 3)'])
66+
def test_broadcast_arange(self, sh, dt):
67+
np_a = numpy.arange(3, dtype=dt)
68+
dp_a = dpnp.arange(3, dtype=dt)
69+
func = lambda xp, a: xp.broadcast_to(a, sh)
70+
71+
assert_allclose(func(numpy, np_a), func(dpnp, dp_a))
72+
73+
@pytest.mark.parametrize("dt", get_all_dtypes())
74+
@pytest.mark.parametrize(
75+
"sh1, sh2",
76+
[
77+
pytest.param([0], [0], id="(0)"),
78+
pytest.param([1], [1], id="(1)"),
79+
pytest.param([1], [2], id="(2)"),
80+
],
81+
)
82+
def test_broadcast_not_tuple(self, sh1, sh2, dt):
83+
np_a = numpy.ones(sh1, dtype=dt)
84+
dp_a = dpnp.ones(sh1, dtype=dt)
85+
func = lambda xp, a: xp.broadcast_to(a, sh2)
86+
87+
assert_allclose(func(numpy, np_a), func(dpnp, dp_a))
88+
89+
@pytest.mark.parametrize("dt", get_all_dtypes())
90+
@pytest.mark.parametrize(
91+
"sh1, sh2",
92+
[
93+
pytest.param([1], (0,), id="(0,)"),
94+
pytest.param((1, 2), (0, 2), id="(0, 2)"),
95+
pytest.param((2, 1), (2, 0), id="(2, 0)"),
96+
],
97+
)
98+
def test_broadcast_zero_shape(self, sh1, sh2, dt):
99+
np_a = numpy.ones(sh1, dtype=dt)
100+
dp_a = dpnp.ones(sh1, dtype=dt)
101+
func = lambda xp, a: xp.broadcast_to(a, sh2)
102+
103+
assert_allclose(func(numpy, np_a), func(dpnp, dp_a))
104+
105+
@pytest.mark.parametrize(
106+
"sh1, sh2",
107+
[
108+
pytest.param((0,), (), id="(0,)-()"),
109+
pytest.param((1,), (), id="(1,)-()"),
110+
pytest.param((3,), (), id="(3,)-()"),
111+
pytest.param((3,), (1,), id="(3,)-(1,)"),
112+
pytest.param((3,), (2,), id="(3,)-(2,)"),
113+
pytest.param((3,), (4,), id="(3,)-(4,)"),
114+
pytest.param((1, 2), (2, 1), id="(1, 2)-(2, 1)"),
115+
pytest.param((1, 2), (1,), id="(1, 2)-(1,)"),
116+
pytest.param((1,), -1, id="(1,)--1"),
117+
pytest.param((1,), (-1,), id="(1,)-(-1,)"),
118+
pytest.param((1, 2), (-1, 2), id="(1, 2)-(-1, 2)"),
119+
],
120+
)
121+
def test_broadcast_raise(self, sh1, sh2):
122+
np_a = numpy.zeros(sh1)
123+
dp_a = dpnp.zeros(sh1)
124+
func = lambda xp, a: xp.broadcast_to(a, sh2)
125+
126+
with pytest.raises(ValueError):
127+
func(numpy, np_a)
128+
func(dpnp, dp_a)
28129

29130

30131
@pytest.mark.usefixtures("allow_fall_back_on_numpy")
@@ -38,134 +139,134 @@ def test_returns_copy(self):
38139
def test_large_concatenate_axis_None(self):
39140
x = dpnp.arange(1, 100)
40141
r = dpnp.concatenate(x, None)
41-
numpy.testing.assert_array_equal(x, r)
142+
assert_array_equal(x, r)
42143
r = dpnp.concatenate(x, 100)
43-
numpy.testing.assert_array_equal(x, r)
144+
assert_array_equal(x, r)
44145

45146
def test_concatenate(self):
46147
# Test concatenate function
47148
# One sequence returns unmodified (but as array)
48149
r4 = list(range(4))
49-
numpy.testing.assert_array_equal(dpnp.concatenate((r4,)), r4)
150+
assert_array_equal(dpnp.concatenate((r4,)), r4)
50151
# Any sequence
51-
numpy.testing.assert_array_equal(dpnp.concatenate((tuple(r4),)), r4)
52-
numpy.testing.assert_array_equal(dpnp.concatenate((dpnp.array(r4),)), r4)
152+
assert_array_equal(dpnp.concatenate((tuple(r4),)), r4)
153+
assert_array_equal(dpnp.concatenate((dpnp.array(r4),)), r4)
53154
# 1D default concatenation
54155
r3 = list(range(3))
55-
numpy.testing.assert_array_equal(dpnp.concatenate((r4, r3)), r4 + r3)
156+
assert_array_equal(dpnp.concatenate((r4, r3)), r4 + r3)
56157
# Mixed sequence types
57-
numpy.testing.assert_array_equal(dpnp.concatenate((tuple(r4), r3)), r4 + r3)
58-
numpy.testing.assert_array_equal(
158+
assert_array_equal(dpnp.concatenate((tuple(r4), r3)), r4 + r3)
159+
assert_array_equal(
59160
dpnp.concatenate((dpnp.array(r4), r3)), r4 + r3
60161
)
61162
# Explicit axis specification
62-
numpy.testing.assert_array_equal(dpnp.concatenate((r4, r3), 0), r4 + r3)
163+
assert_array_equal(dpnp.concatenate((r4, r3), 0), r4 + r3)
63164
# Including negative
64-
numpy.testing.assert_array_equal(dpnp.concatenate((r4, r3), -1), r4 + r3)
165+
assert_array_equal(dpnp.concatenate((r4, r3), -1), r4 + r3)
65166
# 2D
66167
a23 = dpnp.array([[10, 11, 12], [13, 14, 15]])
67168
a13 = dpnp.array([[0, 1, 2]])
68169
res = dpnp.array([[10, 11, 12], [13, 14, 15], [0, 1, 2]])
69-
numpy.testing.assert_array_equal(dpnp.concatenate((a23, a13)), res)
70-
numpy.testing.assert_array_equal(dpnp.concatenate((a23, a13), 0), res)
71-
numpy.testing.assert_array_equal(dpnp.concatenate((a23.T, a13.T), 1), res.T)
72-
numpy.testing.assert_array_equal(dpnp.concatenate((a23.T, a13.T), -1), res.T)
170+
assert_array_equal(dpnp.concatenate((a23, a13)), res)
171+
assert_array_equal(dpnp.concatenate((a23, a13), 0), res)
172+
assert_array_equal(dpnp.concatenate((a23.T, a13.T), 1), res.T)
173+
assert_array_equal(dpnp.concatenate((a23.T, a13.T), -1), res.T)
73174
# Arrays much match shape
74-
numpy.testing.assert_raises(ValueError, dpnp.concatenate, (a23.T, a13.T), 0)
175+
assert_raises(ValueError, dpnp.concatenate, (a23.T, a13.T), 0)
75176
# 3D
76177
res = dpnp.reshape(dpnp.arange(2 * 3 * 7), (2, 3, 7))
77178
a0 = res[..., :4]
78179
a1 = res[..., 4:6]
79180
a2 = res[..., 6:]
80-
numpy.testing.assert_array_equal(dpnp.concatenate((a0, a1, a2), 2), res)
81-
numpy.testing.assert_array_equal(dpnp.concatenate((a0, a1, a2), -1), res)
82-
numpy.testing.assert_array_equal(dpnp.concatenate((a0.T, a1.T, a2.T), 0), res.T)
181+
assert_array_equal(dpnp.concatenate((a0, a1, a2), 2), res)
182+
assert_array_equal(dpnp.concatenate((a0, a1, a2), -1), res)
183+
assert_array_equal(dpnp.concatenate((a0.T, a1.T, a2.T), 0), res.T)
83184

84185
out = dpnp.copy(res)
85186
rout = dpnp.concatenate((a0, a1, a2), 2, out=out)
86-
numpy.testing.assert_(out is rout)
87-
numpy.testing.assert_equal(res, rout)
187+
assert_(out is rout)
188+
assert_equal(res, rout)
88189

89190

90191
class TestHstack:
91192
def test_non_iterable(self):
92-
numpy.testing.assert_raises(TypeError, dpnp.hstack, 1)
193+
assert_raises(TypeError, dpnp.hstack, 1)
93194

94195
@pytest.mark.usefixtures("allow_fall_back_on_numpy")
95196
def test_empty_input(self):
96-
numpy.testing.assert_raises(ValueError, dpnp.hstack, ())
197+
assert_raises(ValueError, dpnp.hstack, ())
97198

98199
@pytest.mark.usefixtures("allow_fall_back_on_numpy")
99200
def test_0D_array(self):
100201
b = dpnp.array(2)
101202
a = dpnp.array(1)
102203
res = dpnp.hstack([a, b])
103204
desired = dpnp.array([1, 2])
104-
numpy.testing.assert_array_equal(res, desired)
205+
assert_array_equal(res, desired)
105206

106207
@pytest.mark.usefixtures("allow_fall_back_on_numpy")
107208
def test_1D_array(self):
108209
a = dpnp.array([1])
109210
b = dpnp.array([2])
110211
res = dpnp.hstack([a, b])
111212
desired = dpnp.array([1, 2])
112-
numpy.testing.assert_array_equal(res, desired)
213+
assert_array_equal(res, desired)
113214

114215
@pytest.mark.usefixtures("allow_fall_back_on_numpy")
115216
def test_2D_array(self):
116217
a = dpnp.array([[1], [2]])
117218
b = dpnp.array([[1], [2]])
118219
res = dpnp.hstack([a, b])
119220
desired = dpnp.array([[1, 1], [2, 2]])
120-
numpy.testing.assert_array_equal(res, desired)
221+
assert_array_equal(res, desired)
121222

122223
def test_generator(self):
123-
with numpy.testing.assert_warns(FutureWarning):
224+
with assert_warns(FutureWarning):
124225
dpnp.hstack((numpy.arange(3) for _ in range(2)))
125-
with numpy.testing.assert_warns(FutureWarning):
226+
with assert_warns(FutureWarning):
126227
dpnp.hstack(map(lambda x: x, numpy.ones((3, 2))))
127228

128229

129230
class TestVstack:
130231
def test_non_iterable(self):
131-
numpy.testing.assert_raises(TypeError, dpnp.vstack, 1)
232+
assert_raises(TypeError, dpnp.vstack, 1)
132233

133234
@pytest.mark.usefixtures("allow_fall_back_on_numpy")
134235
def test_empty_input(self):
135-
numpy.testing.assert_raises(ValueError, dpnp.vstack, ())
236+
assert_raises(ValueError, dpnp.vstack, ())
136237

137238
@pytest.mark.usefixtures("allow_fall_back_on_numpy")
138239
def test_0D_array(self):
139240
a = dpnp.array(1)
140241
b = dpnp.array(2)
141242
res = dpnp.vstack([a, b])
142243
desired = dpnp.array([[1], [2]])
143-
numpy.testing.assert_array_equal(res, desired)
244+
assert_array_equal(res, desired)
144245

145246
@pytest.mark.usefixtures("allow_fall_back_on_numpy")
146247
def test_1D_array(self):
147248
a = dpnp.array([1])
148249
b = dpnp.array([2])
149250
res = dpnp.vstack([a, b])
150251
desired = dpnp.array([[1], [2]])
151-
numpy.testing.assert_array_equal(res, desired)
252+
assert_array_equal(res, desired)
152253

153254
@pytest.mark.usefixtures("allow_fall_back_on_numpy")
154255
def test_2D_array(self):
155256
a = dpnp.array([[1], [2]])
156257
b = dpnp.array([[1], [2]])
157258
res = dpnp.vstack([a, b])
158259
desired = dpnp.array([[1], [2], [1], [2]])
159-
numpy.testing.assert_array_equal(res, desired)
260+
assert_array_equal(res, desired)
160261

161262
@pytest.mark.usefixtures("allow_fall_back_on_numpy")
162263
def test_2D_array2(self):
163264
a = dpnp.array([1, 2])
164265
b = dpnp.array([1, 2])
165266
res = dpnp.vstack([a, b])
166267
desired = dpnp.array([[1, 2], [1, 2]])
167-
numpy.testing.assert_array_equal(res, desired)
268+
assert_array_equal(res, desired)
168269

169270
def test_generator(self):
170-
with numpy.testing.assert_warns(FutureWarning):
271+
with assert_warns(FutureWarning):
171272
dpnp.vstack((numpy.arange(3) for _ in range(2)))

0 commit comments

Comments
 (0)