Skip to content

Commit 1d4047c

Browse files
committed
Reworked dpnp.copyto() implementation through existing calls
1 parent 2f235bf commit 1d4047c

File tree

9 files changed

+608
-391
lines changed

9 files changed

+608
-391
lines changed

dpnp/backend/include/dpnp_iface_fptr.hpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,8 +139,6 @@ enum class DPNPFuncName : size_t
139139
DPNP_FN_COPYSIGN_EXT, /**< Used in numpy.copysign() impl, requires extra
140140
parameters */
141141
DPNP_FN_COPYTO, /**< Used in numpy.copyto() impl */
142-
DPNP_FN_COPYTO_EXT, /**< Used in numpy.copyto() impl, requires extra
143-
parameters */
144142
DPNP_FN_CORRELATE, /**< Used in numpy.correlate() impl */
145143
DPNP_FN_CORRELATE_EXT, /**< Used in numpy.correlate() impl, requires extra
146144
parameters */

dpnp/backend/kernels/dpnp_krnl_elemwise.cpp

Lines changed: 0 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -423,60 +423,6 @@ static void func_map_init_elemwise_1arg_2type(func_map_t &fmap)
423423
(void *)
424424
dpnp_copyto_c_default<std::complex<double>, std::complex<double>>};
425425

426-
fmap[DPNPFuncName::DPNP_FN_COPYTO_EXT][eft_BLN][eft_BLN] = {
427-
eft_BLN, (void *)dpnp_copyto_c_ext<bool, bool>};
428-
fmap[DPNPFuncName::DPNP_FN_COPYTO_EXT][eft_BLN][eft_INT] = {
429-
eft_INT, (void *)dpnp_copyto_c_ext<bool, int32_t>};
430-
fmap[DPNPFuncName::DPNP_FN_COPYTO_EXT][eft_BLN][eft_LNG] = {
431-
eft_LNG, (void *)dpnp_copyto_c_ext<bool, int64_t>};
432-
fmap[DPNPFuncName::DPNP_FN_COPYTO_EXT][eft_BLN][eft_FLT] = {
433-
eft_FLT, (void *)dpnp_copyto_c_ext<bool, float>};
434-
fmap[DPNPFuncName::DPNP_FN_COPYTO_EXT][eft_BLN][eft_DBL] = {
435-
eft_DBL, (void *)dpnp_copyto_c_ext<bool, double>};
436-
fmap[DPNPFuncName::DPNP_FN_COPYTO_EXT][eft_INT][eft_BLN] = {
437-
eft_BLN, (void *)dpnp_copyto_c_ext<int32_t, bool>};
438-
fmap[DPNPFuncName::DPNP_FN_COPYTO_EXT][eft_INT][eft_INT] = {
439-
eft_INT, (void *)dpnp_copyto_c_ext<int32_t, int32_t>};
440-
fmap[DPNPFuncName::DPNP_FN_COPYTO_EXT][eft_INT][eft_LNG] = {
441-
eft_LNG, (void *)dpnp_copyto_c_ext<int32_t, int64_t>};
442-
fmap[DPNPFuncName::DPNP_FN_COPYTO_EXT][eft_INT][eft_FLT] = {
443-
eft_FLT, (void *)dpnp_copyto_c_ext<int32_t, float>};
444-
fmap[DPNPFuncName::DPNP_FN_COPYTO_EXT][eft_INT][eft_DBL] = {
445-
eft_DBL, (void *)dpnp_copyto_c_ext<int32_t, double>};
446-
fmap[DPNPFuncName::DPNP_FN_COPYTO_EXT][eft_LNG][eft_BLN] = {
447-
eft_BLN, (void *)dpnp_copyto_c_ext<int64_t, bool>};
448-
fmap[DPNPFuncName::DPNP_FN_COPYTO_EXT][eft_LNG][eft_INT] = {
449-
eft_INT, (void *)dpnp_copyto_c_ext<int64_t, int32_t>};
450-
fmap[DPNPFuncName::DPNP_FN_COPYTO_EXT][eft_LNG][eft_LNG] = {
451-
eft_LNG, (void *)dpnp_copyto_c_ext<int64_t, int64_t>};
452-
fmap[DPNPFuncName::DPNP_FN_COPYTO_EXT][eft_LNG][eft_FLT] = {
453-
eft_FLT, (void *)dpnp_copyto_c_ext<int64_t, float>};
454-
fmap[DPNPFuncName::DPNP_FN_COPYTO_EXT][eft_LNG][eft_DBL] = {
455-
eft_DBL, (void *)dpnp_copyto_c_ext<int64_t, double>};
456-
fmap[DPNPFuncName::DPNP_FN_COPYTO_EXT][eft_FLT][eft_BLN] = {
457-
eft_BLN, (void *)dpnp_copyto_c_ext<float, bool>};
458-
fmap[DPNPFuncName::DPNP_FN_COPYTO_EXT][eft_FLT][eft_INT] = {
459-
eft_INT, (void *)dpnp_copyto_c_ext<float, int32_t>};
460-
fmap[DPNPFuncName::DPNP_FN_COPYTO_EXT][eft_FLT][eft_LNG] = {
461-
eft_LNG, (void *)dpnp_copyto_c_ext<float, int64_t>};
462-
fmap[DPNPFuncName::DPNP_FN_COPYTO_EXT][eft_FLT][eft_FLT] = {
463-
eft_FLT, (void *)dpnp_copyto_c_ext<float, float>};
464-
fmap[DPNPFuncName::DPNP_FN_COPYTO_EXT][eft_FLT][eft_DBL] = {
465-
eft_DBL, (void *)dpnp_copyto_c_ext<float, double>};
466-
fmap[DPNPFuncName::DPNP_FN_COPYTO_EXT][eft_DBL][eft_BLN] = {
467-
eft_BLN, (void *)dpnp_copyto_c_ext<double, bool>};
468-
fmap[DPNPFuncName::DPNP_FN_COPYTO_EXT][eft_DBL][eft_INT] = {
469-
eft_INT, (void *)dpnp_copyto_c_ext<double, int32_t>};
470-
fmap[DPNPFuncName::DPNP_FN_COPYTO_EXT][eft_DBL][eft_LNG] = {
471-
eft_LNG, (void *)dpnp_copyto_c_ext<double, int64_t>};
472-
fmap[DPNPFuncName::DPNP_FN_COPYTO_EXT][eft_DBL][eft_FLT] = {
473-
eft_FLT, (void *)dpnp_copyto_c_ext<double, float>};
474-
fmap[DPNPFuncName::DPNP_FN_COPYTO_EXT][eft_DBL][eft_DBL] = {
475-
eft_DBL, (void *)dpnp_copyto_c_ext<double, double>};
476-
fmap[DPNPFuncName::DPNP_FN_COPYTO_EXT][eft_C128][eft_C128] = {
477-
eft_C128,
478-
(void *)dpnp_copyto_c_ext<std::complex<double>, std::complex<double>>};
479-
480426
fmap[DPNPFuncName::DPNP_FN_COS][eft_INT][eft_INT] = {
481427
eft_DBL, (void *)dpnp_cos_c_default<int32_t, double>};
482428
fmap[DPNPFuncName::DPNP_FN_COS][eft_LNG][eft_LNG] = {

dpnp/dpnp_algo/dpnp_algo.pxd

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,6 @@ cdef extern from "dpnp_iface_fptr.hpp" namespace "DPNPFuncName": # need this na
8787
DPNP_FN_COPYSIGN
8888
DPNP_FN_COPYSIGN_EXT
8989
DPNP_FN_COPYTO
90-
DPNP_FN_COPYTO_EXT
9190
DPNP_FN_CORRELATE
9291
DPNP_FN_CORRELATE_EXT
9392
DPNP_FN_COSH

dpnp/dpnp_algo/dpnp_algo_manipulation.pxi

Lines changed: 0 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ and the rest of the library
3838
__all__ += [
3939
"dpnp_atleast_2d",
4040
"dpnp_atleast_3d",
41-
"dpnp_copyto",
4241
"dpnp_expand_dims",
4342
"dpnp_repeat",
4443
"dpnp_reshape",
@@ -105,45 +104,6 @@ cpdef utils.dpnp_descriptor dpnp_atleast_3d(utils.dpnp_descriptor arr):
105104
return arr
106105

107106

108-
cpdef dpnp_copyto(utils.dpnp_descriptor dst, utils.dpnp_descriptor src, where=True):
109-
# Convert string type names (array.dtype) to C enum DPNPFuncType
110-
cdef DPNPFuncType dst_type = dpnp_dtype_to_DPNPFuncType(dst.dtype)
111-
cdef DPNPFuncType src_type = dpnp_dtype_to_DPNPFuncType(src.dtype)
112-
113-
cdef shape_type_c dst_shape = dst.shape
114-
cdef shape_type_c dst_strides = utils.strides_to_vector(dst.strides, dst_shape)
115-
116-
cdef shape_type_c src_shape = src.shape
117-
cdef shape_type_c src_strides = utils.strides_to_vector(src.strides, src_shape)
118-
119-
# get the FPTR data structure
120-
cdef DPNPFuncData kernel_data = get_dpnp_function_ptr(DPNP_FN_COPYTO_EXT, src_type, dst_type)
121-
122-
_, _, result_sycl_queue = utils.get_common_usm_allocation(dst, src)
123-
124-
cdef c_dpctl.SyclQueue q = <c_dpctl.SyclQueue> result_sycl_queue
125-
cdef c_dpctl.DPCTLSyclQueueRef q_ref = q.get_queue_ref()
126-
127-
# Call FPTR function
128-
cdef fptr_1in_1out_strides_t func = <fptr_1in_1out_strides_t > kernel_data.ptr
129-
cdef c_dpctl.DPCTLSyclEventRef event_ref = func(q_ref,
130-
dst.get_data(),
131-
dst.size,
132-
dst.ndim,
133-
dst_shape.data(),
134-
dst_strides.data(),
135-
src.get_data(),
136-
src.size,
137-
src.ndim,
138-
src_shape.data(),
139-
src_strides.data(),
140-
NULL,
141-
NULL) # dep_events_ref
142-
143-
with nogil: c_dpctl.DPCTLEvent_WaitAndThrow(event_ref)
144-
c_dpctl.DPCTLEvent_Delete(event_ref)
145-
146-
147107
cpdef utils.dpnp_descriptor dpnp_expand_dims(utils.dpnp_descriptor in_array, axis):
148108
axis_tuple = utils._object_to_tuple(axis)
149109
result_ndim = len(axis_tuple) + in_array.ndim

dpnp/dpnp_iface_manipulation.py

Lines changed: 64 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -313,64 +313,79 @@ def copyto(dst, src, casting="same_kind", where=True):
313313
"""
314314
Copies values from one array to another, broadcasting as necessary.
315315
316+
Raises a ``TypeError`` if the `casting` rule is violated, and if
317+
`where` is provided, it selects which elements to copy.
318+
316319
For full documentation refer to :obj:`numpy.copyto`.
317320
318321
Limitations
319322
-----------
320-
Input arrays are supported as :obj:`dpnp.ndarray`.
321-
Otherwise the function will be executed sequentially on CPU.
322-
Parameter ``casting`` is supported only with default value ``"same_kind"``.
323-
Parameter ``where`` is supported only with default value ``True``.
324-
Shapes of input arrays are supported to be equal.
323+
The `dst` parameter is supported as either :class:`dpnp.ndarray`
324+
or :class:`dpctl.tensor.usm_ndarray`.
325+
The `where` parameter is supported as either :class:`dpnp.ndarray`,
326+
:class:`dpctl.tensor.usm_ndarray` or scalar.
327+
Otherwise ``TypeError`` exeption will be raised.
325328
Input array data types are limited by supported DPNP :ref:`Data types`.
326329
330+
Examples
331+
--------
332+
>>> import dpnp as np
333+
>>> A = np.array([4, 5, 6])
334+
>>> B = [1, 2, 3]
335+
>>> np.copyto(A, B)
336+
>>> A
337+
array([1, 2, 3])
338+
339+
>>> A = np.array([[1, 2, 3], [4, 5, 6]])
340+
>>> B = [[4, 5, 6], [7, 8, 9]]
341+
>>> np.copyto(A, B)
342+
>>> A
343+
array([[4, 5, 6],
344+
[7, 8, 9]])
345+
327346
"""
328347

329-
dst_desc = dpnp.get_dpnp_descriptor(
330-
dst, copy_when_strides=False, copy_when_nondefault_queue=False
331-
)
332-
src_desc = dpnp.get_dpnp_descriptor(src, copy_when_nondefault_queue=False)
333-
if dst_desc and src_desc:
334-
if casting != "same_kind":
335-
pass
336-
elif (
337-
dst_desc.dtype == dpnp.bool
338-
and src_desc.dtype # due to 'same_kind' casting
339-
in [
340-
dpnp.int32,
341-
dpnp.int64,
342-
dpnp.float32,
343-
dpnp.float64,
344-
dpnp.complex128,
345-
]
346-
):
347-
pass
348-
elif dst_desc.dtype in [
349-
dpnp.int32,
350-
dpnp.int64,
351-
] and src_desc.dtype in [ # due to 'same_kind' casting
352-
dpnp.float32,
353-
dpnp.float64,
354-
dpnp.complex128,
355-
]:
356-
pass
357-
elif (
358-
dst_desc.dtype in [dpnp.float32, dpnp.float64]
359-
and src_desc.dtype == dpnp.complex128
360-
): # due to 'same_kind' casting
361-
pass
362-
elif where is not True:
363-
pass
364-
elif dst_desc.shape != src_desc.shape:
365-
pass
366-
elif dst_desc.strides != src_desc.strides:
367-
pass
368-
else:
369-
return dpnp_copyto(dst_desc, src_desc, where=where)
348+
if not dpnp.is_supported_array_type(dst):
349+
raise TypeError(
350+
"Destination array must be any of supported type, "
351+
f"but got {type(dst)}"
352+
)
353+
elif not dpnp.is_supported_array_type(src):
354+
src = dpnp.array(src, sycl_queue=dst.sycl_queue)
370355

371-
return call_origin(
372-
numpy.copyto, dst, src, casting, where, dpnp_inplace=True
373-
)
356+
if not dpt.can_cast(src.dtype, dst.dtype, casting=casting):
357+
raise TypeError(
358+
f"Cannot cast from {src.dtype} to {dst.dtype} "
359+
f"according to the rule {casting}."
360+
)
361+
362+
if where is True:
363+
dst[...] = src
364+
elif where is False:
365+
# nothing to copy
366+
pass
367+
else:
368+
if dpnp.isscalar(where):
369+
where = dpnp.array(
370+
where, dtype=dpnp.bool, sycl_queue=dst.sycl_queue
371+
)
372+
elif not dpnp.is_supported_array_type(where):
373+
raise TypeError(
374+
"`where` array must be any of supported type, "
375+
f"but got {type(where)}"
376+
)
377+
elif where.dtype != dpnp.bool:
378+
raise TypeError(
379+
"`where` keyword argument must be of boolean type, "
380+
f"but got {where.dtype}"
381+
)
382+
383+
dst_usm, src_usm, mask_usm = dpt.broadcast_arrays(
384+
dpnp.get_usm_ndarray(dst),
385+
dpnp.get_usm_ndarray(src),
386+
dpnp.get_usm_ndarray(where),
387+
)
388+
dst_usm[mask_usm] = src_usm[mask_usm]
374389

375390

376391
def expand_dims(x1, axis):

tests/__init__.py

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,8 @@
11
import numpy
22

3-
import dpnp
43
from tests import testing
54
from tests.third_party.cupy import testing as cupy_testing
65

7-
from .helper import has_support_aspect64
8-
96
numpy.testing.assert_allclose = testing.assert_allclose
107
numpy.testing.assert_array_equal = testing.assert_array_equal
118
numpy.testing.assert_equal = testing.assert_equal
12-
13-
# patch for shaped_arange func to exclude calls of astype and reshape
14-
# necessary because new data container does not support these functions yet
15-
16-
orig_shaped_arange = cupy_testing.shaped_arange
17-
orig_shaped_reverse_arange = cupy_testing.shaped_reverse_arange
18-
19-
20-
def _shaped_arange(shape, xp=dpnp, dtype=dpnp.float64, order="C"):
21-
if dtype is dpnp.float64:
22-
dtype = dpnp.float32 if not has_support_aspect64() else dtype
23-
res = xp.array(
24-
orig_shaped_arange(shape, xp=numpy, dtype=dtype, order=order),
25-
dtype=dtype,
26-
)
27-
return res
28-
29-
30-
def _shaped_reverse_arange(shape, xp=dpnp, dtype=dpnp.float32):
31-
res = xp.array(
32-
orig_shaped_reverse_arange(shape, xp=numpy, dtype=dtype), dtype=dtype
33-
)
34-
return res
35-
36-
37-
cupy_testing.shaped_arange = _shaped_arange
38-
cupy_testing.shaped_reverse_arange = _shaped_reverse_arange

tests/test_manipulation.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,6 @@
2525

2626
@pytest.mark.parametrize("in_obj, out_dtype", testdata)
2727
def test_copyto_dtype(in_obj, out_dtype):
28-
if out_dtype == dpnp.complex64:
29-
pytest.skip("SAT-6016: dpnp.copyto() do not work with complex64 dtype")
3028
ndarr = numpy.array(in_obj)
3129
expected = numpy.empty(ndarr.size, dtype=out_dtype)
3230
numpy.copyto(expected, ndarr)

0 commit comments

Comments
 (0)