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

Add copy keyword to dpnp.asarray and align dpnp.array(..., copy=None) with NumPy 2.0 #2006

Merged
merged 6 commits into from
Aug 21, 2024
Merged
34 changes: 24 additions & 10 deletions dpnp/dpnp_iface_arraycreation.py
Original file line number Diff line number Diff line change
Expand Up @@ -233,17 +233,24 @@ def array(
The desired dtype for the array. If not given, a default dtype will be
used that can represent the values (by considering Promotion Type Rule
and device capabilities when necessary).
copy : bool, optional
If ``True`` (default), then the object is copied.
Default: ``None``.
copy : {None, bool}, optional
If ``True``, then the array data is copied. If ``None``, a copy will
only be made if a copy is needed to satisfy any of the requirements
(``dtype``, ``order``, etc.). For ``False`` it raises a ``ValueError``
exception if a copy can not be avoided.
Default: ``True``.
order : {"C", "F", "A", "K"}, optional
Memory layout of the newly output array. Default: "K".
Memory layout of the newly output array.
Default: "K".
device : {None, string, SyclDevice, SyclQueue}, optional
An array API concept of device where the output array is created.
The `device` can be ``None`` (the default), an OneAPI filter selector
string, an instance of :class:`dpctl.SyclDevice` corresponding to
a non-partitioned SYCL device, an instance of :class:`dpctl.SyclQueue`,
or a `Device` object returned by
:obj:`dpnp.dpnp_array.dpnp_array.device` property.
Default: ``None``.
usm_type : {None, "device", "shared", "host"}, optional
The type of SYCL USM allocation for the output array.
Default: ``None``.
Expand Down Expand Up @@ -322,11 +329,6 @@ def array(
f"default value ``0``, but got {ndmin}"
)

# `False`` in numpy means exactly the same like `None` in python array API:
# that is to reuse existing memory buffer if possible or to copy otherwise.
if copy is False:
copy = None

return dpnp_container.asarray(
a,
dtype=dtype,
Expand Down Expand Up @@ -443,10 +445,12 @@ def asarray(
a,
dtype=None,
order=None,
like=None,
*,
device=None,
usm_type=None,
sycl_queue=None,
copy=None,
like=None,
):
"""
Converts an input object into array.
Expand All @@ -463,15 +467,18 @@ def asarray(
The desired dtype for the array. If not given, a default dtype will be
used that can represent the values (by considering Promotion Type Rule
and device capabilities when necessary).
Default: ``None``.
order : {None, "C", "F", "A", "K"}, optional
Memory layout of the newly output array. Default: "K".
Memory layout of the newly output array.
Default: "K".
device : {None, string, SyclDevice, SyclQueue}, optional
An array API concept of device where the output array is created.
The `device` can be ``None`` (the default), an OneAPI filter selector
string, an instance of :class:`dpctl.SyclDevice` corresponding to
a non-partitioned SYCL device, an instance of :class:`dpctl.SyclQueue`,
or a `Device` object returned by
:obj:`dpnp.dpnp_array.dpnp_array.device` property.
Default: ``None``.
usm_type : {None, "device", "shared", "host"}, optional
The type of SYCL USM allocation for the output array.
Default: ``None``.
Expand All @@ -481,6 +488,12 @@ def asarray(
to get the SYCL queue from `device` keyword if present or to use
a default queue.
Default: ``None``.
copy : {None, bool}, optional
If ``True``, then the array data is copied. If ``None``, a copy will
only be made if a copy is needed to satisfy any of the requirements
(``dtype``, ``order``, etc.). For ``False`` it raises a ``ValueError``
exception if a copy can not be avoided.
Default: ``True``.

Returns
-------
Expand Down Expand Up @@ -533,6 +546,7 @@ def asarray(
return dpnp_container.asarray(
a,
dtype=dtype,
copy=copy,
order=order,
device=device,
usm_type=usm_type,
Expand Down
2 changes: 1 addition & 1 deletion dpnp/dpnp_utils/dpnp_utils_linearalgebra.py
Original file line number Diff line number Diff line change
Expand Up @@ -925,7 +925,7 @@ def dpnp_matmul(
# If `order` was not passed as default
# we need to update it to match the passed `order`.
if order not in ["k", "K"]:
return dpnp.array(result, copy=False, order=order)
return dpnp.asarray(result, order=order)
# dpnp.ascontiguousarray changes 0-D array to 1-D array
if result.ndim == 0:
return result
Expand Down
21 changes: 18 additions & 3 deletions tests/third_party/cupy/creation_tests/test_from_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,12 @@ def test_array_copy_list_of_cupy_with_dtype_char(
@testing.numpy_cupy_array_equal()
def test_array_no_copy(self, xp, dtype, order):
a = testing.shaped_arange((2, 3, 4), xp, dtype)
b = xp.array(a, copy=False, order=order)
if xp is numpy and numpy.lib.NumpyVersion(numpy.__version__) < "2.0.0":
# copy keyword behavior changes in asarray, array since numpy 2.0
copy_flag = False
else:
copy_flag = None
b = xp.array(a, copy=copy_flag, order=order)
a.fill(0)
return b

Expand All @@ -313,14 +318,24 @@ def test_array_no_copy(self, xp, dtype, order):
@testing.numpy_cupy_array_equal()
def test_array_f_contiguous_input(self, xp, dtype, order):
a = testing.shaped_arange((2, 3, 4), xp, dtype, order="F")
b = xp.array(a, copy=False, order=order)
if xp is numpy and numpy.lib.NumpyVersion(numpy.__version__) < "2.0.0":
# copy keyword behavior changes in asarray, array since numpy 2.0
copy_flag = False
else:
copy_flag = None
b = xp.array(a, copy=copy_flag, order=order)
return b

@testing.for_all_dtypes()
@testing.numpy_cupy_array_equal()
def test_array_f_contiguous_output(self, xp, dtype):
a = testing.shaped_arange((2, 3, 4), xp, dtype)
b = xp.array(a, copy=False, order="F")
if xp is numpy and numpy.lib.NumpyVersion(numpy.__version__) < "2.0.0":
# copy keyword behavior changes in asarray, array since numpy 2.0
copy_flag = False
else:
copy_flag = None
b = xp.array(a, copy=copy_flag, order="F")
assert b.flags.f_contiguous
return b

Expand Down
Loading