Skip to content

Commit 45940b8

Browse files
Merge pull request #867 from IntelPython/master
Merge master to gold
2 parents b73fa9e + ae54d5c commit 45940b8

32 files changed

+715
-491
lines changed

dpnp/backend/include/dpnp_iface.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -622,7 +622,7 @@ INP_DLLEXPORT void dpnp_initval_c(void* result1, void* value, size_t size);
622622
* @param [in] shape Shape of input array.
623623
* @param [in] ndim Number of elements in shape.
624624
*/
625-
template <typename _DataType>
625+
template <typename _DataType, typename _ResultType>
626626
INP_DLLEXPORT void dpnp_inv_c(void* array1_in, void* result1, size_t* shape, size_t ndim);
627627

628628
/**

dpnp/backend/kernels/dpnp_krnl_linalg.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -190,17 +190,17 @@ void dpnp_det_c(void* array1_in, void* result1, size_t* shape, size_t ndim)
190190
return;
191191
}
192192

193-
template <typename _DataType>
193+
template <typename _DataType, typename _ResultType>
194194
void dpnp_inv_c(void* array1_in, void* result1, size_t* shape, size_t ndim)
195195
{
196196
(void)ndim; // avoid warning unused variable
197197
_DataType* array_1 = reinterpret_cast<_DataType*>(array1_in);
198-
_DataType* result = reinterpret_cast<_DataType*>(result1);
198+
_ResultType* result = reinterpret_cast<_ResultType*>(result1);
199199

200200
size_t n = shape[0];
201201

202-
_DataType a_arr[n][n];
203-
_DataType e_arr[n][n];
202+
_ResultType a_arr[n][n];
203+
_ResultType e_arr[n][n];
204204

205205
for (size_t i = 0; i < n; ++i)
206206
{
@@ -541,10 +541,10 @@ void func_map_init_linalg_func(func_map_t& fmap)
541541
fmap[DPNPFuncName::DPNP_FN_DET][eft_FLT][eft_FLT] = {eft_FLT, (void*)dpnp_det_c<float>};
542542
fmap[DPNPFuncName::DPNP_FN_DET][eft_DBL][eft_DBL] = {eft_DBL, (void*)dpnp_det_c<double>};
543543

544-
fmap[DPNPFuncName::DPNP_FN_INV][eft_INT][eft_INT] = {eft_INT, (void*)dpnp_inv_c<int>};
545-
fmap[DPNPFuncName::DPNP_FN_INV][eft_LNG][eft_LNG] = {eft_LNG, (void*)dpnp_inv_c<long>};
546-
fmap[DPNPFuncName::DPNP_FN_INV][eft_FLT][eft_FLT] = {eft_FLT, (void*)dpnp_inv_c<float>};
547-
fmap[DPNPFuncName::DPNP_FN_INV][eft_DBL][eft_DBL] = {eft_DBL, (void*)dpnp_inv_c<double>};
544+
fmap[DPNPFuncName::DPNP_FN_INV][eft_INT][eft_INT] = {eft_DBL, (void*)dpnp_inv_c<int, double>};
545+
fmap[DPNPFuncName::DPNP_FN_INV][eft_LNG][eft_LNG] = {eft_DBL, (void*)dpnp_inv_c<long, double>};
546+
fmap[DPNPFuncName::DPNP_FN_INV][eft_FLT][eft_FLT] = {eft_DBL, (void*)dpnp_inv_c<float, double>};
547+
fmap[DPNPFuncName::DPNP_FN_INV][eft_DBL][eft_DBL] = {eft_DBL, (void*)dpnp_inv_c<double, double>};
548548

549549
fmap[DPNPFuncName::DPNP_FN_KRON][eft_INT][eft_INT] = {eft_INT, (void*)dpnp_kron_c<int, int, int>};
550550
fmap[DPNPFuncName::DPNP_FN_KRON][eft_INT][eft_LNG] = {eft_LNG, (void*)dpnp_kron_c<int, long, long>};

dpnp/backend/kernels/dpnp_krnl_mathematical.cpp

Lines changed: 62 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -346,50 +346,80 @@ void dpnp_remainder_c(void* result_out,
346346
const size_t input2_shape_ndim,
347347
const size_t* where)
348348
{
349-
(void)input1_shape;
350-
(void)input1_shape_ndim;
351-
(void)input2_size;
352-
(void)input2_shape;
353-
(void)input2_shape_ndim;
354349
(void)where;
355350

356-
cl::sycl::event event;
357-
_DataType_input1* input1 = reinterpret_cast<_DataType_input1*>(const_cast<void*>(input1_in));
358-
_DataType_input2* input2 = reinterpret_cast<_DataType_input2*>(const_cast<void*>(input2_in));
351+
if (!input1_size || !input2_size)
352+
{
353+
return;
354+
}
355+
356+
_DataType_input1* input1_data = reinterpret_cast<_DataType_input1*>(const_cast<void*>(input1_in));
357+
_DataType_input2* input2_data = reinterpret_cast<_DataType_input2*>(const_cast<void*>(input2_in));
359358
_DataType_output* result = reinterpret_cast<_DataType_output*>(result_out);
360359

361-
if constexpr ((std::is_same<_DataType_input1, double>::value || std::is_same<_DataType_input1, float>::value) &&
362-
std::is_same<_DataType_input2, _DataType_input1>::value)
360+
std::vector<size_t> result_shape = get_result_shape(input1_shape, input1_shape_ndim,
361+
input2_shape, input2_shape_ndim);
362+
363+
DPNPC_id<_DataType_input1>* input1_it;
364+
const size_t input1_it_size_in_bytes = sizeof(DPNPC_id<_DataType_input1>);
365+
input1_it = reinterpret_cast<DPNPC_id<_DataType_input1>*>(dpnp_memory_alloc_c(input1_it_size_in_bytes));
366+
new (input1_it) DPNPC_id<_DataType_input1>(input1_data, input1_shape, input1_shape_ndim);
367+
368+
input1_it->broadcast_to_shape(result_shape);
369+
370+
DPNPC_id<_DataType_input2>* input2_it;
371+
const size_t input2_it_size_in_bytes = sizeof(DPNPC_id<_DataType_input2>);
372+
input2_it = reinterpret_cast<DPNPC_id<_DataType_input2>*>(dpnp_memory_alloc_c(input2_it_size_in_bytes));
373+
new (input2_it) DPNPC_id<_DataType_input2>(input2_data, input2_shape, input2_shape_ndim);
374+
375+
input2_it->broadcast_to_shape(result_shape);
376+
377+
const size_t result_size = input1_it->get_output_size();
378+
379+
cl::sycl::range<1> gws(result_size);
380+
auto kernel_parallel_for_func = [=](cl::sycl::id<1> global_id) {
381+
const size_t i = global_id[0];
382+
const _DataType_output input1_elem = (*input1_it)[i];
383+
const _DataType_output input2_elem = (*input2_it)[i];
384+
double fmod_res = cl::sycl::fmod((double)input1_elem, (double)input2_elem);
385+
double add = fmod_res + input2_elem;
386+
result[i] = cl::sycl::fmod(add, (double)input2_elem);
387+
388+
};
389+
auto kernel_func = [&](cl::sycl::handler& cgh) {
390+
cgh.parallel_for<class dpnp_remainder_c_kernel<_DataType_output, _DataType_input1, _DataType_input2>>(
391+
gws, kernel_parallel_for_func);
392+
};
393+
394+
cl::sycl::event event;
395+
396+
if (input1_size == input2_size)
363397
{
364-
event = oneapi::mkl::vm::fmod(DPNP_QUEUE, input1_size, input1, input2, result);
365-
event.wait();
366-
event = oneapi::mkl::vm::add(DPNP_QUEUE, input1_size, result, input2, result);
367-
event.wait();
368-
event = oneapi::mkl::vm::fmod(DPNP_QUEUE, input1_size, result, input2, result);
398+
if constexpr ((std::is_same<_DataType_input1, double>::value ||
399+
std::is_same<_DataType_input1, float>::value) &&
400+
std::is_same<_DataType_input2, _DataType_input1>::value)
401+
{
402+
event = oneapi::mkl::vm::fmod(DPNP_QUEUE, input1_size, input1_data, input2_data, result);
403+
event.wait();
404+
event = oneapi::mkl::vm::add(DPNP_QUEUE, input1_size, result, input2_data, result);
405+
event.wait();
406+
event = oneapi::mkl::vm::fmod(DPNP_QUEUE, input1_size, result, input2_data, result);
407+
}
408+
else
409+
{
410+
event = DPNP_QUEUE.submit(kernel_func);
411+
}
369412
}
370413
else
371414
{
372-
cl::sycl::range<1> gws(input1_size);
373-
auto kernel_parallel_for_func = [=](cl::sycl::id<1> global_id) {
374-
size_t i = global_id[0]; /*for (size_t i = 0; i < size; ++i)*/
375-
{
376-
_DataType_input1 input_elem1 = input1[i];
377-
_DataType_input2 input_elem2 = input2[i];
378-
double fmod = cl::sycl::fmod((double)input_elem1, (double)input_elem2);
379-
double add = fmod + input_elem2;
380-
result[i] = cl::sycl::fmod(add, (double)input_elem2);
381-
}
382-
};
383-
384-
auto kernel_func = [&](cl::sycl::handler& cgh) {
385-
cgh.parallel_for<class dpnp_remainder_c_kernel<_DataType_input1, _DataType_input2, _DataType_output>>(
386-
gws, kernel_parallel_for_func);
387-
};
388-
389415
event = DPNP_QUEUE.submit(kernel_func);
390416
}
391417

392418
event.wait();
419+
420+
input1_it->~DPNPC_id();
421+
input2_it->~DPNPC_id();
422+
393423
}
394424

395425
template <typename _KernelNameSpecialization1, typename _KernelNameSpecialization2, typename _KernelNameSpecialization3>

dpnp/dparray.pyx

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ from dpnp.dpnp_iface import *
4242
# to avoid interference with Python internal functions
4343
from dpnp.dpnp_iface import sum as iface_sum
4444
from dpnp.dpnp_iface import prod as iface_prod
45+
from dpnp.dpnp_iface import get_dpnp_descriptor as iface_get_dpnp_descriptor
4546

4647
from dpnp.dpnp_algo cimport *
4748
from dpnp.dpnp_iface_statistics import min, max # TODO do the same as for iface_sum
@@ -386,7 +387,7 @@ cdef class dparray:
386387
387388
if key_is_slice or key_has_slice:
388389
# fallback to numpy in case of slicing
389-
return utils.nd2dp_array(utils.dp2nd_array(self)[key])
390+
return nd2dp_array(dp2nd_array(self)[key])
390391
391392
lin_idx = utils._get_linear_index(key, self.shape, self.ndim)
392393
@@ -514,11 +515,12 @@ cdef class dparray:
514515
if order == 'F':
515516
return self.transpose().reshape(self.size)
516517
517-
return dpnp_flatten(self)
518+
self_desc = iface_get_dpnp_descriptor(self)
519+
return dpnp_flatten(self_desc).get_pyobj()
518520
519-
result = utils.dp2nd_array(self).flatten(order=order)
521+
result = dp2nd_array(self).flatten(order=order)
520522
521-
return utils.nd2dp_array(result)
523+
return nd2dp_array(result)
522524
523525
def ravel(self, order='C'):
524526
"""
@@ -799,11 +801,12 @@ cdef class dparray:
799801
elif self.dtype == numpy.complex64 or dtype == numpy.complex64:
800802
pass
801803
else:
802-
return dpnp_astype(self, dtype)
804+
self_desc = iface_get_dpnp_descriptor(self)
805+
return dpnp_astype(self_desc, dtype).get_pyobj()
803806
804-
result = utils.dp2nd_array(self).astype(dtype=dtype, order=order, casting=casting, subok=subok, copy=copy)
807+
result = dp2nd_array(self).astype(dtype=dtype, order=order, casting=casting, subok=subok, copy=copy)
805808
806-
return utils.nd2dp_array(result)
809+
return nd2dp_array(result)
807810
808811
def conj(self):
809812
"""
@@ -1270,3 +1273,20 @@ cdef class dparray:
12701273
"""
12711274
12721275
return asnumpy(self).tostring(order)
1276+
1277+
1278+
def dp2nd_array(arr):
1279+
"""Convert dparray to ndarray"""
1280+
return asnumpy(arr) if isinstance(arr, dparray) else arr
1281+
1282+
1283+
def nd2dp_array(arr):
1284+
"""Convert ndarray to dparray"""
1285+
if not isinstance(arr, numpy.ndarray):
1286+
return arr
1287+
1288+
result = dparray(arr.shape, dtype=arr.dtype)
1289+
for i in range(result.size):
1290+
result._setitem_scalar(i, arr.item(i))
1291+
1292+
return result

dpnp/dpnp_algo/dpnp_algo.pxd

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727

2828
from libcpp.vector cimport vector
2929
from libcpp cimport bool as cpp_bool
30-
from dpnp.dparray cimport dparray
30+
3131
from dpnp.dpnp_utils.dpnp_algo_utils cimport dpnp_descriptor
3232

3333

@@ -235,8 +235,8 @@ ctypedef void(*fptr_2in_1out_t)(void * , const void * , const size_t, const long
235235
ctypedef void(*fptr_blas_gemm_2in_1out_t)(void *, void * , void * , size_t, size_t, size_t)
236236
ctypedef void(*dpnp_reduction_c_t)(void *, const void * , const size_t*, const size_t, const long*, const size_t, const void * , const long*)
237237

238-
cpdef dparray dpnp_astype(dparray array1, dtype_target)
239-
cpdef dparray dpnp_flatten(dparray array1)
238+
cpdef dpnp_descriptor dpnp_astype(dpnp_descriptor array1, dtype)
239+
cpdef dpnp_descriptor dpnp_flatten(dpnp_descriptor array1)
240240

241241

242242
"""

dpnp/dpnp_algo/dpnp_algo.pyx

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ cpdef utils.dpnp_descriptor dpnp_array(object obj, object dtype=None):
107107
if not cpython.PySequence_Check(obj):
108108
raise TypeError(f"DPNP dpnp_array(): Unsupported non-sequence obj={type(obj)}")
109109

110-
obj_shape, elem_dtype = utils.get_shape_dtype(obj)
110+
obj_shape, obj_dtype = utils.get_shape_dtype(obj)
111111
if dtype is not None:
112112
""" Set type from parameter. result might be empty array """
113113
result = utils_py.create_output_descriptor_py(obj_shape, dtype, None)
@@ -116,35 +116,37 @@ cpdef utils.dpnp_descriptor dpnp_array(object obj, object dtype=None):
116116
""" Empty object (ex. empty list) and no type provided """
117117
result = utils_py.create_output_descriptor_py(obj_shape, None, None)
118118
else:
119-
result = utils_py.create_output_descriptor_py(obj_shape, elem_dtype, None)
119+
result = utils_py.create_output_descriptor_py(obj_shape, obj_dtype, None)
120120

121-
utils.copy_values_to_dparray(result.get_pyobj(), obj)
121+
utils.container_copy(result.get_pyobj(), obj)
122122

123123
return result
124124

125125

126-
cpdef dparray dpnp_astype(dparray array1, dtype_target):
126+
cpdef utils.dpnp_descriptor dpnp_astype(utils.dpnp_descriptor array1, dtype):
127127
cdef DPNPFuncType param1_type = dpnp_dtype_to_DPNPFuncType(array1.dtype)
128-
cdef DPNPFuncType param2_type = dpnp_dtype_to_DPNPFuncType(dtype_target)
128+
cdef DPNPFuncType param2_type = dpnp_dtype_to_DPNPFuncType(dtype)
129129

130130
cdef DPNPFuncData kernel_data = get_dpnp_function_ptr(DPNP_FN_ASTYPE, param1_type, param2_type)
131131

132-
result_type = dpnp_DPNPFuncType_to_dtype( < size_t > kernel_data.return_type)
133-
cdef dparray result = dparray(array1.shape, dtype=result_type)
132+
# ceate result array with type given by FPTR data
133+
cdef shape_type_c result_shape = array1.shape
134+
cdef utils.dpnp_descriptor result = utils.create_output_descriptor(result_shape, kernel_data.return_type, None)
134135

135136
cdef fptr_dpnp_astype_t func = <fptr_dpnp_astype_t > kernel_data.ptr
136137
func(array1.get_data(), result.get_data(), array1.size)
137138

138139
return result
139140

140141

141-
cpdef dparray dpnp_flatten(dparray array_):
142+
cpdef utils.dpnp_descriptor dpnp_flatten(utils.dpnp_descriptor array_):
142143
cdef DPNPFuncType param1_type = dpnp_dtype_to_DPNPFuncType(array_.dtype)
143144

144145
cdef DPNPFuncData kernel_data = get_dpnp_function_ptr(DPNP_FN_FLATTEN, param1_type, param1_type)
145146

146-
result_type = dpnp_DPNPFuncType_to_dtype( < size_t > kernel_data.return_type)
147-
cdef dparray result = dparray(array_.size, dtype=result_type)
147+
# ceate result array with type given by FPTR data
148+
cdef shape_type_c result_shape = (array_.size,)
149+
cdef utils.dpnp_descriptor result = utils.create_output_descriptor(result_shape, kernel_data.return_type, None)
148150

149151
cdef fptr_dpnp_flatten_t func = <fptr_dpnp_flatten_t > kernel_data.ptr
150152
func(array_.get_data(), result.get_data(), array_.size)

dpnp/dpnp_algo/dpnp_algo_indexing.pyx

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,12 @@ ctypedef void(*custom_indexing_6in_func_ptr_t)(void *, void * , void * , const s
6565
ctypedef void(*fptr_dpnp_nonzero_t)(const void * , void * , const size_t * , const size_t , const size_t)
6666

6767

68-
cpdef dparray dpnp_choose(input, choices):
69-
res_array = dparray(len(input), dtype=choices[0].dtype)
68+
cpdef utils.dpnp_descriptor dpnp_choose(object input, list choices):
69+
cdef shape_type_c obj_shape = utils._object_to_tuple(len(input))
70+
cdef utils.dpnp_descriptor res_array = utils_py.create_output_descriptor_py(obj_shape, choices[0].dtype, None)
71+
7072
for i in range(len(input)):
71-
res_array[i] = (choices[input[i]])[i]
73+
res_array.get_pyobj()[i] = (choices[input[i]])[i]
7274
return res_array
7375

7476

@@ -169,12 +171,13 @@ cpdef object dpnp_indices(dimensions):
169171
return dpnp_result
170172

171173

172-
cpdef tuple dpnp_nonzero(dparray in_array1):
174+
cpdef tuple dpnp_nonzero(utils.dpnp_descriptor in_array1):
173175
cdef shape_type_c shape_arr = in_array1.shape
174176
res_count = in_array1.ndim
175177

176178
# have to go through array one extra time to count size of result arrays
177-
res_size = dpnp.count_nonzero(in_array1)
179+
res_size_obj = dpnp_count_nonzero(in_array1)
180+
cdef size_t res_size = dpnp.convert_single_elem_array_to_scalar(res_size_obj.get_pyobj())
178181

179182
cdef DPNPFuncType param1_type = dpnp_dtype_to_DPNPFuncType(in_array1.dtype)
180183

@@ -183,12 +186,15 @@ cpdef tuple dpnp_nonzero(dparray in_array1):
183186
cdef fptr_dpnp_nonzero_t func = <fptr_dpnp_nonzero_t > kernel_data.ptr
184187

185188
res_list = []
189+
cdef utils.dpnp_descriptor res_arr
190+
cdef shape_type_c result_shape
186191
for j in range(res_count):
187-
res_arr = dparray((res_size, ), dtype=dpnp.int64)
192+
result_shape = utils._object_to_tuple(res_size)
193+
res_arr = utils_py.create_output_descriptor_py(result_shape, dpnp.int64, None)
188194

189195
func(in_array1.get_data(), res_arr.get_data(), < size_t * > shape_arr.data(), in_array1.ndim, j)
190196

191-
res_list.append(res_arr)
197+
res_list.append(res_arr.get_pyobj())
192198

193199
result = utils._object_to_tuple(res_list)
194200

@@ -263,20 +269,21 @@ cpdef dpnp_putmask(object arr, object mask, object values):
263269
arr[i] = values[i % values_size]
264270

265271

266-
cpdef object dpnp_select(condlist, choicelist, default):
267-
size_ = condlist[0].size
268-
res_array = dparray(size_, dtype=choicelist[0].dtype)
272+
cpdef utils.dpnp_descriptor dpnp_select(list condlist, list choicelist, default):
273+
cdef size_t size_ = condlist[0].size
274+
cdef utils.dpnp_descriptor res_array = utils_py.create_output_descriptor_py(condlist[0].shape, choicelist[0].dtype, None)
275+
269276
pass_val = {a: default for a in range(size_)}
270277
for i in range(len(condlist)):
271278
for j in range(size_):
272279
if (condlist[i])[j]:
273-
res_array[j] = (choicelist[i])[j]
280+
res_array.get_pyobj()[j] = (choicelist[i])[j]
274281
pass_val.pop(j)
275282

276283
for ind, val in pass_val.items():
277-
res_array[ind] = val
284+
res_array.get_pyobj()[ind] = val
278285

279-
return res_array.reshape(condlist[0].shape)
286+
return res_array
280287

281288

282289
cpdef utils.dpnp_descriptor dpnp_take(utils.dpnp_descriptor input, utils.dpnp_descriptor indices):
@@ -371,7 +378,7 @@ cpdef object dpnp_take_along_axis(object arr, object indices, int axis):
371378
return dpnp_result_array
372379

373380
else:
374-
result_array = dparray(shape_arr, dtype=res_type)
381+
result_array = utils_py.create_output_descriptor_py(shape_arr, res_type, None).get_pyobj()
375382
for i in range(size_arr):
376383
ind = size_indices * (i // size_indices) + indices[i % size_indices]
377384
result_array[i] = arr[ind]

0 commit comments

Comments
 (0)