Skip to content

Commit cb29813

Browse files
committed
update dpnp.ravel
1 parent 818bf80 commit cb29813

File tree

3 files changed

+125
-14
lines changed

3 files changed

+125
-14
lines changed

dpnp/dpnp_iface_manipulation.py

Lines changed: 52 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1849,23 +1849,50 @@ def ravel(a, order="C"):
18491849
x : {dpnp.ndarray, usm_ndarray}
18501850
Input array. The elements in `a` are read in the order specified by
18511851
order, and packed as a 1-D array.
1852-
order : {"C", "F"}, optional
1852+
order : {None, "C", "F", "A"}, optional
18531853
The elements of `a` are read using this index order. ``"C"`` means to
18541854
index the elements in row-major, C-style order, with the last axis
18551855
index changing fastest, back to the first axis index changing slowest.
18561856
``"F"`` means to index the elements in column-major, Fortran-style
18571857
order, with the first index changing fastest, and the last index
1858-
changing slowest. By default, ``"C"`` index order is used.
1858+
changing slowest. Note that the "C" and "F" options take no account of
1859+
the memory layout of the underlying array, and only refer to
1860+
the order of axis indexing. "A" means to read the elements in
1861+
Fortran-like index order if `a` is Fortran *contiguous* in
1862+
memory, C-like order otherwise. ``order=None`` is an alias for
1863+
``order="C"``.
1864+
Default: ``"C"``.
18591865
18601866
Returns
18611867
-------
18621868
out : dpnp.ndarray
18631869
A contiguous 1-D array of the same subtype as `a`, with shape (a.size,).
18641870
1871+
Limitations
1872+
-----------
1873+
`order="K"` is not supported and the function raises `NotImplementedError`
1874+
exception.
1875+
18651876
See Also
18661877
--------
1867-
:obj:`dpnp.reshape` : Change the shape of an array without changing its
1868-
data.
1878+
:obj:`dpnp.ndarray.flat` : 1-D iterator over an array.
1879+
:obj:`dpnp.ndarray.flatten` : 1-D array copy of the elements of an array
1880+
in row-major order.
1881+
:obj:`dpnp.ndarray.reshape` : Change the shape of an array without
1882+
changing its data.
1883+
:obj:`dpnp.reshape` : The same as :obj:`dpnp.ndarray.reshape`.
1884+
1885+
Notes
1886+
-----
1887+
In row-major, C-style order, in two dimensions, the row index
1888+
varies the slowest, and the column index the quickest. This can
1889+
be generalized to multiple dimensions, where row-major order
1890+
implies that the index along the first axis varies slowest, and
1891+
the index along the last quickest. The opposite holds for
1892+
column-major, Fortran-style index ordering.
1893+
1894+
When a view is desired in as many cases as possible, ``arr.reshape(-1)``
1895+
may be preferable.
18691896
18701897
Examples
18711898
--------
@@ -1880,9 +1907,26 @@ def ravel(a, order="C"):
18801907
>>> np.ravel(x, order='F')
18811908
array([1, 4, 2, 5, 3, 6])
18821909
1910+
When ``order`` is 'A', it will preserve the array's 'C' or 'F' ordering:
1911+
1912+
>>> np.ravel(x.T)
1913+
array([1, 4, 2, 5, 3, 6])
1914+
>>> np.ravel(x.T, order='A')
1915+
array([1, 2, 3, 4, 5, 6])
1916+
18831917
"""
18841918

1885-
return dpnp.reshape(a, -1, order=order)
1919+
if order in "kK":
1920+
raise NotImplementedError(
1921+
"Keyword argument `order` is supported only with "
1922+
f"values None, 'C', 'F', and 'A', but got '{order}'"
1923+
)
1924+
1925+
result = dpnp.reshape(a, -1, order=order)
1926+
if result.flags.c_contiguous:
1927+
return result
1928+
1929+
return dpnp.ascontiguousarray(result)
18861930

18871931

18881932
def repeat(a, repeats, axis=None):
@@ -2071,8 +2115,6 @@ def reshape(a, /, shape=None, order="C", *, newshape=None, copy=None):
20712115
an integer, then the result will be a 1-D array of that length.
20722116
One shape dimension can be -1. In this case, the value is
20732117
inferred from the length of the array and remaining dimensions.
2074-
newshape : int or tuple of ints
2075-
Replaced by `shape` argument. Retained for backward compatibility.
20762118
order : {None, "C", "F", "A"}, optional
20772119
Read the elements of `a` using this index order, and place the
20782120
elements into the reshaped array using this index order. ``"C"``
@@ -2087,6 +2129,8 @@ def reshape(a, /, shape=None, order="C", *, newshape=None, copy=None):
20872129
read / write the elements in Fortran-like index order if ``a`` is
20882130
Fortran *contiguous* in memory, C-like order otherwise.
20892131
Default: ``"C"``.
2132+
newshape : int or tuple of ints
2133+
Replaced by `shape` argument. Retained for backward compatibility.
20902134
copy : {None, bool}, optional
20912135
If ``True``, then the array data is copied. If ``None``, a copy will
20922136
only be made if it's required by ``order``. For ``False`` it raises
@@ -2109,7 +2153,7 @@ def reshape(a, /, shape=None, order="C", *, newshape=None, copy=None):
21092153
It is not always possible to change the shape of an array without copying
21102154
the data.
21112155
2112-
The ``order`` keyword gives the index ordering both for *fetching*
2156+
The `order` keyword gives the index ordering both for *fetching*
21132157
the values from ``a``, and then *placing* the values into the output
21142158
array. For example, let's say you have an array:
21152159

tests/test_manipulation.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -448,6 +448,22 @@ def test_no_copy(self):
448448
assert_array_equal(b, a)
449449

450450

451+
class TestRavel:
452+
def test_error(self):
453+
ia = dpnp.arange(10).reshape(2, 5)
454+
assert_raises(NotImplementedError, dpnp.ravel, ia, order="K")
455+
456+
@pytest.mark.parametrize("order", ["C", "F", "A"])
457+
def test_non_contiguous(self, order):
458+
a = numpy.arange(10)[::2]
459+
ia = dpnp.arange(10)[::2]
460+
expected = numpy.ravel(a, order=order)
461+
result = dpnp.ravel(ia, order=order)
462+
assert result.flags.c_contiguous == expected.flags.c_contiguous
463+
assert result.flags.f_contiguous == expected.flags.f_contiguous
464+
assert_array_equal(result, expected)
465+
466+
451467
class TestRepeat:
452468
@pytest.mark.parametrize(
453469
"data",

tests/third_party/cupy/manipulation_tests/test_shape.py

Lines changed: 57 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -142,29 +142,80 @@ def test_ndim_limit2(self, dtype, order):
142142

143143

144144
class TestRavel:
145-
@testing.for_orders("CF")
146-
# order = 'A' is out of support currently
145+
@testing.for_orders("CFA")
146+
# order = 'K' is not supported currently
147147
@testing.numpy_cupy_array_equal()
148148
def test_ravel(self, xp, order):
149149
a = testing.shaped_arange((2, 3, 4), xp)
150150
a = a.transpose(2, 0, 1)
151151
return a.ravel(order)
152152

153-
@testing.for_orders("CF")
154-
# order = 'A' is out of support currently
153+
@testing.for_orders("CFA")
154+
# order = 'K' is not supported currently
155155
@testing.numpy_cupy_array_equal()
156156
def test_ravel2(self, xp, order):
157157
a = testing.shaped_arange((2, 3, 4), xp)
158158
return a.ravel(order)
159159

160-
@testing.for_orders("CF")
161-
# order = 'A' is out of support currently
160+
@testing.for_orders("CFA")
161+
# order = 'K' is not supported currently
162162
@testing.numpy_cupy_array_equal()
163163
def test_ravel3(self, xp, order):
164164
a = testing.shaped_arange((2, 3, 4), xp)
165165
a = xp.asfortranarray(a)
166166
return a.ravel(order)
167167

168+
@testing.for_orders("CFA")
169+
# order = 'K' is not supported currently
170+
@testing.numpy_cupy_array_equal()
171+
def test_ravel4(self, xp, order):
172+
a = testing.shaped_arange((2, 3, 4), xp)
173+
a = a.transpose(0, 2, 1)[:, ::-2]
174+
return a.ravel(order)
175+
176+
@testing.for_orders("CFA")
177+
# order = 'K' is not supported currently
178+
@testing.numpy_cupy_array_equal()
179+
def test_ravel_non_contiguous(self, xp, order):
180+
a = xp.arange(10)[::2]
181+
assert not a.flags.c_contiguous and not a.flags.f_contiguous
182+
b = a.ravel(order)
183+
assert b.flags.c_contiguous
184+
return b
185+
186+
@testing.for_orders("CFA")
187+
# order = 'K' is not supported currently
188+
@testing.numpy_cupy_array_equal()
189+
def test_ravel_broadcasted(self, xp, order):
190+
a = xp.array([1])
191+
b = xp.broadcast_to(a, (10,))
192+
assert not b.flags.c_contiguous and not b.flags.f_contiguous
193+
b = b.ravel(order)
194+
assert b.flags.c_contiguous
195+
return b
196+
197+
@testing.for_orders("CFA")
198+
# order = 'K' is not supported currently
199+
@testing.numpy_cupy_array_equal()
200+
def test_ravel_broadcasted2(self, xp, order):
201+
a = testing.shaped_arange((2, 1), xp)
202+
b = xp.broadcast_to(a, (3, 2, 4))
203+
assert not b.flags.c_contiguous and not b.flags.f_contiguous
204+
b = b.ravel(order)
205+
assert b.flags.c_contiguous
206+
return b
207+
208+
@testing.for_orders("CFA")
209+
# order = 'K' is not supported currently
210+
@testing.for_orders("CF", name="a_order")
211+
@testing.numpy_cupy_array_equal()
212+
def test_ravel_broadcasted3(self, xp, order, a_order):
213+
a = testing.shaped_arange((2, 1, 3), xp, order=a_order)
214+
b = xp.broadcast_to(a, (2, 4, 3))
215+
b = b.ravel(order)
216+
assert b.flags.c_contiguous
217+
return b
218+
168219
@testing.numpy_cupy_array_equal()
169220
def test_external_ravel(self, xp):
170221
a = testing.shaped_arange((2, 3, 4), xp)

0 commit comments

Comments
 (0)