Skip to content

Commit a8d7135

Browse files
authored
Reuse dpctl.tensor implementation for dpnp.nonzero() (#1330)
1 parent bb01f05 commit a8d7135

File tree

9 files changed

+23
-111
lines changed

9 files changed

+23
-111
lines changed

dpnp/backend/include/dpnp_iface.hpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,6 @@ typedef ssize_t shape_elem_type;
5757

5858
#include <dpctl_sycl_interface.h>
5959

60-
#include "dpnp_iface_fptr.hpp"
6160
#include "dpnp_iface_fft.hpp"
6261
#include "dpnp_iface_random.hpp"
6362

dpnp/backend/include/dpnp_iface_fptr.hpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,6 @@ enum class DPNPFuncName : size_t
234234
DPNP_FN_NEGATIVE, /**< Used in numpy.negative() impl */
235235
DPNP_FN_NEGATIVE_EXT, /**< Used in numpy.negative() impl, requires extra parameters */
236236
DPNP_FN_NONZERO, /**< Used in numpy.nonzero() impl */
237-
DPNP_FN_NONZERO_EXT, /**< Used in numpy.nonzero() impl, requires extra parameters */
238237
DPNP_FN_NOT_EQUAL_EXT, /**< Used in numpy.not_equal() impl, requires extra parameters */
239238
DPNP_FN_ONES, /**< Used in numpy.ones() impl */
240239
DPNP_FN_ONES_LIKE, /**< Used in numpy.ones_like() impl */

dpnp/backend/kernels/dpnp_krnl_indexing.cpp

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -475,6 +475,7 @@ void dpnp_nonzero_c(const void* in_array1,
475475
j,
476476
dep_event_vec_ref);
477477
DPCTLEvent_WaitAndThrow(event_ref);
478+
DPCTLEvent_Delete(event_ref);
478479
}
479480

480481
template <typename _DataType>
@@ -485,16 +486,6 @@ void (*dpnp_nonzero_default_c)(const void*,
485486
const size_t,
486487
const size_t) = dpnp_nonzero_c<_DataType>;
487488

488-
template <typename _DataType>
489-
DPCTLSyclEventRef (*dpnp_nonzero_ext_c)(DPCTLSyclQueueRef,
490-
const void*,
491-
void*,
492-
const size_t,
493-
const shape_elem_type*,
494-
const size_t,
495-
const size_t,
496-
const DPCTLEventVectorRef) = dpnp_nonzero_c<_DataType>;
497-
498489
template <typename _DataType>
499490
DPCTLSyclEventRef dpnp_place_c(DPCTLSyclQueueRef q_ref,
500491
void* arr_in,
@@ -1021,12 +1012,6 @@ void func_map_init_indexing_func(func_map_t& fmap)
10211012
fmap[DPNPFuncName::DPNP_FN_NONZERO][eft_FLT][eft_FLT] = {eft_FLT, (void*)dpnp_nonzero_default_c<float>};
10221013
fmap[DPNPFuncName::DPNP_FN_NONZERO][eft_DBL][eft_DBL] = {eft_DBL, (void*)dpnp_nonzero_default_c<double>};
10231014

1024-
fmap[DPNPFuncName::DPNP_FN_NONZERO_EXT][eft_BLN][eft_BLN] = {eft_BLN, (void*)dpnp_nonzero_ext_c<bool>};
1025-
fmap[DPNPFuncName::DPNP_FN_NONZERO_EXT][eft_INT][eft_INT] = {eft_INT, (void*)dpnp_nonzero_ext_c<int32_t>};
1026-
fmap[DPNPFuncName::DPNP_FN_NONZERO_EXT][eft_LNG][eft_LNG] = {eft_LNG, (void*)dpnp_nonzero_ext_c<int64_t>};
1027-
fmap[DPNPFuncName::DPNP_FN_NONZERO_EXT][eft_FLT][eft_FLT] = {eft_FLT, (void*)dpnp_nonzero_ext_c<float>};
1028-
fmap[DPNPFuncName::DPNP_FN_NONZERO_EXT][eft_DBL][eft_DBL] = {eft_DBL, (void*)dpnp_nonzero_ext_c<double>};
1029-
10301015
fmap[DPNPFuncName::DPNP_FN_PLACE][eft_INT][eft_INT] = {eft_INT, (void*)dpnp_place_default_c<int32_t>};
10311016
fmap[DPNPFuncName::DPNP_FN_PLACE][eft_LNG][eft_LNG] = {eft_LNG, (void*)dpnp_place_default_c<int64_t>};
10321017
fmap[DPNPFuncName::DPNP_FN_PLACE][eft_FLT][eft_FLT] = {eft_FLT, (void*)dpnp_place_default_c<float>};

dpnp/dpnp_algo/dpnp_algo.pxd

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,6 @@ cdef extern from "dpnp_iface_fptr.hpp" namespace "DPNPFuncName": # need this na
211211
DPNP_FN_NEGATIVE
212212
DPNP_FN_NEGATIVE_EXT
213213
DPNP_FN_NONZERO
214-
DPNP_FN_NONZERO_EXT
215214
DPNP_FN_NOT_EQUAL_EXT
216215
DPNP_FN_ONES
217216
DPNP_FN_ONES_LIKE

dpnp/dpnp_algo/dpnp_algo_indexing.pyx

Lines changed: 1 addition & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# cython: language_level=3
22
# -*- coding: utf-8 -*-
33
# *****************************************************************************
4-
# Copyright (c) 2016-2020, Intel Corporation
4+
# Copyright (c) 2016-2023, Intel Corporation
55
# All rights reserved.
66
#
77
# Redistribution and use in source and binary forms, with or without
@@ -40,7 +40,6 @@ __all__ += [
4040
"dpnp_diagonal",
4141
"dpnp_fill_diagonal",
4242
"dpnp_indices",
43-
"dpnp_nonzero",
4443
"dpnp_place",
4544
"dpnp_put",
4645
"dpnp_put_along_axis",
@@ -104,14 +103,6 @@ ctypedef c_dpctl.DPCTLSyclEventRef(*custom_indexing_6in_func_ptr_t)(c_dpctl.DPCT
104103
const size_t,
105104
const size_t,
106105
const c_dpctl.DPCTLEventVectorRef)
107-
ctypedef c_dpctl.DPCTLSyclEventRef(*fptr_dpnp_nonzero_t)(c_dpctl.DPCTLSyclQueueRef,
108-
const void * ,
109-
void * ,
110-
const size_t,
111-
const shape_elem_type * ,
112-
const size_t ,
113-
const size_t,
114-
const c_dpctl.DPCTLEventVectorRef)
115106

116107

117108
cpdef utils.dpnp_descriptor dpnp_choose(utils.dpnp_descriptor x1, list choices1):
@@ -316,60 +307,6 @@ cpdef object dpnp_indices(dimensions):
316307
return dpnp_result
317308

318309

319-
cpdef tuple dpnp_nonzero(utils.dpnp_descriptor in_array1):
320-
cdef shape_type_c shape_arr = in_array1.shape
321-
res_count = in_array1.ndim
322-
323-
# have to go through array one extra time to count size of result arrays
324-
res_size_obj = dpnp_count_nonzero(in_array1)
325-
cdef size_t res_size = dpnp.convert_single_elem_array_to_scalar(res_size_obj.get_pyobj())
326-
327-
cdef DPNPFuncType param1_type = dpnp_dtype_to_DPNPFuncType(in_array1.dtype)
328-
329-
cdef DPNPFuncData kernel_data = get_dpnp_function_ptr(DPNP_FN_NONZERO_EXT, param1_type, param1_type)
330-
331-
cdef fptr_dpnp_nonzero_t func = <fptr_dpnp_nonzero_t > kernel_data.ptr
332-
333-
cdef c_dpctl.SyclQueue q
334-
cdef c_dpctl.DPCTLSyclQueueRef q_ref
335-
cdef c_dpctl.DPCTLSyclEventRef event_ref
336-
337-
array1_obj = in_array1.get_array()
338-
339-
res_list = []
340-
cdef utils.dpnp_descriptor res_arr
341-
cdef shape_type_c result_shape
342-
for j in range(res_count):
343-
result_shape = utils._object_to_tuple(res_size)
344-
res_arr = utils_py.create_output_descriptor_py(result_shape,
345-
dpnp.int64,
346-
None,
347-
device=array1_obj.sycl_device,
348-
usm_type=array1_obj.usm_type,
349-
sycl_queue=array1_obj.sycl_queue)
350-
351-
q = <c_dpctl.SyclQueue> res_arr.get_array().sycl_queue
352-
q_ref = q.get_queue_ref()
353-
354-
event_ref = func(q_ref,
355-
in_array1.get_data(),
356-
res_arr.get_data(),
357-
res_arr.size,
358-
shape_arr.data(),
359-
in_array1.ndim,
360-
j,
361-
NULL) # dep_events_ref
362-
363-
with nogil: c_dpctl.DPCTLEvent_WaitAndThrow(event_ref)
364-
c_dpctl.DPCTLEvent_Delete(event_ref)
365-
366-
res_list.append(res_arr.get_pyobj())
367-
368-
result = utils._object_to_tuple(res_list)
369-
370-
return result
371-
372-
373310
cpdef dpnp_place(dpnp_descriptor arr, object mask, dpnp_descriptor vals):
374311
result_sycl_device, result_usm_type, result_sycl_queue = utils.get_common_usm_allocation(arr, vals)
375312

dpnp/dpnp_array.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -760,7 +760,10 @@ def ndim(self):
760760
return self._array_obj.ndim
761761

762762
# 'newbyteorder',
763-
# 'nonzero',
763+
764+
def nonzero(self):
765+
return dpnp.nonzero(self)
766+
764767
# 'partition',
765768

766769
def prod(self, axis=None, dtype=None, out=None, keepdims=False, initial=None, where=True):

dpnp/dpnp_iface_indexing.py

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# distutils: language = c++
33
# -*- coding: utf-8 -*-
44
# *****************************************************************************
5-
# Copyright (c) 2016-2020, Intel Corporation
5+
# Copyright (c) 2016-2023, Intel Corporation
66
# All rights reserved.
77
#
88
# Redistribution and use in source and binary forms, with or without
@@ -39,14 +39,14 @@
3939
4040
"""
4141

42-
43-
import collections
44-
4542
from dpnp.dpnp_algo import *
4643
from dpnp.dpnp_utils import *
4744

4845
import dpnp
46+
from dpnp.dpnp_array import dpnp_array
47+
4948
import numpy
49+
import dpctl.tensor as dpt
5050

5151

5252
__all__ = [
@@ -286,15 +286,21 @@ def indices(dimensions, dtype=int, sparse=False):
286286
return call_origin(numpy.indices, dimensions, dtype, sparse)
287287

288288

289-
def nonzero(x1):
289+
def nonzero(x, /):
290290
"""
291291
Return the indices of the elements that are non-zero.
292292
293293
For full documentation refer to :obj:`numpy.nonzero`.
294294
295+
Returns
296+
-------
297+
y : tuple[dpnp.ndarray]
298+
Indices of elements that are non-zero.
299+
295300
Limitations
296301
-----------
297-
Input array is supported as :obj:`dpnp.ndarray`.
302+
Parameters `x` is supported as either :class:`dpnp.ndarray`
303+
or :class:`dpctl.tensor.usm_ndarray`.
298304
Otherwise the function will be executed sequentially on CPU.
299305
Input array data types are limited by supported DPNP :ref:`Data types`.
300306
@@ -329,11 +335,11 @@ def nonzero(x1):
329335
330336
"""
331337

332-
x1_desc = dpnp.get_dpnp_descriptor(x1, copy_when_nondefault_queue=False)
333-
if x1_desc:
334-
return dpnp_nonzero(x1_desc)
338+
if isinstance(x, dpnp_array) or isinstance(x, dpt.usm_ndarray):
339+
dpt_array = x.get_array() if isinstance(x, dpnp_array) else x
340+
return tuple(dpnp_array._create_from_usm_ndarray(y) for y in dpt.nonzero(dpt_array))
335341

336-
return call_origin(numpy.nonzero, x1)
342+
return call_origin(numpy.nonzero, x)
337343

338344

339345
def place(x1, mask, vals):

dpnp/dpnp_iface_searching.py

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,7 @@
4444
from dpnp.dpnp_utils import *
4545

4646
import dpnp
47-
from dpnp.dpnp_array import dpnp_array
48-
4947
import numpy
50-
import dpctl.tensor as dpt
5148

5249

5350
__all__ = [
@@ -221,13 +218,7 @@ def where(condition, x=None, y=None, /):
221218
if missing == 1:
222219
raise ValueError("Must provide both 'x' and 'y' or neither.")
223220
elif missing == 2:
224-
# TODO: rework through dpnp.nonzero() once ready
225-
# return dpnp.nonzero(condition)
226-
if isinstance(condition, dpnp_array):
227-
return dpt.nonzero(condition.get_array())
228-
229-
if isinstance(condition, dpt.usm_ndarray):
230-
return dpt.nonzero(condition)
221+
return dpnp.nonzero(condition)
231222
elif missing == 0:
232223
# get USM type and queue to copy scalar from the host memory into a USM allocation
233224
usm_type, queue = get_usm_allocations([condition, x, y])

tests/skipped_tests_gpu.tbl

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -52,13 +52,6 @@ tests/test_sycl_queue.py::test_modf[level_zero:gpu:0]
5252
tests/test_sycl_queue.py::test_1in_1out[opencl:gpu:0-trapz-data19]
5353
tests/test_sycl_queue.py::test_1in_1out[opencl:cpu:0-trapz-data19]
5454

55-
tests/test_indexing.py::test_nonzero[[[1, 0], [1, 0]]]
56-
tests/test_indexing.py::test_nonzero[[[1, 2], [3, 4]]]
57-
tests/test_indexing.py::test_nonzero[[[0, 1, 2], [3, 0, 5], [6, 7, 0]]]
58-
tests/test_indexing.py::test_nonzero[[[0, 1, 0, 3, 0], [5, 0, 7, 0, 9]]]
59-
tests/test_indexing.py::test_nonzero[[[[1, 2], [0, 4]], [[0, 2], [0, 1]], [[0, 0], [3, 1]]]]
60-
tests/test_indexing.py::test_nonzero[[[[[1, 2, 3], [3, 4, 5]], [[1, 2, 3], [2, 1, 0]]], [[[1, 3, 5], [3, 1, 0]], [[0, 1, 2], [1, 3, 4]]]]]
61-
6255
tests/third_party/cupy/indexing_tests/test_indexing.py::TestIndexing::test_take_no_axis
6356
tests/third_party/cupy/indexing_tests/test_insert.py::TestPlace_param_3_{n_vals=1, shape=(7,)}::test_place
6457
tests/third_party/cupy/indexing_tests/test_insert.py::TestPlace_param_4_{n_vals=1, shape=(2, 3)}::test_place

0 commit comments

Comments
 (0)