Skip to content

Add support for order="K" or "A" for dpnp.empty_like, dpnp.ones_like, dpnp.zeros_like and dpnp.full_like #2088

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 7 commits into from
Oct 7, 2024
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
16 changes: 1 addition & 15 deletions dpnp/dpnp_iface.py
Original file line number Diff line number Diff line change
Expand Up @@ -320,14 +320,10 @@ def as_usm_ndarray(a, dtype=None, device=None, usm_type=None, sycl_queue=None):
)


def check_limitations(
order=None, subok=False, like=None, initial=None, where=True
):
def check_limitations(subok=False, like=None, initial=None, where=True):
"""
Checking limitation kwargs for their supported values.

Parameter `order` is only supported with values ``"C"``, ``"F"``,
and ``None``.
Parameter `subok` is only supported with default value ``False``.
Parameter `like` is only supported with default value ``None``.
Parameter `initial` is only supported with default value ``None``.
Expand All @@ -340,16 +336,6 @@ def check_limitations(

"""

if order in ("A", "a", "K", "k"):
raise NotImplementedError(
"Keyword argument `order` is supported only with "
f"values 'C' and 'F', but got '{order}'"
)
if order not in ("C", "c", "F", "f", None):
raise ValueError(
"Unrecognized `order` keyword value, expecting "
f"'C' or 'F', but got '{order}'"
)
if like is not None:
raise NotImplementedError(
"Keyword argument `like` is supported only with "
Expand Down
200 changes: 130 additions & 70 deletions dpnp/dpnp_iface_arraycreation.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,82 @@
]


def _get_empty_array(
a,
/,
*,
dtype=None,
order="K",
shape=None,
device=None,
usm_type=None,
sycl_queue=None,
):
"""
Get an empty array as the base for empty_like, ones_like, zeros_like,
and full_like.

"""
strides = None
if shape is None:
_shape = a.shape
elif dpnp.isscalar(shape):
_shape = (shape,)
else:
_shape = shape
_dtype = a.dtype if dtype is None else dtype
_usm_type = a.usm_type if usm_type is None else usm_type
_sycl_queue = dpnp.get_normalized_queue_device(
a, sycl_queue=sycl_queue, device=device
)

if order is None:
order = "K"
if order in "aA":
if a.flags.fnc:
order = "F"
else:
order = "C"
elif order in "kK":
if len(_shape) != a.ndim:
order = "C"
elif a.flags.f_contiguous:
order = "F"
elif a.flags.c_contiguous:
order = "C"
else:
strides = _get_strides_for_order_k(a, _shape)
order = "C"
elif order not in "cfCF":
raise ValueError(
f"order must be None, 'C', 'F', 'A', or 'K' (got '{order}')"
)

return dpnp_array(
_shape,
dtype=_dtype,
strides=strides,
order=order,
usm_type=_usm_type,
sycl_queue=_sycl_queue,
)


def _get_strides_for_order_k(x, shape=None):
"""
Calculate strides when order='K' for empty_like, ones_like, zeros_like,
and full_like where `shape` is ``None`` or len(shape) == x.ndim.

"""
stride_and_index = sorted([(abs(s), -i) for i, s in enumerate(x.strides)])
strides = [0] * x.ndim
stride = 1
for _, i in stride_and_index:
strides[-i] = stride
stride *= shape[-i] if shape else x.shape[-i]
return strides


def arange(
start,
/,
Expand Down Expand Up @@ -1206,7 +1282,7 @@ def empty_like(
/,
*,
dtype=None,
order="C",
order="K",
subok=False,
shape=None,
device=None,
Expand All @@ -1227,9 +1303,10 @@ def empty_like(
The desired dtype for the array, e.g., dpnp.int32.
Default is the default floating point data type for the device where
input array is allocated.
order : {None, "C", "F"}, optional
order : {None, "C", "F", "A", "K"}, optional
Memory layout of the newly output array.
Default: ``"C"``.
``order=None`` is an alias for ``order="K"``.
Default: ``"K"``.
shape : {None, int, sequence of ints}
Overrides the shape of the result.
device : {None, string, SyclDevice, SyclQueue}, optional
Expand All @@ -1256,8 +1333,6 @@ def empty_like(

Limitations
-----------
Parameter `order` is supported only with values ``"C"``, ``"F"`` and
``None``.
Parameter `subok` is supported only with default value ``False``.
Otherwise, the function raises `NotImplementedError` exception.

Expand Down Expand Up @@ -1295,20 +1370,16 @@ def empty_like(
"""

dpnp.check_supported_arrays_type(a)
dpnp.check_limitations(order=order, subok=subok)
dpnp.check_limitations(subok=subok)

_shape = a.shape if shape is None else shape
_dtype = a.dtype if dtype is None else dtype
_usm_type = a.usm_type if usm_type is None else usm_type
_sycl_queue = dpnp.get_normalized_queue_device(
a, sycl_queue=sycl_queue, device=device
)
return dpnp_container.empty(
_shape,
dtype=_dtype,
return _get_empty_array(
a,
dtype=dtype,
order=order,
usm_type=_usm_type,
sycl_queue=_sycl_queue,
shape=shape,
device=device,
usm_type=usm_type,
sycl_queue=sycl_queue,
)


Expand Down Expand Up @@ -2063,7 +2134,7 @@ def full_like(
fill_value,
*,
dtype=None,
order="C",
order="K",
subok=False,
shape=None,
device=None,
Expand All @@ -2088,9 +2159,10 @@ def full_like(
The desired dtype for the array, e.g., dpnp.int32.
Default is the default floating point data type for the device where
input array is allocated.
order : {None, "C", "F"}, optional
order : {None, "C", "F", "A", "K"}, optional
Memory layout of the newly output array.
Default: ``"C"``.
``order=None`` is an alias for ``order="K"``.
Default: ``"K"``.
shape : {None, int, sequence of ints}
Overrides the shape of the result.
device : {None, string, SyclDevice, SyclQueue}, optional
Expand All @@ -2117,8 +2189,6 @@ def full_like(

Limitations
-----------
Parameter `order` is supported only with values ``"C"``, ``"F"`` and
``None``.
Parameter `subok` is supported only with default value ``False``.
Otherwise, the function raises `NotImplementedError` exception.

Expand Down Expand Up @@ -2156,23 +2226,19 @@ def full_like(
"""

dpnp.check_supported_arrays_type(a)
dpnp.check_limitations(order=order, subok=subok)

_shape = a.shape if shape is None else shape
_dtype = a.dtype if dtype is None else dtype
_usm_type = a.usm_type if usm_type is None else usm_type
_sycl_queue = dpnp.get_normalized_queue_device(
a, sycl_queue=sycl_queue, device=device
)
dpnp.check_limitations(subok=subok)

return dpnp_container.full(
_shape,
fill_value,
dtype=_dtype,
res = _get_empty_array(
a,
dtype=dtype,
order=order,
usm_type=_usm_type,
sycl_queue=_sycl_queue,
shape=shape,
device=device,
usm_type=usm_type,
sycl_queue=sycl_queue,
)
dpnp.copyto(res, fill_value, casting="unsafe")
return res


def geomspace(
Expand Down Expand Up @@ -3112,7 +3178,7 @@ def ones_like(
/,
*,
dtype=None,
order="C",
order="K",
subok=False,
shape=None,
device=None,
Expand All @@ -3133,9 +3199,10 @@ def ones_like(
The desired dtype for the array, e.g., dpnp.int32.
Default is the default floating point data type for the device where
input array is allocated.
order : {None, "C", "F"}, optional
order : {None, "C", "F", "A", "K"}, optional
Memory layout of the newly output array.
Default: ``"C"``.
``order=None`` is an alias for ``order="K"``.
Default: ``"K"``.
shape : {None, int, sequence of ints}
Overrides the shape of the result.
device : {None, string, SyclDevice, SyclQueue}, optional
Expand All @@ -3162,8 +3229,6 @@ def ones_like(

Limitations
-----------
Parameter `order` is supported only with values ``"C"``, ``"F"`` and
``None``.
Parameter `subok` is supported only with default value ``False``.
Otherwise, the function raises `NotImplementedError` exception.

Expand Down Expand Up @@ -3202,21 +3267,19 @@ def ones_like(

"""
dpnp.check_supported_arrays_type(a)
dpnp.check_limitations(order=order, subok=subok)
dpnp.check_limitations(subok=subok)

_shape = a.shape if shape is None else shape
_dtype = a.dtype if dtype is None else dtype
_usm_type = a.usm_type if usm_type is None else usm_type
_sycl_queue = dpnp.get_normalized_queue_device(
a, sycl_queue=sycl_queue, device=device
)
return dpnp_container.ones(
_shape,
dtype=_dtype,
res = _get_empty_array(
a,
dtype=dtype,
order=order,
usm_type=_usm_type,
sycl_queue=_sycl_queue,
shape=shape,
device=device,
usm_type=usm_type,
sycl_queue=sycl_queue,
)
res.fill(1)
return res


def trace(a, offset=0, axis1=0, axis2=1, dtype=None, out=None):
Expand Down Expand Up @@ -3759,7 +3822,7 @@ def zeros_like(
/,
*,
dtype=None,
order="C",
order="K",
subok=False,
shape=None,
device=None,
Expand All @@ -3780,9 +3843,10 @@ def zeros_like(
The desired dtype for the array, e.g., dpnp.int32.
Default is the default floating point data type for the device where
input array is allocated.
order : {None, "C", "F"}, optional
order : {None, "C", "F", "A", "K"}, optional
Memory layout of the newly output array.
Default: ``"C"``.
``order=None`` is an alias for ``order="K"``.
Default: ``"K"``.
shape : {None, int, sequence of ints}
Overrides the shape of the result.
device : {None, string, SyclDevice, SyclQueue}, optional
Expand All @@ -3809,8 +3873,6 @@ def zeros_like(

Limitations
-----------
Parameter `order` is supported only with values ``"C"``, ``"F"`` and
``None``.
Parameter `subok` is supported only with default value ``False``.
Otherwise, the function raises `NotImplementedError` exception.

Expand Down Expand Up @@ -3850,18 +3912,16 @@ def zeros_like(
"""

dpnp.check_supported_arrays_type(a)
dpnp.check_limitations(order=order, subok=subok)
dpnp.check_limitations(subok=subok)

_shape = a.shape if shape is None else shape
_dtype = a.dtype if dtype is None else dtype
_usm_type = a.usm_type if usm_type is None else usm_type
_sycl_queue = dpnp.get_normalized_queue_device(
a, sycl_queue=sycl_queue, device=device
)
return dpnp_container.zeros(
_shape,
dtype=_dtype,
res = _get_empty_array(
a,
dtype=dtype,
order=order,
usm_type=_usm_type,
sycl_queue=_sycl_queue,
shape=shape,
device=device,
usm_type=usm_type,
sycl_queue=sycl_queue,
)
res.fill(0)
return res
Loading
Loading