From ff2dd42330f3d4d46ad4b4d9dd9460761dbd2e59 Mon Sep 17 00:00:00 2001 From: Vahid Tavanashad Date: Wed, 16 Aug 2023 14:35:21 -0500 Subject: [PATCH 1/3] use dpctl.tensor.sign and dpctl.tensor.negative in dpnp --- dpnp/backend/include/dpnp_iface_fptr.hpp | 8 +- dpnp/backend/kernels/dpnp_krnl_elemwise.cpp | 18 --- dpnp/dpnp_algo/dpnp_algo.pxd | 5 - dpnp/dpnp_algo/dpnp_algo_mathematical.pxi | 10 -- dpnp/dpnp_algo/dpnp_elementwise_common.py | 77 +++++++++++++ dpnp/dpnp_iface_mathematical.py | 118 +++++++++++++++----- dpnp/dpnp_iface_trigonometric.py | 48 ++++---- tests/skipped_tests_gpu.tbl | 2 - 8 files changed, 193 insertions(+), 93 deletions(-) diff --git a/dpnp/backend/include/dpnp_iface_fptr.hpp b/dpnp/backend/include/dpnp_iface_fptr.hpp index 418bed21966..733d2d0f215 100644 --- a/dpnp/backend/include/dpnp_iface_fptr.hpp +++ b/dpnp/backend/include/dpnp_iface_fptr.hpp @@ -282,8 +282,6 @@ enum class DPNPFuncName : size_t DPNP_FN_NANVAR_EXT, /**< Used in numpy.nanvar() impl, requires extra parameters */ DPNP_FN_NEGATIVE, /**< Used in numpy.negative() impl */ - DPNP_FN_NEGATIVE_EXT, /**< Used in numpy.negative() impl, requires extra - parameters */ DPNP_FN_NONZERO, /**< Used in numpy.nonzero() impl */ DPNP_FN_NOT_EQUAL_EXT, /**< Used in numpy.not_equal() impl, requires extra parameters */ @@ -441,10 +439,8 @@ enum class DPNPFuncName : size_t DPNP_FN_SEARCHSORTED_EXT, /**< Used in numpy.searchsorted() impl, requires extra parameters */ DPNP_FN_SIGN, /**< Used in numpy.sign() impl */ - DPNP_FN_SIGN_EXT, /**< Used in numpy.sign() impl, requires extra parameters - */ - DPNP_FN_SIN, /**< Used in numpy.sin() impl */ - DPNP_FN_SINH, /**< Used in numpy.sinh() impl */ + DPNP_FN_SIN, /**< Used in numpy.sin() impl */ + DPNP_FN_SINH, /**< Used in numpy.sinh() impl */ DPNP_FN_SINH_EXT, /**< Used in numpy.sinh() impl, requires extra parameters */ DPNP_FN_SORT, /**< Used in numpy.sort() impl */ diff --git a/dpnp/backend/kernels/dpnp_krnl_elemwise.cpp b/dpnp/backend/kernels/dpnp_krnl_elemwise.cpp index d99510fde91..8fb510e9fab 100644 --- a/dpnp/backend/kernels/dpnp_krnl_elemwise.cpp +++ b/dpnp/backend/kernels/dpnp_krnl_elemwise.cpp @@ -1061,15 +1061,6 @@ static void func_map_init_elemwise_1arg_1type(func_map_t &fmap) fmap[DPNPFuncName::DPNP_FN_NEGATIVE][eft_DBL][eft_DBL] = { eft_DBL, (void *)dpnp_negative_c_default}; - fmap[DPNPFuncName::DPNP_FN_NEGATIVE_EXT][eft_INT][eft_INT] = { - eft_INT, (void *)dpnp_negative_c_ext}; - fmap[DPNPFuncName::DPNP_FN_NEGATIVE_EXT][eft_LNG][eft_LNG] = { - eft_LNG, (void *)dpnp_negative_c_ext}; - fmap[DPNPFuncName::DPNP_FN_NEGATIVE_EXT][eft_FLT][eft_FLT] = { - eft_FLT, (void *)dpnp_negative_c_ext}; - fmap[DPNPFuncName::DPNP_FN_NEGATIVE_EXT][eft_DBL][eft_DBL] = { - eft_DBL, (void *)dpnp_negative_c_ext}; - fmap[DPNPFuncName::DPNP_FN_RECIP][eft_INT][eft_INT] = { eft_INT, (void *)dpnp_recip_c_default}; fmap[DPNPFuncName::DPNP_FN_RECIP][eft_LNG][eft_LNG] = { @@ -1097,15 +1088,6 @@ static void func_map_init_elemwise_1arg_1type(func_map_t &fmap) fmap[DPNPFuncName::DPNP_FN_SIGN][eft_DBL][eft_DBL] = { eft_DBL, (void *)dpnp_sign_c_default}; - fmap[DPNPFuncName::DPNP_FN_SIGN_EXT][eft_INT][eft_INT] = { - eft_INT, (void *)dpnp_sign_c_ext}; - fmap[DPNPFuncName::DPNP_FN_SIGN_EXT][eft_LNG][eft_LNG] = { - eft_LNG, (void *)dpnp_sign_c_ext}; - fmap[DPNPFuncName::DPNP_FN_SIGN_EXT][eft_FLT][eft_FLT] = { - eft_FLT, (void *)dpnp_sign_c_ext}; - fmap[DPNPFuncName::DPNP_FN_SIGN_EXT][eft_DBL][eft_DBL] = { - eft_DBL, (void *)dpnp_sign_c_ext}; - fmap[DPNPFuncName::DPNP_FN_SQUARE][eft_INT][eft_INT] = { eft_INT, (void *)dpnp_square_c_default}; fmap[DPNPFuncName::DPNP_FN_SQUARE][eft_LNG][eft_LNG] = { diff --git a/dpnp/dpnp_algo/dpnp_algo.pxd b/dpnp/dpnp_algo/dpnp_algo.pxd index 089e45e7c71..9a4a556435a 100644 --- a/dpnp/dpnp_algo/dpnp_algo.pxd +++ b/dpnp/dpnp_algo/dpnp_algo.pxd @@ -160,8 +160,6 @@ cdef extern from "dpnp_iface_fptr.hpp" namespace "DPNPFuncName": # need this na DPNP_FN_MODF_EXT DPNP_FN_NANVAR DPNP_FN_NANVAR_EXT - DPNP_FN_NEGATIVE - DPNP_FN_NEGATIVE_EXT DPNP_FN_NONZERO DPNP_FN_ONES DPNP_FN_ONES_LIKE @@ -257,8 +255,6 @@ cdef extern from "dpnp_iface_fptr.hpp" namespace "DPNPFuncName": # need this na DPNP_FN_RNG_ZIPF_EXT DPNP_FN_SEARCHSORTED DPNP_FN_SEARCHSORTED_EXT - DPNP_FN_SIGN - DPNP_FN_SIGN_EXT DPNP_FN_SINH DPNP_FN_SINH_EXT DPNP_FN_SORT @@ -427,7 +423,6 @@ cpdef dpnp_descriptor dpnp_maximum(dpnp_descriptor x1_obj, dpnp_descriptor x2_ob dpnp_descriptor out=*, object where=*) cpdef dpnp_descriptor dpnp_minimum(dpnp_descriptor x1_obj, dpnp_descriptor x2_obj, object dtype=*, dpnp_descriptor out=*, object where=*) -cpdef dpnp_descriptor dpnp_negative(dpnp_descriptor array1) cpdef dpnp_descriptor dpnp_power(dpnp_descriptor x1_obj, dpnp_descriptor x2_obj, object dtype=*, dpnp_descriptor out=*, object where=*) diff --git a/dpnp/dpnp_algo/dpnp_algo_mathematical.pxi b/dpnp/dpnp_algo/dpnp_algo_mathematical.pxi index 64003efd7ac..86579933b01 100644 --- a/dpnp/dpnp_algo/dpnp_algo_mathematical.pxi +++ b/dpnp/dpnp_algo/dpnp_algo_mathematical.pxi @@ -56,10 +56,8 @@ __all__ += [ "dpnp_nancumsum", "dpnp_nanprod", "dpnp_nansum", - "dpnp_negative", "dpnp_power", "dpnp_prod", - "dpnp_sign", "dpnp_sum", "dpnp_trapz", ] @@ -455,10 +453,6 @@ cpdef utils.dpnp_descriptor dpnp_nansum(utils.dpnp_descriptor x1): return dpnp_sum(result) -cpdef utils.dpnp_descriptor dpnp_negative(dpnp_descriptor x1): - return call_fptr_1in_1out_strides(DPNP_FN_NEGATIVE_EXT, x1) - - cpdef utils.dpnp_descriptor dpnp_power(utils.dpnp_descriptor x1_obj, utils.dpnp_descriptor x2_obj, object dtype=None, @@ -529,10 +523,6 @@ cpdef utils.dpnp_descriptor dpnp_prod(utils.dpnp_descriptor x1, return result -cpdef utils.dpnp_descriptor dpnp_sign(utils.dpnp_descriptor x1): - return call_fptr_1in_1out_strides(DPNP_FN_SIGN_EXT, x1) - - cpdef utils.dpnp_descriptor dpnp_sum(utils.dpnp_descriptor x1, object axis=None, object dtype=None, diff --git a/dpnp/dpnp_algo/dpnp_elementwise_common.py b/dpnp/dpnp_algo/dpnp_elementwise_common.py index 7735dae3634..188bfe7d2a4 100644 --- a/dpnp/dpnp_algo/dpnp_elementwise_common.py +++ b/dpnp/dpnp_algo/dpnp_elementwise_common.py @@ -1390,6 +1390,42 @@ def dpnp_multiply(x1, x2, out=None, order="K"): return dpnp_array._create_from_usm_ndarray(res_usm) +_negative_docstring = """ +negative(x, out=None, order="K") + +Computes the numerical negative for each element `x_i` of input array `x`. + +Args: + x (dpnp.ndarray): + Input array, expected to have numeric data type. + out ({None, dpnp.ndarray}, optional): + Output array to populate. + Array have the correct shape and the expected data type. + order ("C","F","A","K", optional): + Memory layout of the newly output array, if parameter `out` is `None`. + Default: "K". +Returns: + dpnp.ndarray: + An array containing the negative of `x`. +""" + + +negative_func = UnaryElementwiseFunc( + "negative", ti._negative_result_type, ti._negative, _negative_docstring +) + + +def dpnp_negative(x, out=None, order="K"): + """Invokes negative() from dpctl.tensor implementation for negative() function.""" + + # dpctl.tensor only works with usm_ndarray + x1_usm = dpnp.get_usm_ndarray(x) + out_usm = None if out is None else dpnp.get_usm_ndarray(out) + + res_usm = negative_func(x1_usm, out=out_usm, order=order) + return dpnp_array._create_from_usm_ndarray(res_usm) + + _not_equal_docstring_ = """ not_equal(x1, x2, out=None, order="K") @@ -1525,6 +1561,47 @@ def dpnp_right_shift(x1, x2, out=None, order="K"): return dpnp_array._create_from_usm_ndarray(res_usm) +_sign_docstring = """ +sign(x, out=None, order="K") + +Computes an indication of the sign of each element `x_i` of input array `x` +using the signum function. + +The signum function returns `-1` if `x_i` is less than `0`, +`0` if `x_i` is equal to `0`, and `1` if `x_i` is greater than `0`. + +Args: + x (dpnp.ndarray): + Input array, expected to have numeric data type. + out ({None, dpnp.ndarray}, optional): + Output array to populate. + Array have the correct shape and the expected data type. + order ("C","F","A","K", optional): + Memory layout of the newly output array, if parameter `out` is `None`. + Default: "K". +Returns: + dpnp.ndarray: + An array containing the element-wise results. The data type of the + returned array is determined by the Type Promotion Rules. +""" + + +sign_func = UnaryElementwiseFunc( + "sign", ti._sign_result_type, ti._sign, _sign_docstring +) + + +def dpnp_sign(x, out=None, order="K"): + """Invokes sign() from dpctl.tensor implementation for sign() function.""" + + # dpctl.tensor only works with usm_ndarray + x1_usm = dpnp.get_usm_ndarray(x) + out_usm = None if out is None else dpnp.get_usm_ndarray(out) + + res_usm = sign_func(x1_usm, out=out_usm, order=order) + return dpnp_array._create_from_usm_ndarray(res_usm) + + _sin_docstring = """ sin(x, out=None, order='K') Computes sine for each element `x_i` of input array `x`. diff --git a/dpnp/dpnp_iface_mathematical.py b/dpnp/dpnp_iface_mathematical.py index a6850b0bce4..def99c6adbd 100644 --- a/dpnp/dpnp_iface_mathematical.py +++ b/dpnp/dpnp_iface_mathematical.py @@ -57,7 +57,9 @@ dpnp_floor, dpnp_floor_divide, dpnp_multiply, + dpnp_negative, dpnp_remainder, + dpnp_sign, dpnp_subtract, dpnp_trunc, ) @@ -1486,39 +1488,64 @@ def nansum(x1, **kwargs): return call_origin(numpy.nansum, x1, **kwargs) -def negative(x1, **kwargs): +def negative( + x, + /, + out=None, + *, + order="K", + where=True, + dtype=None, + subok=True, + **kwargs, +): """ Negative element-wise. For full documentation refer to :obj:`numpy.negative`. + Returns + ------- + out : dpnp.ndarray + The numerical negative of each element of `x`. + Limitations ----------- - Parameter `x1` is supported as :class:`dpnp.ndarray`. + Parameters `x` is only supported as either :class:`dpnp.ndarray` or :class:`dpctl.tensor.usm_ndarray`. + Parameters `where`, `dtype` and `subok` are supported with their default values. Keyword arguments `kwargs` are currently unsupported. Otherwise the function will be executed sequentially on CPU. Input array data types are limited by supported DPNP :ref:`Data types`. See Also -------- - :obj:`dpnp.copysign` : Change the sign of x1 to that of x2, element-wise. + :obj:`dpnp.copysign` : Change the sign of `x1` to that of `x2`, element-wise. Examples -------- >>> import dpnp as np - >>> result = np.negative([1, -1]) - >>> [x for x in result] - [-1, 1] + >>> np.negative(np.array([1, -1])) + array([-1, 1]) + + The ``-`` operator can be used as a shorthand for ``negative`` on + :class:`dpnp.ndarray`. + >>> x = np.array([1., -1.]) + >>> -x + array([-1., 1.]) """ - x1_desc = dpnp.get_dpnp_descriptor( - x1, copy_when_strides=False, copy_when_nondefault_queue=False + return check_nd_call_func( + numpy.negative, + dpnp_negative, + x, + out=out, + where=where, + order=order, + dtype=dtype, + subok=subok, + **kwargs, ) - if x1_desc and not kwargs: - return dpnp_negative(x1_desc).get_pyobj() - - return call_origin(numpy.negative, x1, **kwargs) def power(x1, x2, /, out=None, *, where=True, dtype=None, subok=True, **kwargs): @@ -1759,35 +1786,70 @@ def round_(a, decimals=0, out=None): return around(a, decimals, out) -def sign(x1, **kwargs): +def sign( + x, + /, + out=None, + *, + order="K", + where=True, + dtype=None, + subok=True, + **kwargs, +): """ Returns an element-wise indication of the sign of a number. For full documentation refer to :obj:`numpy.sign`. + Returns + ------- + out : dpnp.ndarray + The indication of the sign of each element of `x`. + Limitations ----------- - Parameter `x1` is supported as :class:`dpnp.ndarray`. - Keyword arguments `kwargs` are currently unsupported. + Parameters `x` is only supported as either :class:`dpnp.ndarray` or :class:`dpctl.tensor.usm_ndarray`. + Parameters `where`, `dtype` and `subok` are supported with their default values. + Keyword argument `kwargs` is currently unsupported. Otherwise the function will be executed sequentially on CPU. Input array data types are limited by supported DPNP :ref:`Data types`. Examples -------- >>> import dpnp as np - >>> result = np.sign(np.array([-5., 4.5])) - >>> [x for x in result] - [-1.0, 1.0] - - """ - - x1_desc = dpnp.get_dpnp_descriptor( - x1, copy_when_strides=False, copy_when_nondefault_queue=False - ) - if x1_desc and not kwargs: - return dpnp_sign(x1_desc).get_pyobj() - - return call_origin(numpy.sign, x1, **kwargs) + >>> np.sign(np.array([-5., 4.5])) + array([-1.0, 1.0]) + >>> np.sign(np.array(0)) + array(0) + >>> np.sign(np.array(5-2j)) + array([1+0j]) + + """ + + if numpy.iscomplexobj(x): + return call_origin( + numpy.sign, + x, + out=out, + where=where, + order=order, + dtype=dtype, + subok=subok, + **kwargs, + ) + else: + return check_nd_call_func( + numpy.sign, + dpnp_sign, + x, + out=out, + where=where, + order=order, + dtype=dtype, + subok=subok, + **kwargs, + ) def subtract( diff --git a/dpnp/dpnp_iface_trigonometric.py b/dpnp/dpnp_iface_trigonometric.py index d64359e1db8..dc91fa75eda 100644 --- a/dpnp/dpnp_iface_trigonometric.py +++ b/dpnp/dpnp_iface_trigonometric.py @@ -97,7 +97,7 @@ def arccos(x1): Limitations ----------- - Input array is supported as :obj:`dpnp.ndarray`. + Input array is supported as :class:`dpnp.ndarray`. Input array data types are limited by supported DPNP :ref:`Data types`. See Also @@ -133,7 +133,7 @@ def arccosh(x1): Limitations ----------- - Input array is supported as :obj:`dpnp.ndarray`. + Input array is supported as :class:`dpnp.ndarray`. Input array data types are limited by supported DPNP :ref:`Data types`. See Also @@ -171,8 +171,8 @@ def arcsin(x1, out=None, **kwargs): Limitations ----------- - Input array is supported as :obj:`dpnp.ndarray`. - Keyword arguments ``kwargs`` are currently unsupported. + Input array is supported as :class:`dpnp.ndarray`. + Keyword argument `kwargs` is currently unsupported. Input array data types are limited by supported DPNP :ref:`Data types`. See Also @@ -217,7 +217,7 @@ def arcsinh(x1): Limitations ----------- - Input array is supported as :obj:`dpnp.ndarray`. + Input array is supported as :class:`dpnp.ndarray`. Input array data types are limited by supported DPNP :ref:`Data types`. Examples @@ -247,8 +247,8 @@ def arctan(x1, out=None, **kwargs): Limitations ----------- - Input array is supported as :obj:`dpnp.ndarray`. - Keyword arguments ``kwargs`` are currently unsupported. + Input array is supported as :class:`dpnp.ndarray`. + Keyword argument `kwargs` is currently unsupported. Input array data types are limited by supported DPNP :ref:`Data types`. See Also @@ -289,7 +289,7 @@ def arctanh(x1): Limitations ----------- - Input array is supported as :obj:`dpnp.ndarray`. + Input array is supported as :class:`dpnp.ndarray`. Input array data types are limited by supported DPNP :ref:`Data types`. Examples @@ -319,7 +319,7 @@ def cbrt(x1): Limitations ----------- - Input array is supported as :obj:`dpnp.ndarray`. + Input array is supported as :class:`dpnp.ndarray`. Input array data types are limited by supported DPNP :ref:`Data types`. Examples @@ -349,10 +349,10 @@ def arctan2(x1, x2, dtype=None, out=None, where=True, **kwargs): Limitations ----------- - Parameters ``x1`` and ``x2`` are supported as either :obj:`dpnp.ndarray` or scalar. - Parameters ``dtype``, ``out`` and ``where`` are supported with their default values. - Keyword arguments ``kwargs`` are currently unsupported. - Otherwise the functions will be executed sequentially on CPU. + Parameters `x1` and `x2` are supported as either :obj:`dpnp.ndarray` or scalar. + Parameters `dtype`, `out` and `where` are supported with their default values. + Keyword argument `kwargs` is currently unsupported. + Otherwise the function will be executed sequentially on CPU. Input array data types are limited by supported DPNP :ref:`Data types`. See Also @@ -436,7 +436,7 @@ def cos( ----------- Parameter `x` is only supported as either :class:`dpnp.ndarray` or :class:`dpctl.tensor.usm_ndarray`. Parameters `where`, `dtype` and `subok` are supported with their default values. - Keyword arguments `kwargs` are currently unsupported. + Keyword argument `kwargs` is currently unsupported. Otherwise the function will be executed sequentially on CPU. Input array data types are limited by supported DPNP :ref:`Data types`. @@ -659,10 +659,10 @@ def hypot(x1, x2, dtype=None, out=None, where=True, **kwargs): Limitations ----------- - Parameters ``x1`` and ``x2`` are supported as either :obj:`dpnp.ndarray` or scalar. - Parameters ``dtype``, ``out`` and ``where`` are supported with their default values. - Keyword arguments ``kwargs`` are currently unsupported. - Otherwise the functions will be executed sequentially on CPU. + Parameters `x1` and `x2` are supported as either :obj:`dpnp.ndarray` or scalar. + Parameters `dtype`, `out` and `where` are supported with their default values. + Keyword argument `kwargs` is currently unsupported. + Otherwise the function will be executed sequentially on CPU. Input array data types are limited by supported DPNP :ref:`Data types`. Examples @@ -889,7 +889,7 @@ def reciprocal(x1, **kwargs): Limitations ----------- Input array is supported as :obj:`dpnp.ndarray`. - Keyword arguments ``kwargs`` are currently unsupported. + Keyword argument `kwargs` is currently unsupported. Otherwise the function will be executed sequentially on CPU. Input array data types are limited by supported DPNP :ref:`Data types`. @@ -989,7 +989,7 @@ def sin( ----------- Parameter `x` is only supported as either :class:`dpnp.ndarray` or :class:`dpctl.tensor.usm_ndarray`. Parameters `where`, `dtype` and `subok` are supported with their default values. - Keyword arguments `kwargs` are currently unsupported. + Keyword argument `kwargs` is currently unsupported. Otherwise the function will be executed sequentially on CPU. Input array data types are limited by supported DPNP :ref:`Data types`. @@ -1180,8 +1180,8 @@ def tan(x1, out=None, **kwargs): Limitations ----------- - Input array is supported as :obj:`dpnp.ndarray`. - Keyword arguments ``kwargs`` are currently unsupported. + Input array is supported as :class:`dpnp.ndarray`. + Keyword argument `kwargs` is currently unsupported. Input array data types are limited by supported DPNP :ref:`Data types`. Examples @@ -1216,7 +1216,7 @@ def tanh(x1): Limitations ----------- - Input array is supported as :obj:`dpnp.ndarray`. + Input array is supported as :class:`dpnp.ndarray`. Input array data types are limited by supported DPNP :ref:`Data types`. Examples @@ -1246,7 +1246,7 @@ def unwrap(x1): Limitations ----------- - Input array is supported as :obj:`dpnp.ndarray`. + Input array is supported as :class:`dpnp.ndarray`. Input array data types are limited by supported DPNP :ref:`Data types`. See Also diff --git a/tests/skipped_tests_gpu.tbl b/tests/skipped_tests_gpu.tbl index 79ca0610e32..6e56c2b9bbd 100644 --- a/tests/skipped_tests_gpu.tbl +++ b/tests/skipped_tests_gpu.tbl @@ -27,9 +27,7 @@ tests/test_sycl_queue.py::test_1in_1out[level_zero:gpu:0-nancumprod-data11] tests/test_sycl_queue.py::test_1in_1out[level_zero:gpu:0-nancumsum-data12] tests/test_sycl_queue.py::test_1in_1out[level_zero:gpu:0-nanprod-data13] tests/test_sycl_queue.py::test_1in_1out[level_zero:gpu:0-nansum-data14] -tests/test_sycl_queue.py::test_1in_1out[level_zero:gpu:0-negative-data15] tests/test_sycl_queue.py::test_1in_1out[level_zero:gpu:0-prod-data16] -tests/test_sycl_queue.py::test_1in_1out[level_zero:gpu:0-sign-data17] tests/test_sycl_queue.py::test_1in_1out[level_zero:gpu:0-sum-data18] tests/test_sycl_queue.py::test_1in_1out[level_zero:gpu:0-trapz-data19] From 6c2ad267c93a0cd8d26b3b087a8f48add390e26e Mon Sep 17 00:00:00 2001 From: Vahid Tavanashad Date: Mon, 21 Aug 2023 15:57:59 -0500 Subject: [PATCH 2/3] address comments --- dpnp/dpnp_algo/dpnp_elementwise_common.py | 11 +++++++ dpnp/dpnp_iface_logic.py | 38 +++++++++++------------ dpnp/dpnp_iface_mathematical.py | 5 +-- dpnp/dpnp_utils/dpnp_algo_utils.pyx | 4 +-- tests/test_mathematical.py | 31 +++++++++++++++++- tests/test_usm_type.py | 4 ++- 6 files changed, 68 insertions(+), 25 deletions(-) diff --git a/dpnp/dpnp_algo/dpnp_elementwise_common.py b/dpnp/dpnp_algo/dpnp_elementwise_common.py index 188bfe7d2a4..dd3a34369e3 100644 --- a/dpnp/dpnp_algo/dpnp_elementwise_common.py +++ b/dpnp/dpnp_algo/dpnp_elementwise_common.py @@ -1418,6 +1418,13 @@ def dpnp_multiply(x1, x2, out=None, order="K"): def dpnp_negative(x, out=None, order="K"): """Invokes negative() from dpctl.tensor implementation for negative() function.""" + # TODO: discuss with dpctl if the check is needed to be moved there + if not dpnp.isscalar(x) and x.dtype == dpnp.bool: + raise TypeError( + "DPNP boolean negative, the `-` operator, is not supported, " + "use the `~` operator or the logical_not function instead." + ) + # dpctl.tensor only works with usm_ndarray x1_usm = dpnp.get_usm_ndarray(x) out_usm = None if out is None else dpnp.get_usm_ndarray(out) @@ -1594,6 +1601,10 @@ def dpnp_right_shift(x1, x2, out=None, order="K"): def dpnp_sign(x, out=None, order="K"): """Invokes sign() from dpctl.tensor implementation for sign() function.""" + # TODO: discuss with dpctl if the check is needed to be moved there + if not dpnp.isscalar(x) and x.dtype == dpnp.bool: + raise TypeError("DPNP boolean sign is not supported.") + # dpctl.tensor only works with usm_ndarray x1_usm = dpnp.get_usm_ndarray(x) out_usm = None if out is None else dpnp.get_usm_ndarray(out) diff --git a/dpnp/dpnp_iface_logic.py b/dpnp/dpnp_iface_logic.py index a560b71a1a6..d867bbbd660 100644 --- a/dpnp/dpnp_iface_logic.py +++ b/dpnp/dpnp_iface_logic.py @@ -95,8 +95,8 @@ def all(x, /, axis=None, out=None, keepdims=False, *, where=True): Returns ------- dpnp.ndarray - An array with a data type of `bool` - containing the results of the logical AND reduction. + An array with a data type of `bool` + containing the results of the logical AND reduction. Limitations ----------- @@ -160,8 +160,8 @@ def allclose(x1, x2, rtol=1.0e-5, atol=1.0e-8, **kwargs): Limitations ----------- - Parameters ``x1`` and ``x2`` are supported as either :obj:`dpnp.ndarray` or scalar. - Keyword arguments ``kwargs`` are currently unsupported. + Parameters `x1` and `x2` are supported as either :class:`dpnp.ndarray` or scalar. + Keyword argument `kwargs` is currently unsupported. Otherwise the functions will be executed sequentially on CPU. Input array data types are limited by supported DPNP :ref:`Data types`. @@ -276,7 +276,7 @@ def equal( Returns ------- out : dpnp.ndarray - Output array of bool type, element-wise comparison of `x1` and `x2`. + Output array of bool type, element-wise comparison of `x1` and `x2`. Limitations ----------- @@ -352,7 +352,7 @@ def greater( Returns ------- out : dpnp.ndarray - Output array of bool type, element-wise comparison of `x1` and `x2`. + Output array of bool type, element-wise comparison of `x1` and `x2`. Limitations ----------- @@ -422,7 +422,7 @@ def greater_equal( Returns ------- out : dpnp.ndarray - Output array of bool type, element-wise comparison of `x1` and `x2`. + Output array of bool type, element-wise comparison of `x1` and `x2`. Limitations ----------- @@ -480,8 +480,8 @@ def isclose(x1, x2, rtol=1e-05, atol=1e-08, equal_nan=False): Limitations ----------- - ``x2`` is supported to be integer if ``x1`` is :obj:`dpnp.ndarray` or - at least either ``x1`` or ``x2`` should be as :obj:`dpnp.ndarray`. + `x2` is supported to be integer if `x1` is :class:`dpnp.ndarray` or + at least either `x1` or `x2` should be as :class:`dpnp.ndarray`. Otherwise the function will be executed sequentially on CPU. Input array data types are limited by supported DPNP :ref:`Data types`. @@ -678,7 +678,7 @@ def less( Returns ------- out : dpnp.ndarray - Output array of bool type, element-wise comparison of `x1` and `x2`. + Output array of bool type, element-wise comparison of `x1` and `x2`. Limitations ----------- @@ -748,7 +748,7 @@ def less_equal( Returns ------- out : dpnp.ndarray - Output array of bool type, element-wise comparison of `x1` and `x2`. + Output array of bool type, element-wise comparison of `x1` and `x2`. Limitations ----------- @@ -818,8 +818,8 @@ def logical_and( Returns ------- out : dpnp.ndarray - Boolean result of the logical AND operation applied to the elements - of `x1` and `x2`; the shape is determined by broadcasting. + Boolean result of the logical AND operation applied to the elements + of `x1` and `x2`; the shape is determined by broadcasting. Limitations ----------- @@ -891,8 +891,8 @@ def logical_not( Returns ------- out : dpnp.ndarray - Boolean result with the same shape as `x` of the NOT operation - on elements of `x`. + Boolean result with the same shape as `x` of the NOT operation + on elements of `x`. Limitations ----------- @@ -953,8 +953,8 @@ def logical_or( Returns ------- out : dpnp.ndarray - Boolean result of the logical OR operation applied to the elements - of `x1` and `x2`; the shape is determined by broadcasting. + Boolean result of the logical OR operation applied to the elements + of `x1` and `x2`; the shape is determined by broadcasting. Limitations ----------- @@ -1027,8 +1027,8 @@ def logical_xor( Returns ------- out : dpnp.ndarray - Boolean result of the logical XOR operation applied to the elements - of `x1` and `x2`; the shape is determined by broadcasting. + Boolean result of the logical XOR operation applied to the elements + of `x1` and `x2`; the shape is determined by broadcasting. Limitations ----------- diff --git a/dpnp/dpnp_iface_mathematical.py b/dpnp/dpnp_iface_mathematical.py index def99c6adbd..7552bcd2130 100644 --- a/dpnp/dpnp_iface_mathematical.py +++ b/dpnp/dpnp_iface_mathematical.py @@ -1507,7 +1507,7 @@ def negative( Returns ------- out : dpnp.ndarray - The numerical negative of each element of `x`. + The numerical negative of each element of `x`. Limitations ----------- @@ -1805,7 +1805,7 @@ def sign( Returns ------- out : dpnp.ndarray - The indication of the sign of each element of `x`. + The indication of the sign of each element of `x`. Limitations ----------- @@ -1814,6 +1814,7 @@ def sign( Keyword argument `kwargs` is currently unsupported. Otherwise the function will be executed sequentially on CPU. Input array data types are limited by supported DPNP :ref:`Data types`. + However, if the input array data type is complex, the function will be executed sequentially on CPU. Examples -------- diff --git a/dpnp/dpnp_utils/dpnp_algo_utils.pyx b/dpnp/dpnp_utils/dpnp_algo_utils.pyx index f88b42bde7f..9ec9174d400 100644 --- a/dpnp/dpnp_utils/dpnp_algo_utils.pyx +++ b/dpnp/dpnp_utils/dpnp_algo_utils.pyx @@ -131,8 +131,8 @@ def call_origin(function, *args, **kwargs): if not allow_fallback and config.__DPNP_RAISE_EXCEPION_ON_NUMPY_FALLBACK__ == 1: raise NotImplementedError(f"Requested funtion={function.__name__} with args={args} and kwargs={kwargs} " "isn't currently supported and would fall back on NumPy implementation. " - "Define enviroment variable `DPNP_RAISE_EXCEPION_ON_NUMPY_FALLBACK` to `0` " - "if the fall back is required to be supported without rasing an exception.") + "Define environment variable `DPNP_RAISE_EXCEPION_ON_NUMPY_FALLBACK` to `0` " + "if the fall back is required to be supported without raising an exception.") dpnp_inplace = kwargs.pop("dpnp_inplace", False) sycl_queue = kwargs.pop("sycl_queue", None) diff --git a/tests/test_mathematical.py b/tests/test_mathematical.py index 5c8ca88088e..2ae3494854d 100644 --- a/tests/test_mathematical.py +++ b/tests/test_mathematical.py @@ -392,7 +392,7 @@ def test_nancumsum(array): [[[1.0, -1.0], [0.1, -0.1]], [-2, -1, 0, 1, 2]], ids=["[[1., -1.], [0.1, -0.1]]", "[-2, -1, 0, 1, 2]"], ) -@pytest.mark.parametrize("dtype", get_all_dtypes(no_bool=True, no_complex=True)) +@pytest.mark.parametrize("dtype", get_all_dtypes(no_bool=True)) def test_negative(data, dtype): np_a = numpy.array(data, dtype=dtype) dpnp_a = dpnp.array(data, dtype=dtype) @@ -402,6 +402,35 @@ def test_negative(data, dtype): assert_allclose(result, expected) +def test_negative_boolean(): + dpnp_a = dpnp.array([True, False]) + + with pytest.raises(TypeError): + dpnp.negative(dpnp_a) + + +@pytest.mark.parametrize( + "data", + [[2, 0, -2], [1.1, -1.1]], + ids=["[2, 0, -2]", "[1.1, -1.1]"], +) +@pytest.mark.parametrize("dtype", get_all_dtypes(no_bool=True, no_complex=True)) +def test_sign(data, dtype): + np_a = numpy.array(data, dtype=dtype) + dpnp_a = dpnp.array(data, dtype=dtype) + + result = dpnp.sign(dpnp_a) + expected = numpy.sign(np_a) + assert_allclose(result, expected) + + +def test_sign_boolean(): + dpnp_a = dpnp.array([True, False]) + + with pytest.raises(TypeError): + dpnp.sign(dpnp_a) + + @pytest.mark.parametrize("val_type", get_all_dtypes(no_none=True)) @pytest.mark.parametrize("data_type", get_all_dtypes()) @pytest.mark.parametrize("val", [1.5, 1, 5], ids=["1.5", "1", "5"]) diff --git a/tests/test_usm_type.py b/tests/test_usm_type.py index d61331ffa08..4bf16022ba9 100644 --- a/tests/test_usm_type.py +++ b/tests/test_usm_type.py @@ -249,8 +249,10 @@ def test_meshgrid(usm_type_x, usm_type_y): "func,data", [ pytest.param("ceil", [-1.7, -1.5, -0.2, 0.2, 1.5, 1.7, 2.0]), - pytest.param("floor", [-1.7, -1.5, -0.2, 0.2, 1.5, 1.7, 2.0]), pytest.param("conjugate", [[1.0 + 1.0j, 0.0], [0.0, 1.0 + 1.0j]]), + pytest.param("floor", [-1.7, -1.5, -0.2, 0.2, 1.5, 1.7, 2.0]), + pytest.param("negative", [1.0, -1.0]), + pytest.param("sign", [-5.0, 4.5]), pytest.param("sqrt", [1.0, 3.0, 9.0]), pytest.param("trunc", [-1.7, -1.5, -0.2, 0.2, 1.5, 1.7, 2.0]), ], From 096857cb2f7a12f2d4ced3ccd173f99e4d831332 Mon Sep 17 00:00:00 2001 From: Vahid Tavanashad Date: Tue, 22 Aug 2023 04:33:58 -0500 Subject: [PATCH 3/3] add falls back on numpy for tests --- dpnp/dpnp_iface_bitwise.py | 4 ++-- tests/skipped_tests_gpu.tbl | 1 - tests/skipped_tests_gpu_no_fp64.tbl | 2 ++ tests/test_mathematical.py | 3 ++- tests/third_party/cupy/math_tests/test_misc.py | 1 + 5 files changed, 7 insertions(+), 4 deletions(-) diff --git a/dpnp/dpnp_iface_bitwise.py b/dpnp/dpnp_iface_bitwise.py index f3f0e2cfec8..eded1984809 100644 --- a/dpnp/dpnp_iface_bitwise.py +++ b/dpnp/dpnp_iface_bitwise.py @@ -374,7 +374,7 @@ def left_shift( >>> np.left_shift(x1, x2) array([10, 20, 40]) - The ``<<`` operator can be used as a shorthand for ``right_shift`` on + The ``<<`` operator can be used as a shorthand for ``left_shift`` on :class:`dpnp.ndarray`. >>> x1 << x2 @@ -437,7 +437,7 @@ def right_shift( >>> np.right_shift(x1, x2) array([5, 2, 1]) - The ``>>`` operator can be used as a shorthand for ``left_shift`` on + The ``>>`` operator can be used as a shorthand for ``right_shift`` on :class:`dpnp.ndarray`. >>> x1 >> x2 diff --git a/tests/skipped_tests_gpu.tbl b/tests/skipped_tests_gpu.tbl index 6e56c2b9bbd..0b95dde9bb5 100644 --- a/tests/skipped_tests_gpu.tbl +++ b/tests/skipped_tests_gpu.tbl @@ -721,7 +721,6 @@ tests/third_party/cupy/math_tests/test_floating.py::TestFloating::test_signbit tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_clip_min_max_none tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_external_clip4 tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_absolute_negative -tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_sign_negative tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_maximum_nan tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_minimum_nan tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_fmax_nan diff --git a/tests/skipped_tests_gpu_no_fp64.tbl b/tests/skipped_tests_gpu_no_fp64.tbl index 5fc5b57352c..31c4b499cd0 100644 --- a/tests/skipped_tests_gpu_no_fp64.tbl +++ b/tests/skipped_tests_gpu_no_fp64.tbl @@ -1220,6 +1220,8 @@ tests/third_party/cupy/math_tests/test_hyperbolic.py::TestHyperbolic::test_cosh tests/third_party/cupy/math_tests/test_hyperbolic.py::TestHyperbolic::test_sinh tests/third_party/cupy/math_tests/test_hyperbolic.py::TestHyperbolic::test_tanh +tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_sign_negative + tests/third_party/cupy/math_tests/test_sumprod.py::TestNansumNanprodLong_param_0_{axis=0, func='nansum', keepdims=True, shape=(2, 3, 4), transpose_axes=True}::test_nansum_all tests/third_party/cupy/math_tests/test_sumprod.py::TestNansumNanprodLong_param_0_{axis=0, func='nansum', keepdims=True, shape=(2, 3, 4), transpose_axes=True}::test_nansum_axis_transposed tests/third_party/cupy/math_tests/test_sumprod.py::TestNansumNanprodLong_param_1_{axis=0, func='nansum', keepdims=True, shape=(2, 3, 4), transpose_axes=False}::test_nansum_all diff --git a/tests/test_mathematical.py b/tests/test_mathematical.py index 2ae3494854d..2b5c98083e2 100644 --- a/tests/test_mathematical.py +++ b/tests/test_mathematical.py @@ -414,7 +414,8 @@ def test_negative_boolean(): [[2, 0, -2], [1.1, -1.1]], ids=["[2, 0, -2]", "[1.1, -1.1]"], ) -@pytest.mark.parametrize("dtype", get_all_dtypes(no_bool=True, no_complex=True)) +@pytest.mark.parametrize("dtype", get_all_dtypes(no_bool=True)) +@pytest.mark.usefixtures("allow_fall_back_on_numpy") def test_sign(data, dtype): np_a = numpy.array(data, dtype=dtype) dpnp_a = dpnp.array(data, dtype=dtype) diff --git a/tests/third_party/cupy/math_tests/test_misc.py b/tests/third_party/cupy/math_tests/test_misc.py index 9ae4ad058e2..f8e0a32f642 100644 --- a/tests/third_party/cupy/math_tests/test_misc.py +++ b/tests/third_party/cupy/math_tests/test_misc.py @@ -193,6 +193,7 @@ def test_fabs_negative(self, xp, dtype): def test_sign(self): self.check_unary("sign", no_bool=True) + @pytest.mark.usefixtures("allow_fall_back_on_numpy") def test_sign_negative(self): self.check_unary_negative("sign", no_bool=True)