Skip to content

Align signature of dpnp.astype with Python array API #2318

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

Merged
merged 15 commits into from
Feb 20, 2025
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
100 changes: 53 additions & 47 deletions dpnp/dpnp_array.py
Original file line number Diff line number Diff line change
Expand Up @@ -789,47 +789,51 @@ def astype(

Parameters
----------
x1 : {dpnp.ndarray, usm_ndarray}
Array data type casting.
dtype : {None, str, dtype object}
Target data type.
order : {"C", "F", "A", "K"}, optional
order : {None, "C", "F", "A", "K"}, optional
Row-major (C-style) or column-major (Fortran-style) order.
When ``order`` is 'A', it uses 'F' if ``a`` is column-major and uses 'C' otherwise.
And when ``order`` is 'K', it keeps strides as closely as possible.
copy : bool
If it is False and no cast happens, then this method returns the array itself.
Otherwise, a copy is returned.
casting : {'no', 'equiv', 'safe', 'same_kind', 'unsafe'}, optional
Controls what kind of data casting may occur.
Defaults to ``'unsafe'`` for backwards compatibility.

- 'no' means the data types should not be cast at all.
- 'equiv' means only byte-order changes are allowed.
- 'safe' means only casts which can preserve values are allowed.
- 'same_kind' means only safe casts or casts within a kind, like
float64 to float32, are allowed.
- 'unsafe' means any data conversions may be done.

copy : {bool}, optional
By default, ``astype`` always returns a newly allocated array. If
this is set to ``False``, and the `dtype`, `order`, and `subok`
requirements are satisfied, the input array is returned instead of
a copy.
device : {None, string, SyclDevice, SyclQueue}, optional
When `order` is ``"A"``, it uses ``"F"`` if `a` is column-major and
uses ``"C"`` otherwise. And when `order` is ``"K"``, it keeps
strides as closely as possible.

Default: ``"K"``.
casting : {"no", "equiv", "safe", "same_kind", "unsafe"}, optional
Controls what kind of data casting may occur. Defaults to
``"unsafe"`` for backwards compatibility.

- "no" means the data types should not be cast at all.
- "equiv" means only byte-order changes are allowed.
- "safe" means only casts which can preserve values are allowed.
- "same_kind" means only safe casts or casts within a kind,
like float64 to float32, are allowed.
- "unsafe" means any data conversions may be done.

Default: ``"unsafe"``.
copy : bool, optional
Specifies whether to copy an array when the specified dtype matches
the data type of that array. If ``True``, a newly allocated array
must always be returned. If ``False`` and the specified dtype
matches the data type of that array, the self array must be returned;
otherwise, a newly allocated array must be returned.

Default: ``True``.
device : {None, string, SyclDevice, SyclQueue, Device}, 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``.
`device` can be ``None``, a 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 :class:`dpctl.tensor.Device` object
returned by :attr:`dpnp.ndarray.device`.
If the value is ``None``, returned array is created on the same
device as that array.

Default: ``None``.

Returns
-------
arr_t : dpnp.ndarray
Unless `copy` is ``False`` and the other conditions for returning the input array
are satisfied, `arr_t` is a new array of the same shape as the input array,
with dtype, order given by dtype, order.
out : dpnp.ndarray
An array having the specified data type.

Limitations
-----------
Expand All @@ -839,9 +843,9 @@ def astype(
Examples
--------
>>> import dpnp as np
>>> x = np.array([1, 2, 2.5])
>>> x
>>> x = np.array([1, 2, 2.5]); x
array([1. , 2. , 2.5])

>>> x.astype(int)
array([1, 2, 2])

Expand Down Expand Up @@ -925,13 +929,14 @@ def copy(self, order="C", device=None, usm_type=None, sycl_queue=None):
order : {"C", "F", "A", "K"}, optional
Memory layout of the newly output array.
Default: ``"C"``.
device : {None, string, SyclDevice, SyclQueue}, optional
device : {None, string, SyclDevice, SyclQueue, Device}, 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.
`device` can be ``None``, a 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 :class:`dpctl.tensor.Device` object
returned by :attr:`dpnp.ndarray.device`.

Default: ``None``.
usm_type : {None, "device", "shared", "host"}, optional
The type of SYCL USM allocation for the output array.
Expand Down Expand Up @@ -1821,12 +1826,13 @@ def to_device(self, device, /, *, stream=None):

Parameters
----------
device : {string, SyclDevice, SyclQueue}
Array API concept of target device. It can be an OneAPI filter
selector string, an instance of :class:`dpctl.SyclDevice`
corresponding to a non-partitioned SYCL device, an instance of
device : {None, string, SyclDevice, SyclQueue, Device}, optional
An array API concept of device where the output array is created.
`device` can be ``None``, a 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 :class:`dpctl.tensor.Device` object
returned by :obj:`dpnp.dpnp_array.dpnp_array.device` property.
returned by :attr:`dpnp.ndarray.device`.
stream : {SyclQueue, None}, optional
Execution queue to synchronize with. If ``None``, synchronization
is not performed.
Expand Down
150 changes: 56 additions & 94 deletions dpnp/dpnp_iface.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@

"""
# pylint: disable=protected-access
# pylint: disable=redefined-outer-name

import os

Expand All @@ -57,7 +58,6 @@
__all__ = [
"are_same_logical_tensors",
"asnumpy",
"astype",
"as_usm_ndarray",
"check_limitations",
"check_supported_arrays_type",
Expand All @@ -74,7 +74,6 @@
"synchronize_array_data",
]

from dpnp import float64
from dpnp.dpnp_iface_arraycreation import *
from dpnp.dpnp_iface_arraycreation import __all__ as __all__arraycreation
from dpnp.dpnp_iface_bitwise import *
Expand Down Expand Up @@ -182,11 +181,13 @@ def asnumpy(a, order="C"):
----------
a : {array_like}
Arbitrary object that can be converted to :obj:`numpy.ndarray`.
order : {'C', 'F', 'A', 'K'}
order : {None, 'C', 'F', 'A', 'K'}, optional
The desired memory layout of the converted array.
When `order` is ``A``, it uses ``F`` if `a` is column-major and uses
``C`` otherwise. And when `order` is ``K``, it keeps strides as closely
as possible.
When `order` is ``'A'``, it uses ``'F'`` if `a` is column-major and
uses ``'C'`` otherwise. And when `order` is ``'K'``, it keeps strides
as closely as possible.

Default: ``'C'``.

Returns
-------
Expand All @@ -208,71 +209,6 @@ def asnumpy(a, order="C"):
return numpy.asarray(a, order=order)


# pylint: disable=redefined-outer-name
def astype(x1, dtype, order="K", casting="unsafe", copy=True, device=None):
"""
Copy the array with data type casting.

Parameters
----------
x1 : {dpnp.ndarray, usm_ndarray}
Array data type casting.
dtype : {None, str, dtype object}
Target data type.
order : {'C', 'F', 'A', 'K'}
Row-major (C-style) or column-major (Fortran-style) order.
When `order` is ``A``, it uses ``F`` if `a` is column-major and uses
``C`` otherwise. And when `order` is ``K``, it keeps strides as closely
as possible.
copy : bool
If it is ``False`` and no cast happens, then this method returns
the array itself. Otherwise, a copy is returned.
casting : {'no', 'equiv', 'safe', 'same_kind', 'unsafe'}, optional
Controls what kind of data casting may occur. Defaults to ``unsafe``
for backwards compatibility.

- 'no' means the data types should not be cast at all.
- 'equiv' means only byte-order changes are allowed.
- 'safe' means only casts which can preserve values are allowed.
- 'same_kind' means only safe casts or casts within a kind, like
float64 to float32, are allowed.
- 'unsafe' means any data conversions may be done.

copy : {bool}, optional
By default, ``astype`` always returns a newly allocated array. If this
is set to ``False``, and the `dtype`, `order`, and `subok` requirements
are satisfied, the input array is returned instead of a copy.
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``.

Returns
-------
arr_t : dpnp.ndarray
Unless `copy` is ``False`` and the other conditions for returning
the input array are satisfied, `arr_t` is a new array of the same shape
as the input array, with dtype, order given by dtype, order.

"""

if order is None:
order = "K"

x1_obj = dpnp.get_usm_ndarray(x1)
array_obj = dpt.astype(
x1_obj, dtype, order=order, casting=casting, copy=copy, device=device
)

if array_obj is x1_obj and isinstance(x1, dpnp_array):
# return x1 if dpctl returns a zero copy of x1_obj
return x1
return dpnp_array._create_from_usm_ndarray(array_obj)


def as_usm_ndarray(a, dtype=None, device=None, usm_type=None, sycl_queue=None):
"""
Return :class:`dpctl.tensor.usm_ndarray` from input object `a`.
Expand All @@ -285,22 +221,27 @@ def as_usm_ndarray(a, dtype=None, device=None, usm_type=None, sycl_queue=None):
The desired dtype for the result array if new array is creating. 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``.
device : {None, string, SyclDevice, SyclQueue}, optional
An array API concept of device where the result array is created if
required.
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.
device : {None, string, SyclDevice, SyclQueue, Device}, optional
An array API concept of device where the output array is created.
`device` can be ``None``, a 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
:class:`dpctl.tensor.Device` object returned by
:attr:`dpnp.ndarray.device`.
If the value is ``None``, returned array is created on the same device
as `a`.

Default: ``None``.
usm_type : {None, "device", "shared", "host"}, optional
The type of SYCL USM allocation for the result array if new array
is created.

Default: ``None``.
sycl_queue : {None, SyclQueue}, optional
A SYCL queue to use for result array allocation if required.

Default: ``None``.

Returns
Expand Down Expand Up @@ -391,11 +332,15 @@ def check_supported_arrays_type(*arrays, scalar_type=False, all_scalars=False):
----------
arrays : {dpnp.ndarray, usm_ndarray}
Input arrays to check for supported types.
scalar_type : {bool}, optional
scalar_type : bool, optional
A scalar type is also considered as supported if flag is ``True``.
all_scalars : {bool}, optional

Default: ``False``.
all_scalars : bool, optional
All the input arrays can be scalar if flag is ``True``.

Default: ``False``.

Returns
-------
out : bool
Expand Down Expand Up @@ -437,20 +382,24 @@ def default_float_type(device=None, sycl_queue=None):

Parameters
----------
device : {None, string, SyclDevice, SyclQueue}, optional
An array API concept of device where an array of default floating type
might be 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.
device : {None, string, SyclDevice, SyclQueue, Device}, optional
An array API concept of device where the output array is created.
`device` can be ``None``, a 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
:class:`dpctl.tensor.Device` object returned by
:attr:`dpnp.ndarray.device`.
The value ``None`` is interpreted as to use a default device.

Default: ``None``.
sycl_queue : {None, SyclQueue}, optional
A SYCL queue which might be used to create an array of default floating
type. The `sycl_queue` can be ``None`` (the default), which is
interpreted as to get the SYCL queue from `device` keyword if present
or to use a default queue.

Default: ``None``.

Returns
-------
dt : dtype
Expand All @@ -461,7 +410,7 @@ def default_float_type(device=None, sycl_queue=None):
_sycl_queue = get_normalized_queue_device(
device=device, sycl_queue=sycl_queue
)
return map_dtype_to_device(float64, _sycl_queue.sycl_device)
return map_dtype_to_device(dpnp.float64, _sycl_queue.sycl_device)


def get_dpnp_descriptor(
Expand Down Expand Up @@ -569,16 +518,24 @@ def get_normalized_queue_device(obj=None, device=None, sycl_queue=None):
and implementing `__sycl_usm_array_interface__` protocol, an instance
of `numpy.ndarray`, an object supporting Python buffer protocol,
a Python scalar, or a (possibly nested) sequence of Python scalars.
sycl_queue : class:`dpctl.SyclQueue`, optional
sycl_queue : {None, class:`dpctl.SyclQueue`}, optional
A queue which explicitly indicates where USM allocation is done
and the population code (if any) is executed.
Value ``None`` is interpreted as to get the SYCL queue from either
`obj` parameter if not ``None`` or from `device` keyword,
or to use default queue.
device : {string, :class:`dpctl.SyclDevice`, :class:`dpctl.SyclQueue,
:class:`dpctl.tensor.Device`}, optional
An array-API keyword indicating non-partitioned SYCL device
where array is allocated.

Default: ``None``.
device : {None, string, SyclDevice, SyclQueue, Device}, optional
An array API concept of device where the output array is created.
`device` can be ``None``, a 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
:class:`dpctl.tensor.Device` object returned by
:attr:`dpnp.ndarray.device`.
The value ``None`` is interpreted as to use the same device as `obj`.

Default: ``None``.

Returns
-------
Expand Down Expand Up @@ -616,9 +573,13 @@ def get_result_array(a, out=None, casting="safe"):
If provided, value of `a` array will be copied into it
according to ``safe`` casting rule.
It should be of the appropriate shape.

Default: ``None``.
casting : {'no', 'equiv', 'safe', 'same_kind', 'unsafe'}, optional
Controls what kind of data casting may occur.

Default: ``'safe'``.

Returns
-------
out : {dpnp_array}
Expand Down Expand Up @@ -714,6 +675,7 @@ def is_cuda_backend(obj=None):
An input object with sycl_device property to check device backend.
If `obj` is ``None``, device backend will be checked for the default
queue.

Default: ``None``.

Returns
Expand Down
Loading
Loading