Skip to content

Commit 1b4ab46

Browse files
authored
add identity function (#652)
* add identity function
1 parent f5a401e commit 1b4ab46

File tree

9 files changed

+114
-2
lines changed

9 files changed

+114
-2
lines changed

dpnp/backend/include/dpnp_iface.hpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,16 @@ template <typename _DataType>
485485
INP_DLLEXPORT void dpnp_diagonal_c(
486486
void* array1_in, void* result1, const size_t offset, size_t* shape, size_t* res_shape, const size_t res_ndim);
487487

488+
/**
489+
* @ingroup BACKEND_API
490+
* @brief Implementation of identity function
491+
*
492+
* @param [out] result1 Output array.
493+
* @param [in] n Number of rows (and columns) in n x n output.
494+
*/
495+
template <typename _DataType>
496+
INP_DLLEXPORT void dpnp_identity_c(void* result1, const size_t n);
497+
488498
/**
489499
* @ingroup BACKEND_API
490500
* @brief implementation of creating filled with value array function

dpnp/backend/include/dpnp_iface_fptr.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ enum class DPNPFuncName : size_t
114114
DPNP_FN_FULL, /**< Used in numpy.full() implementation */
115115
DPNP_FN_FULL_LIKE, /**< Used in numpy.full_like() implementation */
116116
DPNP_FN_HYPOT, /**< Used in numpy.hypot() implementation */
117+
DPNP_FN_IDENTITY, /**< Used in numpy.identity() implementation */
117118
DPNP_FN_INITVAL, /**< Used in numpy ones, ones_like, zeros, zeros_like, full, full_like impl */
118119
DPNP_FN_INV, /**< Used in numpy.linalg.inv() implementation */
119120
DPNP_FN_INVERT, /**< Used in numpy.invert() implementation */

dpnp/backend/kernels/dpnp_krnl_arraycreation.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,37 @@ void dpnp_full_like_c(void* array_in, void* result, const size_t size)
110110
dpnp_full_c<_DataType>(array_in, result, size);
111111
}
112112

113+
template <typename _KernelNameSpecialization>
114+
class dpnp_identity_c_kernel;
115+
116+
template <typename _DataType>
117+
void dpnp_identity_c(void* result1, const size_t n)
118+
{
119+
if (n == 0)
120+
{
121+
return;
122+
}
123+
124+
cl::sycl::event event;
125+
126+
_DataType* result = reinterpret_cast<_DataType*>(result1);
127+
128+
cl::sycl::range<2> gws(n, n);
129+
auto kernel_parallel_for_func = [=](cl::sycl::id<2> global_id) {
130+
size_t i = global_id[0];
131+
size_t j = global_id[1];
132+
result[i * n + j] = i == j;
133+
};
134+
135+
auto kernel_func = [&](cl::sycl::handler& cgh) {
136+
cgh.parallel_for<class dpnp_identity_c_kernel<_DataType>>(gws, kernel_parallel_for_func);
137+
};
138+
139+
event = DPNP_QUEUE.submit(kernel_func);
140+
141+
event.wait();
142+
}
143+
113144
template <typename _DataType>
114145
void dpnp_ones_c(void* result, size_t size)
115146
{
@@ -478,6 +509,13 @@ void func_map_init_arraycreation(func_map_t& fmap)
478509
fmap[DPNPFuncName::DPNP_FN_FULL_LIKE][eft_C128][eft_C128] = {eft_C128,
479510
(void*)dpnp_full_like_c<std::complex<double>>};
480511

512+
fmap[DPNPFuncName::DPNP_FN_IDENTITY][eft_INT][eft_INT] = {eft_INT, (void*)dpnp_identity_c<int>};
513+
fmap[DPNPFuncName::DPNP_FN_IDENTITY][eft_LNG][eft_LNG] = {eft_LNG, (void*)dpnp_identity_c<long>};
514+
fmap[DPNPFuncName::DPNP_FN_IDENTITY][eft_FLT][eft_FLT] = {eft_FLT, (void*)dpnp_identity_c<float>};
515+
fmap[DPNPFuncName::DPNP_FN_IDENTITY][eft_DBL][eft_DBL] = {eft_DBL, (void*)dpnp_identity_c<double>};
516+
fmap[DPNPFuncName::DPNP_FN_IDENTITY][eft_BLN][eft_BLN] = {eft_BLN, (void*)dpnp_identity_c<bool>};
517+
fmap[DPNPFuncName::DPNP_FN_IDENTITY][eft_C128][eft_C128] = {eft_C128, (void*)dpnp_identity_c<std::complex<double>>};
518+
481519
fmap[DPNPFuncName::DPNP_FN_ONES][eft_INT][eft_INT] = {eft_INT, (void*)dpnp_ones_c<int>};
482520
fmap[DPNPFuncName::DPNP_FN_ONES][eft_LNG][eft_LNG] = {eft_LNG, (void*)dpnp_ones_c<long>};
483521
fmap[DPNPFuncName::DPNP_FN_ONES][eft_FLT][eft_FLT] = {eft_FLT, (void*)dpnp_ones_c<float>};

dpnp/dpnp_algo/dpnp_algo.pxd

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ cdef extern from "dpnp_iface_fptr.hpp" namespace "DPNPFuncName": # need this na
8787
DPNP_FN_FULL
8888
DPNP_FN_FULL_LIKE
8989
DPNP_FN_HYPOT
90+
DPNP_FN_IDENTITY
9091
DPNP_FN_INITVAL
9192
DPNP_FN_INV
9293
DPNP_FN_INVERT

dpnp/dpnp_algo/dpnp_algo_arraycreation.pyx

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ __all__ += [
4646
"dpnp_full",
4747
"dpnp_full_like",
4848
"dpnp_geomspace",
49+
"dpnp_identity",
4950
"dpnp_linspace",
5051
"dpnp_logspace",
5152
"dpnp_meshgrid",
@@ -167,6 +168,21 @@ cpdef dparray dpnp_geomspace(start, stop, num, endpoint, dtype, axis):
167168
return result
168169

169170

171+
cpdef dparray dpnp_identity(n, result_dtype):
172+
cdef DPNPFuncType dtype_in = dpnp_dtype_to_DPNPFuncType(result_dtype)
173+
174+
cdef DPNPFuncData kernel_data = get_dpnp_function_ptr(DPNP_FN_IDENTITY, dtype_in, DPNP_FT_NONE)
175+
176+
result_type = dpnp_DPNPFuncType_to_dtype( < size_t > kernel_data.return_type)
177+
178+
cdef dparray result = dparray((n, n), dtype=result_type)
179+
180+
cdef fptr_1out_t func = <fptr_1out_t > kernel_data.ptr
181+
func(result.get_data(), n)
182+
183+
return result
184+
185+
170186
# TODO this function should work through dpnp_arange_c
171187
cpdef tuple dpnp_linspace(start, stop, num, endpoint, retstep, dtype, axis):
172188
cdef dparray result = dparray(num, dtype=dtype)

dpnp/dpnp_iface_arraycreation.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@
6666
"full",
6767
"full_like",
6868
"geomspace",
69+
"identity",
6970
"linspace",
7071
"loadtxt",
7172
"logspace",
@@ -711,6 +712,40 @@ def geomspace(start, stop, num=50, endpoint=True, dtype=None, axis=0):
711712
return call_origin(numpy.geomspace, start, stop, num, endpoint, dtype, axis)
712713

713714

715+
def identity(n, dtype=None, *, like=None):
716+
"""
717+
Return the identity array.
718+
719+
The identity array is a square array with ones on the main diagonal.
720+
721+
For full documentation refer to :obj:`numpy.identity`.
722+
723+
Limitations
724+
-----------
725+
Parameter ``like`` is currently not supported .
726+
727+
Examples
728+
--------
729+
>>> import dpnp as np
730+
>>> np.identity(3)
731+
array([[1., 0., 0.],
732+
[0., 1., 0.],
733+
[0., 0., 1.]])
734+
735+
"""
736+
if not use_origin_backend():
737+
if like is not None:
738+
pass
739+
elif n < 0:
740+
pass
741+
else:
742+
if dtype is None:
743+
dtype = dpnp.float64
744+
return dpnp_identity(n, dtype)
745+
746+
return call_origin(numpy.identity, n, dtype=dtype, like=like)
747+
748+
714749
def linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None, axis=0):
715750
"""
716751
Return evenly spaced numbers over a specified interval.

tests/skipped_tests.tbl

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,6 @@ tests/third_party/cupy/creation_tests/test_basic.py::TestBasic::test_eye
325325
tests/third_party/cupy/creation_tests/test_basic.py::TestBasic::test_full_default_dtype
326326
tests/third_party/cupy/creation_tests/test_basic.py::TestBasic::test_full_default_dtype_cpu_input
327327
tests/third_party/cupy/creation_tests/test_basic.py::TestBasic::test_full_like_subok
328-
tests/third_party/cupy/creation_tests/test_basic.py::TestBasic::test_identity
329328
tests/third_party/cupy/creation_tests/test_basic.py::TestBasic::test_ones_like_subok
330329
tests/third_party/cupy/creation_tests/test_basic.py::TestBasic::test_zeros_like_subok
331330
tests/third_party/cupy/creation_tests/test_basic.py::TestBasic::test_zeros_strides

tests/skipped_tests_gpu.tbl

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -389,7 +389,6 @@ tests/third_party/cupy/creation_tests/test_basic.py::TestBasic::test_eye
389389
tests/third_party/cupy/creation_tests/test_basic.py::TestBasic::test_full_default_dtype
390390
tests/third_party/cupy/creation_tests/test_basic.py::TestBasic::test_full_default_dtype_cpu_input
391391
tests/third_party/cupy/creation_tests/test_basic.py::TestBasic::test_full_like_subok
392-
tests/third_party/cupy/creation_tests/test_basic.py::TestBasic::test_identity
393392
tests/third_party/cupy/creation_tests/test_basic.py::TestBasic::test_ones_like_subok
394393
tests/third_party/cupy/creation_tests/test_basic.py::TestBasic::test_zeros_like_subok
395394
tests/third_party/cupy/creation_tests/test_basic.py::TestBasic::test_zeros_strides

tests/test_arraycreation.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,19 @@ def test_geomspace(type, num, endpoint):
122122
numpy.testing.assert_allclose(dpnp_res, np_res)
123123

124124

125+
@pytest.mark.parametrize("n",
126+
[0, 1, 4],
127+
ids=['0', '1', '4'])
128+
@pytest.mark.parametrize("type",
129+
[numpy.float64, numpy.float32, numpy.int64,
130+
numpy.int32, numpy.bool, numpy.complex128, None],
131+
ids=['float64', 'float32', 'int64', 'int32', 'bool', 'complex128', 'None'])
132+
def test_identity(n, type):
133+
expected = numpy.identity(n, dtype=type)
134+
result = dpnp.identity(n, dtype=type)
135+
numpy.testing.assert_array_equal(expected, result)
136+
137+
125138
@pytest.mark.parametrize("type",
126139
[numpy.float64, numpy.float32, numpy.int64, numpy.int32],
127140
ids=['float64', 'float32', 'int64', 'int32'])

0 commit comments

Comments
 (0)