From cba65c2b6c06a87e59b7670adc0cb729290e1b63 Mon Sep 17 00:00:00 2001 From: KsanaKozlova Date: Fri, 21 May 2021 16:51:40 +0300 Subject: [PATCH 1/7] add out to matmul function --- dpnp/dpnp_algo/dpnp_algo.pyx | 18 +++++++++++++++--- dpnp/dpnp_iface.py | 32 ++++++++++++++++---------------- tests/test_mixins.py | 19 +++++++++++++++++++ 3 files changed, 50 insertions(+), 19 deletions(-) diff --git a/dpnp/dpnp_algo/dpnp_algo.pyx b/dpnp/dpnp_algo/dpnp_algo.pyx index 0311da775986..ef2cab6a788c 100644 --- a/dpnp/dpnp_algo/dpnp_algo.pyx +++ b/dpnp/dpnp_algo/dpnp_algo.pyx @@ -174,7 +174,8 @@ cpdef dparray dpnp_init_val(shape, dtype, value): return result -cpdef dparray dpnp_matmul(dparray in_array1, dparray in_array2): +cpdef dparray dpnp_matmul(dparray in_array1, dparray in_array2, dparray out=None): + cdef vector[Py_ssize_t] shape_result cdef vector[Py_ssize_t] shape1 = in_array1.shape @@ -235,8 +236,19 @@ cpdef dparray dpnp_matmul(dparray in_array1, dparray in_array2): cdef DPNPFuncData kernel_data = get_dpnp_function_ptr(DPNP_FN_MATMUL, param1_type, param2_type) result_type = dpnp_DPNPFuncType_to_dtype(< size_t > kernel_data.return_type) - # ceate result array with type given by FPTR data - cdef dparray result = dparray(shape_result, dtype=result_type) + + cdef dparray result + + if out is not None: + if out.dtype != result_type: + raise TypeError + elif out.shape != shape_result: + raise ValueError + else: + result = out + else: + result = dparray(shape_result, dtype=result_type) + if result.size == 0: return result diff --git a/dpnp/dpnp_iface.py b/dpnp/dpnp_iface.py index 607f3ef3b920..ebefa0e01424 100644 --- a/dpnp/dpnp_iface.py +++ b/dpnp/dpnp_iface.py @@ -144,7 +144,7 @@ def get_include(): return dpnp_path -def matmul(in_array1, in_array2, out=None): +def matmul(in_array1, in_array2, out=None, **kwargs): """ Matrix product of two arrays. @@ -154,7 +154,7 @@ def matmul(in_array1, in_array2, out=None): ----------- Input arrays are supported as :obj:`dpnp.ndarray`. Otherwise the function will be executed sequentially on CPU. - Parameter ``out`` is supported only with default value ``None``. + Parameter ``out`` is supported as :obj:`dpnp.ndarray` and as default value ``None``. Input array data types are limited by supported DPNP :ref:`Data types`. See Also @@ -182,12 +182,9 @@ def matmul(in_array1, in_array2, out=None): is_dparray1 = isinstance(in_array1, dparray) is_dparray2 = isinstance(in_array2, dparray) + is_dparray_out = isinstance(out, dparray) - if (not use_origin_backend(in_array1) and is_dparray1 and is_dparray2): - - if out is not None: - checker_throw_value_error("matmul", "out", type(out), None) - + if not use_origin_backend(in_array1) and not kwargs: """ Cost model checks """ @@ -201,12 +198,15 @@ def matmul(in_array1, in_array2, out=None): dparray1_size = in_array1.size dparray2_size = in_array2.size - if (dparray1_size > cost_size) and (dparray2_size > cost_size): - # print(f"dparray1_size={dparray1_size}") - return dpnp_matmul(in_array1, in_array2) - - input1 = asnumpy(in_array1) if is_dparray1 else in_array1 - input2 = asnumpy(in_array2) if is_dparray2 else in_array2 - - # TODO need to return dparray instead ndarray - return numpy.matmul(input1, input2, out=out) + if not isinstance(in_array1, dparray): + pass + elif not isinstance(in_array2, dparray): + pass + elif out is not None and not isinstance(out, dparray) : + pass + elif (dparray1_size < cost_size) or (dparray2_size < cost_size): + pass + else: + return dpnp_matmul(in_array1, in_array2, out=out) + + return call_origin(numpy.matmul, in_array1, in_array2, out=out, **kwargs) diff --git a/tests/test_mixins.py b/tests/test_mixins.py index 4635d605e96e..fc93fc796ea8 100644 --- a/tests/test_mixins.py +++ b/tests/test_mixins.py @@ -46,6 +46,25 @@ def test_matmul2(self): numpy.testing.assert_array_equal(expected, result) + def test_matmul3(self): + array_data = [1., 2., 3., 4., 5.] + out = numpy.empty(5) + + # DPNP + array1 = inp.array(array_data, dtype=inp.float64) + array2 = inp.array(array_data, dtype=inp.float64) + out1 = inp.array(out, dtype=inp.float64) + result = inp.matmul(array1, array2, out=out1) + # print(result) + + # original + array_1 = numpy.array(array_data, dtype=numpy.float64) + array_2 = numpy.array(array_data, dtype=numpy.float64) + expected = numpy.matmul(array_1, array_2, out=out) + # print(expected) + + numpy.testing.assert_array_equal(expected, result) + if __name__ == '__main__': unittest.main() From 55e3b5334417ba28c6784dde15c83df2506b6799 Mon Sep 17 00:00:00 2001 From: KsanaKozlova Date: Mon, 24 May 2021 12:15:36 +0300 Subject: [PATCH 2/7] fix test --- dpnp/dpnp_algo/dpnp_algo.pyx | 6 +++--- dpnp/dpnp_iface.py | 2 +- tests/test_mixins.py | 15 +++++++-------- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/dpnp/dpnp_algo/dpnp_algo.pyx b/dpnp/dpnp_algo/dpnp_algo.pyx index ef2cab6a788c..277e897acc38 100644 --- a/dpnp/dpnp_algo/dpnp_algo.pyx +++ b/dpnp/dpnp_algo/dpnp_algo.pyx @@ -241,14 +241,14 @@ cpdef dparray dpnp_matmul(dparray in_array1, dparray in_array2, dparray out=None if out is not None: if out.dtype != result_type: - raise TypeError + raise TypeError("Inappropriate type of ``out`` variable") elif out.shape != shape_result: - raise ValueError + raise ValueError("Inappropriate shape of ``out`` variable") else: result = out else: result = dparray(shape_result, dtype=result_type) - + if result.size == 0: return result diff --git a/dpnp/dpnp_iface.py b/dpnp/dpnp_iface.py index ebefa0e01424..594312944a56 100644 --- a/dpnp/dpnp_iface.py +++ b/dpnp/dpnp_iface.py @@ -202,7 +202,7 @@ def matmul(in_array1, in_array2, out=None, **kwargs): pass elif not isinstance(in_array2, dparray): pass - elif out is not None and not isinstance(out, dparray) : + elif out is not None and not isinstance(out, dparray): pass elif (dparray1_size < cost_size) or (dparray2_size < cost_size): pass diff --git a/tests/test_mixins.py b/tests/test_mixins.py index fc93fc796ea8..6943a4f2a993 100644 --- a/tests/test_mixins.py +++ b/tests/test_mixins.py @@ -47,21 +47,20 @@ def test_matmul2(self): numpy.testing.assert_array_equal(expected, result) def test_matmul3(self): - array_data = [1., 2., 3., 4., 5.] - out = numpy.empty(5) + array_data1 = numpy.full((513, 513), 5) + array_data2 = numpy.full((513, 513), 2) + out = numpy.empty((513, 513), dtype=numpy.float64) # DPNP - array1 = inp.array(array_data, dtype=inp.float64) - array2 = inp.array(array_data, dtype=inp.float64) + array1 = inp.array(array_data1, dtype=inp.float64) + array2 = inp.array(array_data2, dtype=inp.float64) out1 = inp.array(out, dtype=inp.float64) result = inp.matmul(array1, array2, out=out1) - # print(result) # original - array_1 = numpy.array(array_data, dtype=numpy.float64) - array_2 = numpy.array(array_data, dtype=numpy.float64) + array_1 = numpy.array(array_data1, dtype=numpy.float64) + array_2 = numpy.array(array_data2, dtype=numpy.float64) expected = numpy.matmul(array_1, array_2, out=out) - # print(expected) numpy.testing.assert_array_equal(expected, result) From 4be7e2c68f9e7644c3d10b731a4f5afeeb48240a Mon Sep 17 00:00:00 2001 From: KsanaKozlova Date: Tue, 25 May 2021 16:45:49 +0300 Subject: [PATCH 3/7] change error description --- dpnp/dpnp_algo/dpnp_algo.pyx | 9 ++++----- dpnp/dpnp_iface.py | 4 ++-- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/dpnp/dpnp_algo/dpnp_algo.pyx b/dpnp/dpnp_algo/dpnp_algo.pyx index 277e897acc38..93497f5c30e1 100644 --- a/dpnp/dpnp_algo/dpnp_algo.pyx +++ b/dpnp/dpnp_algo/dpnp_algo.pyx @@ -241,11 +241,10 @@ cpdef dparray dpnp_matmul(dparray in_array1, dparray in_array2, dparray out=None if out is not None: if out.dtype != result_type: - raise TypeError("Inappropriate type of ``out`` variable") - elif out.shape != shape_result: - raise ValueError("Inappropriate shape of ``out`` variable") - else: - result = out + checker_throw_value_error('matmul', 'out.dtype', out.dtype, result_type) + if out.shape != shape_result: + checker_throw_value_error('matmul', 'out.shape', out.shape, shape_result) + result = out else: result = dparray(shape_result, dtype=result_type) diff --git a/dpnp/dpnp_iface.py b/dpnp/dpnp_iface.py index 594312944a56..e9fb9d416011 100644 --- a/dpnp/dpnp_iface.py +++ b/dpnp/dpnp_iface.py @@ -182,7 +182,7 @@ def matmul(in_array1, in_array2, out=None, **kwargs): is_dparray1 = isinstance(in_array1, dparray) is_dparray2 = isinstance(in_array2, dparray) - is_dparray_out = isinstance(out, dparray) + out_is_dparray = isinstance(out, dparray) if not use_origin_backend(in_array1) and not kwargs: """ @@ -202,7 +202,7 @@ def matmul(in_array1, in_array2, out=None, **kwargs): pass elif not isinstance(in_array2, dparray): pass - elif out is not None and not isinstance(out, dparray): + elif out is not None and not out_is_dparray: pass elif (dparray1_size < cost_size) or (dparray2_size < cost_size): pass From df2f2b3747a3b11fda8c084e94f49bb1cc66d66f Mon Sep 17 00:00:00 2001 From: Sergey Shalnov Date: Sun, 20 Jun 2021 08:47:24 -0500 Subject: [PATCH 4/7] Update dpnp_iface.py --- dpnp/dpnp_iface.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/dpnp/dpnp_iface.py b/dpnp/dpnp_iface.py index e9fb9d416011..792a09d32e5d 100644 --- a/dpnp/dpnp_iface.py +++ b/dpnp/dpnp_iface.py @@ -195,16 +195,13 @@ def matmul(in_array1, in_array2, out=None, **kwargs): """ cost_size = 262144 # 2D array shape(512, 512) - dparray1_size = in_array1.size - dparray2_size = in_array2.size - if not isinstance(in_array1, dparray): pass elif not isinstance(in_array2, dparray): pass elif out is not None and not out_is_dparray: pass - elif (dparray1_size < cost_size) or (dparray2_size < cost_size): + elif (in_array1.size < cost_size) or (in_array2.size < cost_size): pass else: return dpnp_matmul(in_array1, in_array2, out=out) From b04134835bcf7762b464da41313fa9e3a91ed2f4 Mon Sep 17 00:00:00 2001 From: Sergey Shalnov Date: Sun, 20 Jun 2021 09:30:07 -0500 Subject: [PATCH 5/7] move cost model checks to last branch --- dpnp/dpnp_iface.py | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/dpnp/dpnp_iface.py b/dpnp/dpnp_iface.py index 792a09d32e5d..5c3decbb236f 100644 --- a/dpnp/dpnp_iface.py +++ b/dpnp/dpnp_iface.py @@ -185,25 +185,24 @@ def matmul(in_array1, in_array2, out=None, **kwargs): out_is_dparray = isinstance(out, dparray) if not use_origin_backend(in_array1) and not kwargs: - """ - Cost model checks - """ - cost_size = 4096 # 2D array shape(64, 64) - if ((in_array1.dtype == numpy.float64) or (in_array1.dtype == numpy.float32)): - """ - Floating point types are handled via original math library better than SYCL math library - """ - cost_size = 262144 # 2D array shape(512, 512) - if not isinstance(in_array1, dparray): pass elif not isinstance(in_array2, dparray): pass elif out is not None and not out_is_dparray: pass - elif (in_array1.size < cost_size) or (in_array2.size < cost_size): - pass else: - return dpnp_matmul(in_array1, in_array2, out=out) + """ + Cost model checks + """ + cost_size = 4096 # 2D array shape(64, 64) + if ((in_array1.dtype == numpy.float64) or (in_array1.dtype == numpy.float32)): + """ + Floating point types are handled via original math library better than SYCL math library + """ + cost_size = 262144 # 2D array shape(512, 512) + + if (dparray1_size > cost_size) and (dparray2_size > cost_size): + return dpnp_matmul(in_array1, in_array2, out=out) return call_origin(numpy.matmul, in_array1, in_array2, out=out, **kwargs) From c37c92babf4dfe3e5686c47aeb6c91d65ed74ca4 Mon Sep 17 00:00:00 2001 From: Sergey Shalnov Date: Sun, 20 Jun 2021 09:32:53 -0500 Subject: [PATCH 6/7] Update dpnp_iface.py --- dpnp/dpnp_iface.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/dpnp/dpnp_iface.py b/dpnp/dpnp_iface.py index 5c3decbb236f..174794d2de33 100644 --- a/dpnp/dpnp_iface.py +++ b/dpnp/dpnp_iface.py @@ -180,16 +180,12 @@ def matmul(in_array1, in_array2, out=None, **kwargs): """ - is_dparray1 = isinstance(in_array1, dparray) - is_dparray2 = isinstance(in_array2, dparray) - out_is_dparray = isinstance(out, dparray) - if not use_origin_backend(in_array1) and not kwargs: if not isinstance(in_array1, dparray): pass elif not isinstance(in_array2, dparray): pass - elif out is not None and not out_is_dparray: + elif out is not None and not isinstance(out, dparray): pass else: """ From 9aa3c3fe8925bd78738aef7836e733ddf1711ac3 Mon Sep 17 00:00:00 2001 From: Sergey Shalnov Date: Sun, 20 Jun 2021 10:35:55 -0500 Subject: [PATCH 7/7] Update dpnp_iface.py --- dpnp/dpnp_iface.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/dpnp/dpnp_iface.py b/dpnp/dpnp_iface.py index 174794d2de33..d55281520f11 100644 --- a/dpnp/dpnp_iface.py +++ b/dpnp/dpnp_iface.py @@ -191,7 +191,11 @@ def matmul(in_array1, in_array2, out=None, **kwargs): """ Cost model checks """ + + dparray1_size = in_array1.size + dparray2_size = in_array2.size cost_size = 4096 # 2D array shape(64, 64) + if ((in_array1.dtype == numpy.float64) or (in_array1.dtype == numpy.float32)): """ Floating point types are handled via original math library better than SYCL math library