From 5f37c22e6c0c8963fdcce69be38f913f91b8762f Mon Sep 17 00:00:00 2001 From: Natalia Polina Date: Thu, 29 Jun 2023 02:00:50 -0500 Subject: [PATCH 1/3] Reuse dpctl.tensor comparison functions. --- dpnp/dpnp_algo/dpnp_algo.pxd | 12 - dpnp/dpnp_algo/dpnp_algo_logic.pxi | 54 --- dpnp/dpnp_algo/dpnp_elementwise_common.py | 264 +++++++++++++- dpnp/dpnp_iface_logic.py | 425 ++++++++-------------- dpnp/random/dpnp_algo_random.pyx | 16 +- 5 files changed, 433 insertions(+), 338 deletions(-) diff --git a/dpnp/dpnp_algo/dpnp_algo.pxd b/dpnp/dpnp_algo/dpnp_algo.pxd index 3142f33e0d7..423076bc9c5 100644 --- a/dpnp/dpnp_algo/dpnp_algo.pxd +++ b/dpnp/dpnp_algo/dpnp_algo.pxd @@ -120,7 +120,6 @@ cdef extern from "dpnp_iface_fptr.hpp" namespace "DPNPFuncName": # need this na DPNP_FN_EIG_EXT DPNP_FN_EIGVALS DPNP_FN_EIGVALS_EXT - DPNP_FN_EQUAL_EXT DPNP_FN_ERF DPNP_FN_ERF_EXT DPNP_FN_EYE @@ -149,8 +148,6 @@ cdef extern from "dpnp_iface_fptr.hpp" namespace "DPNPFuncName": # need this na DPNP_FN_FMOD_EXT DPNP_FN_FULL DPNP_FN_FULL_LIKE - DPNP_FN_GREATER_EXT - DPNP_FN_GREATER_EQUAL_EXT DPNP_FN_HYPOT DPNP_FN_HYPOT_EXT DPNP_FN_IDENTITY @@ -165,8 +162,6 @@ cdef extern from "dpnp_iface_fptr.hpp" namespace "DPNPFuncName": # need this na DPNP_FN_KRON_EXT DPNP_FN_LEFT_SHIFT DPNP_FN_LEFT_SHIFT_EXT - DPNP_FN_LESS_EXT - DPNP_FN_LESS_EQUAL_EXT DPNP_FN_LOG DPNP_FN_LOG_EXT DPNP_FN_LOG10 @@ -200,7 +195,6 @@ cdef extern from "dpnp_iface_fptr.hpp" namespace "DPNPFuncName": # need this na DPNP_FN_NEGATIVE DPNP_FN_NEGATIVE_EXT DPNP_FN_NONZERO - DPNP_FN_NOT_EQUAL_EXT DPNP_FN_ONES DPNP_FN_ONES_LIKE DPNP_FN_PARTITION @@ -481,18 +475,12 @@ cpdef dpnp_descriptor dpnp_right_shift(dpnp_descriptor x1_obj, """ Logic functions """ -cpdef dpnp_descriptor dpnp_equal(dpnp_descriptor array1, dpnp_descriptor input2) -cpdef dpnp_descriptor dpnp_greater(dpnp_descriptor input1, dpnp_descriptor input2) -cpdef dpnp_descriptor dpnp_greater_equal(dpnp_descriptor input1, dpnp_descriptor input2) cpdef dpnp_descriptor dpnp_isclose(dpnp_descriptor input1, dpnp_descriptor input2, double rtol=*, double atol=*, cpp_bool equal_nan=*) -cpdef dpnp_descriptor dpnp_less(dpnp_descriptor input1, dpnp_descriptor input2) -cpdef dpnp_descriptor dpnp_less_equal(dpnp_descriptor input1, dpnp_descriptor input2) cpdef dpnp_descriptor dpnp_logical_and(dpnp_descriptor input1, dpnp_descriptor input2) cpdef dpnp_descriptor dpnp_logical_not(dpnp_descriptor input1) cpdef dpnp_descriptor dpnp_logical_or(dpnp_descriptor input1, dpnp_descriptor input2) cpdef dpnp_descriptor dpnp_logical_xor(dpnp_descriptor input1, dpnp_descriptor input2) -cpdef dpnp_descriptor dpnp_not_equal(dpnp_descriptor input1, dpnp_descriptor input2) """ diff --git a/dpnp/dpnp_algo/dpnp_algo_logic.pxi b/dpnp/dpnp_algo/dpnp_algo_logic.pxi index f84e90b186f..a45d3e0eb63 100644 --- a/dpnp/dpnp_algo/dpnp_algo_logic.pxi +++ b/dpnp/dpnp_algo/dpnp_algo_logic.pxi @@ -39,20 +39,14 @@ __all__ += [ "dpnp_all", "dpnp_allclose", "dpnp_any", - "dpnp_equal", - "dpnp_greater", - "dpnp_greater_equal", "dpnp_isclose", "dpnp_isfinite", "dpnp_isinf", "dpnp_isnan", - "dpnp_less", - "dpnp_less_equal", "dpnp_logical_and", "dpnp_logical_not", "dpnp_logical_or", "dpnp_logical_xor", - "dpnp_not_equal" ] @@ -167,30 +161,6 @@ cpdef utils.dpnp_descriptor dpnp_any(utils.dpnp_descriptor array1): return result -cpdef utils.dpnp_descriptor dpnp_equal(utils.dpnp_descriptor x1_obj, - utils.dpnp_descriptor x2_obj, - object dtype=None, - utils.dpnp_descriptor out=None, - object where=True): - return call_fptr_2in_1out_strides(DPNP_FN_EQUAL_EXT, x1_obj, x2_obj, dtype, out, where, func_name="equal") - - -cpdef utils.dpnp_descriptor dpnp_greater(utils.dpnp_descriptor x1_obj, - utils.dpnp_descriptor x2_obj, - object dtype=None, - utils.dpnp_descriptor out=None, - object where=True): - return call_fptr_2in_1out_strides(DPNP_FN_GREATER_EXT, x1_obj, x2_obj, dtype, out, where, func_name="greater") - - -cpdef utils.dpnp_descriptor dpnp_greater_equal(utils.dpnp_descriptor x1_obj, - utils.dpnp_descriptor x2_obj, - object dtype=None, - utils.dpnp_descriptor out=None, - object where=True): - return call_fptr_2in_1out_strides(DPNP_FN_GREATER_EQUAL_EXT, x1_obj, x2_obj, dtype, out, where, func_name="greater_equal") - - cpdef utils.dpnp_descriptor dpnp_isclose(utils.dpnp_descriptor input1, utils.dpnp_descriptor input2, double rtol=1e-05, @@ -255,22 +225,6 @@ cpdef utils.dpnp_descriptor dpnp_isnan(utils.dpnp_descriptor input1): return result -cpdef utils.dpnp_descriptor dpnp_less(utils.dpnp_descriptor x1_obj, - utils.dpnp_descriptor x2_obj, - object dtype=None, - utils.dpnp_descriptor out=None, - object where=True): - return call_fptr_2in_1out_strides(DPNP_FN_LESS_EXT, x1_obj, x2_obj, dtype, out, where, func_name="less") - - -cpdef utils.dpnp_descriptor dpnp_less_equal(utils.dpnp_descriptor x1_obj, - utils.dpnp_descriptor x2_obj, - object dtype=None, - utils.dpnp_descriptor out=None, - object where=True): - return call_fptr_2in_1out_strides(DPNP_FN_LESS_EQUAL_EXT, x1_obj, x2_obj, dtype, out, where, func_name="less_equal") - - cpdef utils.dpnp_descriptor dpnp_logical_and(utils.dpnp_descriptor x1_obj, utils.dpnp_descriptor x2_obj, object dtype=None, @@ -300,11 +254,3 @@ cpdef utils.dpnp_descriptor dpnp_logical_xor(utils.dpnp_descriptor x1_obj, utils.dpnp_descriptor out=None, object where=True): return call_fptr_2in_1out_strides(DPNP_FN_LOGICAL_XOR_EXT, x1_obj, x2_obj, dtype, out, where, func_name="logical_xor") - - -cpdef utils.dpnp_descriptor dpnp_not_equal(utils.dpnp_descriptor x1_obj, - utils.dpnp_descriptor x2_obj, - object dtype=None, - utils.dpnp_descriptor out=None, - object where=True): - return call_fptr_2in_1out_strides(DPNP_FN_NOT_EQUAL_EXT, x1_obj, x2_obj, dtype, out, where, func_name="not_equal") diff --git a/dpnp/dpnp_algo/dpnp_elementwise_common.py b/dpnp/dpnp_algo/dpnp_elementwise_common.py index a4dd92cec74..17059a26082 100644 --- a/dpnp/dpnp_algo/dpnp_elementwise_common.py +++ b/dpnp/dpnp_algo/dpnp_elementwise_common.py @@ -36,11 +36,22 @@ import dpnp.backend.extensions.vm._vm_impl as vmi from dpnp.dpnp_array import dpnp_array -__all__ = ["dpnp_add", "dpnp_divide", "dpnp_multiply", "dpnp_subtract"] +__all__ = [ + "dpnp_add", + "dpnp_divide", + "dpnp_equal", + "dpnp_greater", + "dpnp_greater_equal", + "dpnp_less", + "dpnp_less_equal", + "dpnp_multiply", + "dpnp_not_equal", + "dpnp_subtract", +] _add_docstring_ = """ -add(x1, x2, out=None, order='K') +add(x1, x2, out=None, order="K") Calculates the sum for each element `x1_i` of the input array `x1` with the respective element `x2_i` of the input array `x2`. @@ -85,7 +96,7 @@ def dpnp_add(x1, x2, out=None, order="K"): _divide_docstring_ = """ -divide(x1, x2, out=None, order='K') +divide(x1, x2, out=None, order="K") Calculates the ratio for each element `x1_i` of the input array `x1` with the respective element `x2_i` of the input array `x2`. @@ -163,7 +174,7 @@ def _call_divide_inplace(lhs, rhs, sycl_queue, depends=None): _multiply_docstring_ = """ -multiply(x1, x2, out=None, order='K') +multiply(x1, x2, out=None, order="K") Calculates the product for each element `x1_i` of the input array `x1` with the respective element `x2_i` of the input array `x2`. @@ -212,7 +223,7 @@ def dpnp_multiply(x1, x2, out=None, order="K"): _subtract_docstring_ = """ -subtract(x1, x2, out=None, order='K') +subtract(x1, x2, out=None, order="K") Calculates the difference bewteen each element `x1_i` of the input array `x1` and the respective element `x2_i` of the input array `x2`. @@ -269,3 +280,246 @@ def dpnp_subtract(x1, x2, out=None, order="K"): ) res_usm = func(x1_usm_or_scalar, x2_usm_or_scalar, out=out_usm, order=order) return dpnp_array._create_from_usm_ndarray(res_usm) + + +_less_docstring_ = """ +less(x1, x2, out=None, order="K") + +Calculates the less-than results for each element `x1_i` of +the input array `x1` the respective element `x2_i` of the input array `x2`. + +Args: + x1 (dpnp.ndarray): + First input array, expected to have numeric data type. + x2 (dpnp.ndarray): + Second input array, also 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", None, optional): + Memory layout of the newly output array, if parameter `out` is `None`. + Default: "K". +Returns: + dpnp.ndarray: + an array containing the result of element-wise less-than comparison. + The data type of the returned array is determined by the Type Promotion Rules. +""" + + +def dpnp_less(x1, x2, out=None, order="K"): + """Invokes less() from dpctl.tensor implementation for less() function.""" + + # dpctl.tensor only works with usm_ndarray or scalar + x1_usm_or_scalar = dpnp.get_usm_ndarray_or_scalar(x1) + x2_usm_or_scalar = dpnp.get_usm_ndarray_or_scalar(x2) + out_usm = None if out is None else dpnp.get_usm_ndarray(out) + + func = BinaryElementwiseFunc( + "less", ti._less_result_type, ti._less, _less_docstring_ + ) + res_usm = func(x1_usm_or_scalar, x2_usm_or_scalar, out=out_usm, order=order) + return dpnp_array._create_from_usm_ndarray(res_usm) + + +_less_equal_docstring_ = """ +less_equal(x1, x2, out=None, order="K") + +Calculates the less-than or equal-to results for each element `x1_i` of +the input array `x1` the respective element `x2_i` of the input array `x2`. + +Args: + x1 (dpnp.ndarray): + First input array, expected to have numeric data type. + x2 (dpnp.ndarray): + Second input array, also 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", None, optional): + Memory layout of the newly output array, if parameter `out` is `None`. + Default: "K". +Returns: + dpnp.ndarray: + An array containing the result of element-wise less-than or equal-to comparison. + The data type of the returned array is determined by the Type Promotion Rules. +""" + + +def dpnp_less_equal(x1, x2, out=None, order="K"): + """Invokes less_equal() from dpctl.tensor implementation for less_equal() function.""" + + # dpctl.tensor only works with usm_ndarray or scalar + x1_usm_or_scalar = dpnp.get_usm_ndarray_or_scalar(x1) + x2_usm_or_scalar = dpnp.get_usm_ndarray_or_scalar(x2) + out_usm = None if out is None else dpnp.get_usm_ndarray(out) + + func = BinaryElementwiseFunc( + "less_equal", + ti._less_equal_result_type, + ti._less_equal, + _less_equal_docstring_, + ) + res_usm = func(x1_usm_or_scalar, x2_usm_or_scalar, out=out_usm, order=order) + return dpnp_array._create_from_usm_ndarray(res_usm) + + +_greater_docstring_ = """ +greater(x1, x2, out=None, order="K") + +Calculates the greater-than results for each element `x1_i` of +the input array `x1` the respective element `x2_i` of the input array `x2`. + +Args: + x1 (dpnp.ndarray): + First input array, expected to have numeric data type. + x2 (dpnp.ndarray): + Second input array, also 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", None, optional): + Memory layout of the newly output array, if parameter `out` is `None`. + Default: "K". +Returns: + dpnp.ndarray: + an array containing the result of element-wise greater-than comparison. + The data type of the returned array is determined by the Type Promotion Rules. +""" + + +def dpnp_greater(x1, x2, out=None, order="K"): + """Invokes greater() from dpctl.tensor implementation for greater() function.""" + + # dpctl.tensor only works with usm_ndarray or scalar + x1_usm_or_scalar = dpnp.get_usm_ndarray_or_scalar(x1) + x2_usm_or_scalar = dpnp.get_usm_ndarray_or_scalar(x2) + out_usm = None if out is None else dpnp.get_usm_ndarray(out) + + func = BinaryElementwiseFunc( + "greater", ti._greater_result_type, ti._greater, _greater_docstring_ + ) + res_usm = func(x1_usm_or_scalar, x2_usm_or_scalar, out=out_usm, order=order) + return dpnp_array._create_from_usm_ndarray(res_usm) + + +_greater_equal_docstring_ = """ +greater_equal(x1, x2, out=None, order="K") + +Calculates the greater-than or equal-to results for each element `x1_i` of +the input array `x1` the respective element `x2_i` of the input array `x2`. + +Args: + x1 (dpnp.ndarray): + First input array, expected to have numeric data type. + x2 (dpnp.ndarray): + Second input array, also 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", None, optional): + Memory layout of the newly output array, if parameter `out` is `None`. + Default: "K". +Returns: + dpnp.ndarray: + an array containing the result of element-wise greater-than or equal-to comparison. + The data type of the returned array is determined by the Type Promotion Rules. +""" + + +def dpnp_greater_equal(x1, x2, out=None, order="K"): + """Invokes greater_equal() from dpctl.tensor implementation for greater_equal() function.""" + + # dpctl.tensor only works with usm_ndarray or scalar + x1_usm_or_scalar = dpnp.get_usm_ndarray_or_scalar(x1) + x2_usm_or_scalar = dpnp.get_usm_ndarray_or_scalar(x2) + out_usm = None if out is None else dpnp.get_usm_ndarray(out) + + func = BinaryElementwiseFunc( + "greater_equal", + ti._greater_equal_result_type, + ti._greater_equal, + _greater_equal_docstring_, + ) + res_usm = func(x1_usm_or_scalar, x2_usm_or_scalar, out=out_usm, order=order) + return dpnp_array._create_from_usm_ndarray(res_usm) + + +_equal_docstring_ = """ + +equal(x1, x2, out=None, order="K") +Calculates equality results for each element `x1_i` of +the input array `x1` the respective element `x2_i` of the input array `x2`. + +Args: + x1 (dpnp.ndarray): + First input array, expected to have numeric data type. + x2 (dpnp.ndarray): + Second input array, also 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", None, optional): + Memory layout of the newly output array, if parameter `out` is `None`. + Default: "K". +Returns: + dpnp.ndarray: + an array containing the result of element-wise equality comparison. + The data type of the returned array is determined by the Type Promotion Rules. +""" + + +def dpnp_equal(x1, x2, out=None, order="K"): + """Invokes equal() from dpctl.tensor implementation for equal() function.""" + + # dpctl.tensor only works with usm_ndarray or scalar + x1_usm_or_scalar = dpnp.get_usm_ndarray_or_scalar(x1) + x2_usm_or_scalar = dpnp.get_usm_ndarray_or_scalar(x2) + out_usm = None if out is None else dpnp.get_usm_ndarray(out) + + func = BinaryElementwiseFunc( + "equal", ti._equal_result_type, ti._equal, _equal_docstring_ + ) + res_usm = func(x1_usm_or_scalar, x2_usm_or_scalar, 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") + +Calculates inequality results for each element `x1_i` of +the input array `x1` the respective element `x2_i` of the input array `x2`. + +Args: + x1 (dpnp.ndarray): + First input array, expected to have numeric data type. + x2 (dpnp.ndarray): + Second input array, also 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", None, optional): + Memory layout of the newly output array, if parameter `out` is `None`. + Default: "K". +Returns: + dpnp.ndarray: + an array containing the result of element-wise inequality comparison. + The data type of the returned array is determined by the Type Promotion Rules. +""" + + +def dpnp_not_equal(x1, x2, out=None, order="K"): + """Invokes not_equal() from dpctl.tensor implementation for not_equal() function.""" + + # dpctl.tensor only works with usm_ndarray or scalar + x1_usm_or_scalar = dpnp.get_usm_ndarray_or_scalar(x1) + x2_usm_or_scalar = dpnp.get_usm_ndarray_or_scalar(x2) + out_usm = None if out is None else dpnp.get_usm_ndarray(out) + + func = BinaryElementwiseFunc( + "not_equal", + ti._not_equal_result_type, + ti._not_equal, + _not_equal_docstring_, + ) + res_usm = func(x1_usm_or_scalar, x2_usm_or_scalar, out=out_usm, order=order) + return dpnp_array._create_from_usm_ndarray(res_usm) diff --git a/dpnp/dpnp_iface_logic.py b/dpnp/dpnp_iface_logic.py index 658459bd303..b6a99991895 100644 --- a/dpnp/dpnp_iface_logic.py +++ b/dpnp/dpnp_iface_logic.py @@ -46,6 +46,16 @@ from dpnp.dpnp_algo import * from dpnp.dpnp_utils import * +from .dpnp_algo.dpnp_elementwise_common import ( + dpnp_equal, + dpnp_greater, + dpnp_greater_equal, + dpnp_less, + dpnp_less_equal, + dpnp_not_equal, +) +from .dpnp_iface_mathematical import _check_nd_call + __all__ = [ "all", "allclose", @@ -223,7 +233,18 @@ def any(x1, /, axis=None, out=None, keepdims=False, *, where=True): ) -def equal(x1, x2, /, out=None, *, where=True, dtype=None, subok=True): +def equal( + x1, + x2, + /, + out=None, + *, + order="K", + where=True, + dtype=None, + subok=True, + **kwargs, +): """ Return the truth value of (x1 == x2) element-wise. @@ -240,8 +261,7 @@ def equal(x1, x2, /, out=None, *, where=True, dtype=None, subok=True): or :class:`dpctl.tensor.usm_ndarray`, but both `x1` and `x2` can not be scalars at the same time. Parameters `out`, `where`, `dtype` and `subok` are supported with their default values. Otherwise the function will be executed sequentially on CPU. - Input array data types are limited by supported DPNP :ref:`Data types`, - excluding `dpnp.complex64` and `dpnp.complex128`. + Input array data types are limited by supported DPNP :ref:`Data types`. See Also -------- @@ -256,54 +276,37 @@ def equal(x1, x2, /, out=None, *, where=True, dtype=None, subok=True): >>> import dpnp as np >>> x1 = np.array([0, 1, 3]) >>> x2 = np.arange(3) - >>> out = np.equal(x1, x2) - >>> [i for i in out] - [True, True, False] + >>> np.equal(x1, x2) + array([ True, True, False]) """ - if out is not None: - pass - elif where is not True: - pass - elif dtype is not None: - pass - elif subok is not True: - pass - elif dpnp.isscalar(x1) and dpnp.isscalar(x2): - # at least either x1 or x2 has to be an array - pass - else: - # get USM type and queue to copy scalar from the host memory into a USM allocation - usm_type, queue = ( - get_usm_allocations([x1, x2]) - if dpnp.isscalar(x1) or dpnp.isscalar(x2) - else (None, None) - ) - - x1_desc = dpnp.get_dpnp_descriptor( - x1, - copy_when_strides=False, - copy_when_nondefault_queue=False, - alloc_usm_type=usm_type, - alloc_queue=queue, - ) - x2_desc = dpnp.get_dpnp_descriptor( - x2, - copy_when_strides=False, - copy_when_nondefault_queue=False, - alloc_usm_type=usm_type, - alloc_queue=queue, - ) - if x1_desc and x2_desc: - return dpnp_equal(x1_desc, x2_desc).get_pyobj() - - return call_origin( - numpy.equal, x1, x2, out=out, where=where, dtype=dtype, subok=subok + return _check_nd_call( + numpy.equal, + dpnp_equal, + x1, + x2, + out=out, + where=where, + order=order, + dtype=dtype, + subok=subok, + **kwargs, ) -def greater(x1, x2, /, out=None, *, where=True, dtype=None, subok=True): +def greater( + x1, + x2, + /, + out=None, + *, + order="K", + where=True, + dtype=None, + subok=True, + **kwargs, +): """ Return the truth value of (x1 > x2) element-wise. @@ -320,8 +323,7 @@ def greater(x1, x2, /, out=None, *, where=True, dtype=None, subok=True): or :class:`dpctl.tensor.usm_ndarray`, but both `x1` and `x2` can not be scalars at the same time. Parameters `out`, `where`, `dtype` and `subok` are supported with their default values. Otherwise the function will be executed sequentially on CPU. - Input array data types are limited by supported DPNP :ref:`Data types`, - excluding `dpnp.complex64` and `dpnp.complex128`. + Input array data types are limited by supported DPNP :ref:`Data types`. See Also -------- @@ -336,54 +338,36 @@ def greater(x1, x2, /, out=None, *, where=True, dtype=None, subok=True): >>> import dpnp as np >>> x1 = np.array([4, 2]) >>> x2 = np.array([2, 2]) - >>> out = np.greater(x1, x2) - >>> [i for i in out] - [True, False] - + >>> np.greater(x1, x2) + array([ True, False]) """ - if out is not None: - pass - elif where is not True: - pass - elif dtype is not None: - pass - elif subok is not True: - pass - elif dpnp.isscalar(x1) and dpnp.isscalar(x2): - # at least either x1 or x2 has to be an array - pass - else: - # get USM type and queue to copy scalar from the host memory into a USM allocation - usm_type, queue = ( - get_usm_allocations([x1, x2]) - if dpnp.isscalar(x1) or dpnp.isscalar(x2) - else (None, None) - ) - - x1_desc = dpnp.get_dpnp_descriptor( - x1, - copy_when_strides=False, - copy_when_nondefault_queue=False, - alloc_usm_type=usm_type, - alloc_queue=queue, - ) - x2_desc = dpnp.get_dpnp_descriptor( - x2, - copy_when_strides=False, - copy_when_nondefault_queue=False, - alloc_usm_type=usm_type, - alloc_queue=queue, - ) - if x1_desc and x2_desc: - return dpnp_greater(x1_desc, x2_desc).get_pyobj() - - return call_origin( - numpy.greater, x1, x2, out=out, where=where, dtype=dtype, subok=subok + return _check_nd_call( + numpy.greater, + dpnp_greater, + x1, + x2, + out=out, + where=where, + order=order, + dtype=dtype, + subok=subok, + **kwargs, ) -def greater_equal(x1, x2, /, out=None, *, where=True, dtype=None, subok=True): +def greater_equal( + x1, + x2, + /, + out=None, + *, + order="K", + where=True, + dtype=None, + subok=True, + **kwargs, +): """ Return the truth value of (x1 >= x2) element-wise. @@ -400,8 +384,7 @@ def greater_equal(x1, x2, /, out=None, *, where=True, dtype=None, subok=True): or :class:`dpctl.tensor.usm_ndarray`, but both `x1` and `x2` can not be scalars at the same time. Parameters `out`, `where`, `dtype` and `subok` are supported with their default values. Otherwise the function will be executed sequentially on CPU. - Input array data types are limited by supported DPNP :ref:`Data types`, - excluding `dpnp.complex64` and `dpnp.complex128`. + Input array data types are limited by supported DPNP :ref:`Data types`. See Also -------- @@ -416,56 +399,22 @@ def greater_equal(x1, x2, /, out=None, *, where=True, dtype=None, subok=True): >>> import dpnp as np >>> x1 = np.array([4, 2, 1]) >>> x2 = np.array([2, 2, 2]) - >>> out = np.greater_equal(x1, x2) - >>> [i for i in out] - [True, True, False] + >>> np.greater_equal(x1, x2) + array([ True, True, False]) """ - if out is not None: - pass - elif where is not True: - pass - elif dtype is not None: - pass - elif subok is not True: - pass - elif dpnp.isscalar(x1) and dpnp.isscalar(x2): - # at least either x1 or x2 has to be an array - pass - else: - # get USM type and queue to copy scalar from the host memory into a USM allocation - usm_type, queue = ( - get_usm_allocations([x1, x2]) - if dpnp.isscalar(x1) or dpnp.isscalar(x2) - else (None, None) - ) - - x1_desc = dpnp.get_dpnp_descriptor( - x1, - copy_when_strides=False, - copy_when_nondefault_queue=False, - alloc_usm_type=usm_type, - alloc_queue=queue, - ) - x2_desc = dpnp.get_dpnp_descriptor( - x2, - copy_when_strides=False, - copy_when_nondefault_queue=False, - alloc_usm_type=usm_type, - alloc_queue=queue, - ) - if x1_desc and x2_desc: - return dpnp_greater_equal(x1_desc, x2_desc).get_pyobj() - - return call_origin( + return _check_nd_call( numpy.greater_equal, + dpnp_greater_equal, x1, x2, out=out, where=where, + order=order, dtype=dtype, subok=subok, + **kwargs, ) @@ -646,7 +595,18 @@ def isnan(x1, out=None, **kwargs): return call_origin(numpy.isnan, x1, out, **kwargs) -def less(x1, x2, /, out=None, *, where=True, dtype=None, subok=True): +def less( + x1, + x2, + /, + out=None, + *, + order="K", + where=True, + dtype=None, + subok=True, + **kwargs, +): """ Return the truth value of (x1 < x2) element-wise. @@ -663,8 +623,7 @@ def less(x1, x2, /, out=None, *, where=True, dtype=None, subok=True): or :class:`dpctl.tensor.usm_ndarray`, but both `x1` and `x2` can not be scalars at the same time. Parameters `out`, `where`, `dtype` and `subok` are supported with their default values. Otherwise the function will be executed sequentially on CPU. - Input array data types are limited by supported DPNP :ref:`Data types`, - excluding `dpnp.complex64` and `dpnp.complex128`. + Input array data types are limited by supported DPNP :ref:`Data types`. See Also -------- @@ -679,54 +638,37 @@ def less(x1, x2, /, out=None, *, where=True, dtype=None, subok=True): >>> import dpnp as np >>> x1 = np.array([1, 2]) >>> x2 = np.array([2, 2]) - >>> out = np.less(x1, x2) - >>> [i for i in out] - [True, False] + >>> np.less(x1, x2) + array([ True, False]) """ - if out is not None: - pass - elif where is not True: - pass - elif dtype is not None: - pass - elif subok is not True: - pass - elif dpnp.isscalar(x1) and dpnp.isscalar(x2): - # at least either x1 or x2 has to be an array - pass - else: - # get USM type and queue to copy scalar from the host memory into a USM allocation - usm_type, queue = ( - get_usm_allocations([x1, x2]) - if dpnp.isscalar(x1) or dpnp.isscalar(x2) - else (None, None) - ) - - x1_desc = dpnp.get_dpnp_descriptor( - x1, - copy_when_strides=False, - copy_when_nondefault_queue=False, - alloc_usm_type=usm_type, - alloc_queue=queue, - ) - x2_desc = dpnp.get_dpnp_descriptor( - x2, - copy_when_strides=False, - copy_when_nondefault_queue=False, - alloc_usm_type=usm_type, - alloc_queue=queue, - ) - if x1_desc and x2_desc: - return dpnp_less(x1_desc, x2_desc).get_pyobj() - - return call_origin( - numpy.less, x1, x2, out=out, where=where, dtype=dtype, subok=subok + return _check_nd_call( + numpy.less, + dpnp_less, + x1, + x2, + out=out, + where=where, + order=order, + dtype=dtype, + subok=subok, + **kwargs, ) -def less_equal(x1, x2, /, out=None, *, where=True, dtype=None, subok=True): +def less_equal( + x1, + x2, + /, + out=None, + *, + order="K", + where=True, + dtype=None, + subok=True, + **kwargs, +): """ Return the truth value of (x1 <= x2) element-wise. @@ -743,8 +685,7 @@ def less_equal(x1, x2, /, out=None, *, where=True, dtype=None, subok=True): or :class:`dpctl.tensor.usm_ndarray`, but both `x1` and `x2` can not be scalars at the same time. Parameters `out`, `where`, `dtype` and `subok` are supported with their default values. Otherwise the function will be executed sequentially on CPU. - Input array data types are limited by supported DPNP :ref:`Data types`, - excluding `dpnp.complex64` and `dpnp.complex128`. + Input array data types are limited by supported DPNP :ref:`Data types`. See Also -------- @@ -758,51 +699,23 @@ def less_equal(x1, x2, /, out=None, *, where=True, dtype=None, subok=True): -------- >>> import dpnp as np >>> x1 = np.array([4, 2, 1]) - >>> x2 = np.array([2, 2, 2]) - >>> out = np.less_equal(x1, x2) - >>> [i for i in out] - [False, True, True] + >>> x2 = np.array([2, 2, 2] + >>> np.less_equal(x1, x2) + array([False, True, True]) """ - if out is not None: - pass - elif where is not True: - pass - elif dtype is not None: - pass - elif subok is not True: - pass - elif dpnp.isscalar(x1) and dpnp.isscalar(x2): - # at least either x1 or x2 has to be an array - pass - else: - # get USM type and queue to copy scalar from the host memory into a USM allocation - usm_type, queue = ( - get_usm_allocations([x1, x2]) - if dpnp.isscalar(x1) or dpnp.isscalar(x2) - else (None, None) - ) - - x1_desc = dpnp.get_dpnp_descriptor( - x1, - copy_when_strides=False, - copy_when_nondefault_queue=False, - alloc_usm_type=usm_type, - alloc_queue=queue, - ) - x2_desc = dpnp.get_dpnp_descriptor( - x2, - copy_when_strides=False, - copy_when_nondefault_queue=False, - alloc_usm_type=usm_type, - alloc_queue=queue, - ) - if x1_desc and x2_desc: - return dpnp_less_equal(x1_desc, x2_desc).get_pyobj() - - return call_origin( - numpy.less_equal, x1, x2, out=out, where=where, dtype=dtype, subok=subok + return _check_nd_call( + numpy.less_equal, + dpnp_less_equal, + x1, + x2, + out=out, + where=where, + order=order, + dtype=dtype, + subok=subok, + **kwargs, ) @@ -1111,7 +1024,18 @@ def logical_xor(x1, x2, /, out=None, *, where=True, dtype=None, subok=True): ) -def not_equal(x1, x2, /, out=None, *, where=True, dtype=None, subok=True): +def not_equal( + x1, + x2, + /, + out=None, + *, + order="K", + where=True, + dtype=None, + subok=True, + **kwargs, +): """ Return the truth value of (x1 != x2) element-wise. @@ -1128,8 +1052,7 @@ def not_equal(x1, x2, /, out=None, *, where=True, dtype=None, subok=True): or :class:`dpctl.tensor.usm_ndarray`, but both `x1` and `x2` can not be scalars at the same time. Parameters `out`, `where`, `dtype` and `subok` are supported with their default values. Otherwise the function will be executed sequentially on CPU. - Input array data types are limited by supported DPNP :ref:`Data types`, - excluding `dpnp.complex64` and `dpnp.complex128`. + Input array data types are limited by supported DPNP :ref:`Data types`. See Also -------- @@ -1144,48 +1067,20 @@ def not_equal(x1, x2, /, out=None, *, where=True, dtype=None, subok=True): >>> import dpnp as np >>> x1 = np.array([1., 2.]) >>> x2 = np.arange(1., 3.) - >>> out = np.not_equal(x1, x2) - >>> [i for i in out] - [False, False] + >>> np.not_equal(x1, x2) + array([False, False]) """ - if out is not None: - pass - elif where is not True: - pass - elif dtype is not None: - pass - elif subok is not True: - pass - elif dpnp.isscalar(x1) and dpnp.isscalar(x2): - # at least either x1 or x2 has to be an array - pass - else: - # get USM type and queue to copy scalar from the host memory into a USM allocation - usm_type, queue = ( - get_usm_allocations([x1, x2]) - if dpnp.isscalar(x1) or dpnp.isscalar(x2) - else (None, None) - ) - - x1_desc = dpnp.get_dpnp_descriptor( - x1, - copy_when_strides=False, - copy_when_nondefault_queue=False, - alloc_usm_type=usm_type, - alloc_queue=queue, - ) - x2_desc = dpnp.get_dpnp_descriptor( - x2, - copy_when_strides=False, - copy_when_nondefault_queue=False, - alloc_usm_type=usm_type, - alloc_queue=queue, - ) - if x1_desc and x2_desc: - return dpnp_not_equal(x1_desc, x2_desc).get_pyobj() - - return call_origin( - numpy.not_equal, x1, x2, out=out, where=where, dtype=dtype, subok=subok + return _check_nd_call( + numpy.not_equal, + dpnp_not_equal, + x1, + x2, + out=out, + where=where, + order=order, + dtype=dtype, + subok=subok, + **kwargs, ) diff --git a/dpnp/random/dpnp_algo_random.pyx b/dpnp/random/dpnp_algo_random.pyx index 7c6eaae16ff..6104395a41c 100644 --- a/dpnp/random/dpnp_algo_random.pyx +++ b/dpnp/random/dpnp_algo_random.pyx @@ -458,7 +458,13 @@ cdef class MT19937(_Engine): MT19937_Delete(&self.mt19937) cdef bint is_uint_range(self, value): - return value >= 0 and value <= numpy.iinfo(numpy.uint32).max + if value < 0: + return False + + max_val = numpy.iinfo(numpy.uint32).max + if isinstance(value, dpnp_array): + max_val = dpnp.array(max_val, dtype=dpnp.uint32) + return value <= max_val cdef class MCG59(_Engine): @@ -489,7 +495,13 @@ cdef class MCG59(_Engine): MCG59_Delete(&self.mcg59) cdef bint is_uint64_range(self, value): - return value >= 0 and value <= numpy.iinfo(numpy.uint64).max + if value < 0: + return False + + max_val = numpy.iinfo(numpy.uint64).max + if isinstance(value, dpnp_array): + max_val = dpnp.array(max_val, dtype=dpnp.uint64) + return value <= max_val cpdef utils.dpnp_descriptor dpnp_rng_beta(double a, double b, size): From ded54a9d2218778f393cdf9f68805c380c493f61 Mon Sep 17 00:00:00 2001 From: Natalia Polina Date: Thu, 29 Jun 2023 10:41:25 -0500 Subject: [PATCH 2/3] Fixed remarks for comparison functions. --- dpnp/dpnp_algo/dpnp_elementwise_common.py | 208 +++++++++++----------- dpnp/dpnp_iface_logic.py | 12 +- dpnp/random/dpnp_algo_random.pyx | 4 +- 3 files changed, 112 insertions(+), 112 deletions(-) diff --git a/dpnp/dpnp_algo/dpnp_elementwise_common.py b/dpnp/dpnp_algo/dpnp_elementwise_common.py index 17059a26082..61341c87090 100644 --- a/dpnp/dpnp_algo/dpnp_elementwise_common.py +++ b/dpnp/dpnp_algo/dpnp_elementwise_common.py @@ -173,11 +173,11 @@ def _call_divide_inplace(lhs, rhs, sycl_queue, depends=None): return dpnp_array._create_from_usm_ndarray(res_usm) -_multiply_docstring_ = """ -multiply(x1, x2, out=None, order="K") +_equal_docstring_ = """ -Calculates the product for each element `x1_i` of the input array `x1` -with the respective element `x2_i` of the input array `x2`. +equal(x1, x2, out=None, order="K") +Calculates equality results for each element `x1_i` of +the input array `x1` the respective element `x2_i` of the input array `x2`. Args: x1 (dpnp.ndarray): @@ -192,19 +192,13 @@ def _call_divide_inplace(lhs, rhs, sycl_queue, depends=None): Default: "K". Returns: dpnp.ndarray: - an array containing the result of element-wise division. The data type - of the returned array is determined by the Type Promotion Rules. + an array containing the result of element-wise equality comparison. + The data type of the returned array is determined by the Type Promotion Rules. """ -def dpnp_multiply(x1, x2, out=None, order="K"): - """ - Invokes multiply() from dpctl.tensor implementation for multiply() function. - - TODO: add a pybind11 extension of mul() from OneMKL VM where possible - and would be performance effective. - - """ +def dpnp_equal(x1, x2, out=None, order="K"): + """Invokes equal() from dpctl.tensor implementation for equal() function.""" # dpctl.tensor only works with usm_ndarray or scalar x1_usm_or_scalar = dpnp.get_usm_ndarray_or_scalar(x1) @@ -212,21 +206,17 @@ def dpnp_multiply(x1, x2, out=None, order="K"): out_usm = None if out is None else dpnp.get_usm_ndarray(out) func = BinaryElementwiseFunc( - "multiply", - ti._multiply_result_type, - ti._multiply, - _multiply_docstring_, - ti._multiply_inplace, + "equal", ti._equal_result_type, ti._equal, _equal_docstring_ ) res_usm = func(x1_usm_or_scalar, x2_usm_or_scalar, out=out_usm, order=order) return dpnp_array._create_from_usm_ndarray(res_usm) -_subtract_docstring_ = """ -subtract(x1, x2, out=None, order="K") +_greater_docstring_ = """ +greater(x1, x2, out=None, order="K") -Calculates the difference bewteen each element `x1_i` of the input -array `x1` and the respective element `x2_i` of the input array `x2`. +Calculates the greater-than results for each element `x1_i` of +the input array `x1` the respective element `x2_i` of the input array `x2`. Args: x1 (dpnp.ndarray): @@ -241,30 +231,13 @@ def dpnp_multiply(x1, x2, out=None, order="K"): Default: "K". Returns: dpnp.ndarray: - an array containing the result of element-wise division. The data type - of the returned array is determined by the Type Promotion Rules. + an array containing the result of element-wise greater-than comparison. + The data type of the returned array is determined by the Type Promotion Rules. """ -def dpnp_subtract(x1, x2, out=None, order="K"): - """ - Invokes subtract() from dpctl.tensor implementation for subtract() function. - - TODO: add a pybind11 extension of sub() from OneMKL VM where possible - and would be performance effective. - - """ - - # TODO: discuss with dpctl if the check is needed to be moved there - if ( - not dpnp.isscalar(x1) - and not dpnp.isscalar(x2) - and x1.dtype == x2.dtype == dpnp.bool - ): - raise TypeError( - "DPNP boolean subtract, the `-` operator, is not supported, " - "use the bitwise_xor, the `^` operator, or the logical_xor function instead." - ) +def dpnp_greater(x1, x2, out=None, order="K"): + """Invokes greater() from dpctl.tensor implementation for greater() function.""" # dpctl.tensor only works with usm_ndarray or scalar x1_usm_or_scalar = dpnp.get_usm_ndarray_or_scalar(x1) @@ -272,20 +245,16 @@ def dpnp_subtract(x1, x2, out=None, order="K"): out_usm = None if out is None else dpnp.get_usm_ndarray(out) func = BinaryElementwiseFunc( - "subtract", - ti._subtract_result_type, - ti._subtract, - _subtract_docstring_, - ti._subtract_inplace, + "greater", ti._greater_result_type, ti._greater, _greater_docstring_ ) res_usm = func(x1_usm_or_scalar, x2_usm_or_scalar, out=out_usm, order=order) return dpnp_array._create_from_usm_ndarray(res_usm) -_less_docstring_ = """ -less(x1, x2, out=None, order="K") +_greater_equal_docstring_ = """ +greater_equal(x1, x2, out=None, order="K") -Calculates the less-than results for each element `x1_i` of +Calculates the greater-than or equal-to results for each element `x1_i` of the input array `x1` the respective element `x2_i` of the input array `x2`. Args: @@ -301,13 +270,13 @@ def dpnp_subtract(x1, x2, out=None, order="K"): Default: "K". Returns: dpnp.ndarray: - an array containing the result of element-wise less-than comparison. + an array containing the result of element-wise greater-than or equal-to comparison. The data type of the returned array is determined by the Type Promotion Rules. """ -def dpnp_less(x1, x2, out=None, order="K"): - """Invokes less() from dpctl.tensor implementation for less() function.""" +def dpnp_greater_equal(x1, x2, out=None, order="K"): + """Invokes greater_equal() from dpctl.tensor implementation for greater_equal() function.""" # dpctl.tensor only works with usm_ndarray or scalar x1_usm_or_scalar = dpnp.get_usm_ndarray_or_scalar(x1) @@ -315,16 +284,19 @@ def dpnp_less(x1, x2, out=None, order="K"): out_usm = None if out is None else dpnp.get_usm_ndarray(out) func = BinaryElementwiseFunc( - "less", ti._less_result_type, ti._less, _less_docstring_ + "greater_equal", + ti._greater_equal_result_type, + ti._greater_equal, + _greater_equal_docstring_, ) res_usm = func(x1_usm_or_scalar, x2_usm_or_scalar, out=out_usm, order=order) return dpnp_array._create_from_usm_ndarray(res_usm) -_less_equal_docstring_ = """ -less_equal(x1, x2, out=None, order="K") +_less_docstring_ = """ +less(x1, x2, out=None, order="K") -Calculates the less-than or equal-to results for each element `x1_i` of +Calculates the less-than results for each element `x1_i` of the input array `x1` the respective element `x2_i` of the input array `x2`. Args: @@ -340,13 +312,13 @@ def dpnp_less(x1, x2, out=None, order="K"): Default: "K". Returns: dpnp.ndarray: - An array containing the result of element-wise less-than or equal-to comparison. + an array containing the result of element-wise less-than comparison. The data type of the returned array is determined by the Type Promotion Rules. """ -def dpnp_less_equal(x1, x2, out=None, order="K"): - """Invokes less_equal() from dpctl.tensor implementation for less_equal() function.""" +def dpnp_less(x1, x2, out=None, order="K"): + """Invokes less() from dpctl.tensor implementation for less() function.""" # dpctl.tensor only works with usm_ndarray or scalar x1_usm_or_scalar = dpnp.get_usm_ndarray_or_scalar(x1) @@ -354,19 +326,16 @@ def dpnp_less_equal(x1, x2, out=None, order="K"): out_usm = None if out is None else dpnp.get_usm_ndarray(out) func = BinaryElementwiseFunc( - "less_equal", - ti._less_equal_result_type, - ti._less_equal, - _less_equal_docstring_, + "less", ti._less_result_type, ti._less, _less_docstring_ ) res_usm = func(x1_usm_or_scalar, x2_usm_or_scalar, out=out_usm, order=order) return dpnp_array._create_from_usm_ndarray(res_usm) -_greater_docstring_ = """ -greater(x1, x2, out=None, order="K") +_less_equal_docstring_ = """ +less_equal(x1, x2, out=None, order="K") -Calculates the greater-than results for each element `x1_i` of +Calculates the less-than or equal-to results for each element `x1_i` of the input array `x1` the respective element `x2_i` of the input array `x2`. Args: @@ -382,13 +351,13 @@ def dpnp_less_equal(x1, x2, out=None, order="K"): Default: "K". Returns: dpnp.ndarray: - an array containing the result of element-wise greater-than comparison. + An array containing the result of element-wise less-than or equal-to comparison. The data type of the returned array is determined by the Type Promotion Rules. """ -def dpnp_greater(x1, x2, out=None, order="K"): - """Invokes greater() from dpctl.tensor implementation for greater() function.""" +def dpnp_less_equal(x1, x2, out=None, order="K"): + """Invokes less_equal() from dpctl.tensor implementation for less_equal() function.""" # dpctl.tensor only works with usm_ndarray or scalar x1_usm_or_scalar = dpnp.get_usm_ndarray_or_scalar(x1) @@ -396,17 +365,20 @@ def dpnp_greater(x1, x2, out=None, order="K"): out_usm = None if out is None else dpnp.get_usm_ndarray(out) func = BinaryElementwiseFunc( - "greater", ti._greater_result_type, ti._greater, _greater_docstring_ + "less_equal", + ti._less_equal_result_type, + ti._less_equal, + _less_equal_docstring_, ) res_usm = func(x1_usm_or_scalar, x2_usm_or_scalar, out=out_usm, order=order) return dpnp_array._create_from_usm_ndarray(res_usm) -_greater_equal_docstring_ = """ -greater_equal(x1, x2, out=None, order="K") +_multiply_docstring_ = """ +multiply(x1, x2, out=None, order="K") -Calculates the greater-than or equal-to results for each element `x1_i` of -the input array `x1` the respective element `x2_i` of the input array `x2`. +Calculates the product for each element `x1_i` of the input array `x1` +with the respective element `x2_i` of the input array `x2`. Args: x1 (dpnp.ndarray): @@ -421,13 +393,19 @@ def dpnp_greater(x1, x2, out=None, order="K"): Default: "K". Returns: dpnp.ndarray: - an array containing the result of element-wise greater-than or equal-to comparison. - The data type of the returned array is determined by the Type Promotion Rules. + an array containing the result of element-wise division. The data type + of the returned array is determined by the Type Promotion Rules. """ -def dpnp_greater_equal(x1, x2, out=None, order="K"): - """Invokes greater_equal() from dpctl.tensor implementation for greater_equal() function.""" +def dpnp_multiply(x1, x2, out=None, order="K"): + """ + Invokes multiply() from dpctl.tensor implementation for multiply() function. + + TODO: add a pybind11 extension of mul() from OneMKL VM where possible + and would be performance effective. + + """ # dpctl.tensor only works with usm_ndarray or scalar x1_usm_or_scalar = dpnp.get_usm_ndarray_or_scalar(x1) @@ -435,19 +413,20 @@ def dpnp_greater_equal(x1, x2, out=None, order="K"): out_usm = None if out is None else dpnp.get_usm_ndarray(out) func = BinaryElementwiseFunc( - "greater_equal", - ti._greater_equal_result_type, - ti._greater_equal, - _greater_equal_docstring_, + "multiply", + ti._multiply_result_type, + ti._multiply, + _multiply_docstring_, + ti._multiply_inplace, ) res_usm = func(x1_usm_or_scalar, x2_usm_or_scalar, out=out_usm, order=order) return dpnp_array._create_from_usm_ndarray(res_usm) -_equal_docstring_ = """ +_not_equal_docstring_ = """ +not_equal(x1, x2, out=None, order="K") -equal(x1, x2, out=None, order="K") -Calculates equality results for each element `x1_i` of +Calculates inequality results for each element `x1_i` of the input array `x1` the respective element `x2_i` of the input array `x2`. Args: @@ -463,13 +442,13 @@ def dpnp_greater_equal(x1, x2, out=None, order="K"): Default: "K". Returns: dpnp.ndarray: - an array containing the result of element-wise equality comparison. + an array containing the result of element-wise inequality comparison. The data type of the returned array is determined by the Type Promotion Rules. """ -def dpnp_equal(x1, x2, out=None, order="K"): - """Invokes equal() from dpctl.tensor implementation for equal() function.""" +def dpnp_not_equal(x1, x2, out=None, order="K"): + """Invokes not_equal() from dpctl.tensor implementation for not_equal() function.""" # dpctl.tensor only works with usm_ndarray or scalar x1_usm_or_scalar = dpnp.get_usm_ndarray_or_scalar(x1) @@ -477,17 +456,20 @@ def dpnp_equal(x1, x2, out=None, order="K"): out_usm = None if out is None else dpnp.get_usm_ndarray(out) func = BinaryElementwiseFunc( - "equal", ti._equal_result_type, ti._equal, _equal_docstring_ + "not_equal", + ti._not_equal_result_type, + ti._not_equal, + _not_equal_docstring_, ) res_usm = func(x1_usm_or_scalar, x2_usm_or_scalar, 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") +_subtract_docstring_ = """ +subtract(x1, x2, out=None, order="K") -Calculates inequality results for each element `x1_i` of -the input array `x1` the respective element `x2_i` of the input array `x2`. +Calculates the difference bewteen each element `x1_i` of the input +array `x1` and the respective element `x2_i` of the input array `x2`. Args: x1 (dpnp.ndarray): @@ -502,13 +484,30 @@ def dpnp_equal(x1, x2, out=None, order="K"): Default: "K". Returns: dpnp.ndarray: - an array containing the result of element-wise inequality comparison. - The data type of the returned array is determined by the Type Promotion Rules. + an array containing the result of element-wise division. The data type + of the returned array is determined by the Type Promotion Rules. """ -def dpnp_not_equal(x1, x2, out=None, order="K"): - """Invokes not_equal() from dpctl.tensor implementation for not_equal() function.""" +def dpnp_subtract(x1, x2, out=None, order="K"): + """ + Invokes subtract() from dpctl.tensor implementation for subtract() function. + + TODO: add a pybind11 extension of sub() from OneMKL VM where possible + and would be performance effective. + + """ + + # TODO: discuss with dpctl if the check is needed to be moved there + if ( + not dpnp.isscalar(x1) + and not dpnp.isscalar(x2) + and x1.dtype == x2.dtype == dpnp.bool + ): + raise TypeError( + "DPNP boolean subtract, the `-` operator, is not supported, " + "use the bitwise_xor, the `^` operator, or the logical_xor function instead." + ) # dpctl.tensor only works with usm_ndarray or scalar x1_usm_or_scalar = dpnp.get_usm_ndarray_or_scalar(x1) @@ -516,10 +515,11 @@ def dpnp_not_equal(x1, x2, out=None, order="K"): out_usm = None if out is None else dpnp.get_usm_ndarray(out) func = BinaryElementwiseFunc( - "not_equal", - ti._not_equal_result_type, - ti._not_equal, - _not_equal_docstring_, + "subtract", + ti._subtract_result_type, + ti._subtract, + _subtract_docstring_, + ti._subtract_inplace, ) res_usm = func(x1_usm_or_scalar, x2_usm_or_scalar, out=out_usm, order=order) return dpnp_array._create_from_usm_ndarray(res_usm) diff --git a/dpnp/dpnp_iface_logic.py b/dpnp/dpnp_iface_logic.py index b6a99991895..45c521596c2 100644 --- a/dpnp/dpnp_iface_logic.py +++ b/dpnp/dpnp_iface_logic.py @@ -259,7 +259,7 @@ def equal( ----------- Parameters `x1` and `x2` are supported as either scalar, :class:`dpnp.ndarray` or :class:`dpctl.tensor.usm_ndarray`, but both `x1` and `x2` can not be scalars at the same time. - Parameters `out`, `where`, `dtype` and `subok` are supported with their default values. + Parameters `where`, `dtype` and `subok` are supported with their default values. Otherwise the function will be executed sequentially on CPU. Input array data types are limited by supported DPNP :ref:`Data types`. @@ -321,7 +321,7 @@ def greater( ----------- Parameters `x1` and `x2` are supported as either scalar, :class:`dpnp.ndarray` or :class:`dpctl.tensor.usm_ndarray`, but both `x1` and `x2` can not be scalars at the same time. - Parameters `out`, `where`, `dtype` and `subok` are supported with their default values. + Parameters `where`, `dtype` and `subok` are supported with their default values. Otherwise the function will be executed sequentially on CPU. Input array data types are limited by supported DPNP :ref:`Data types`. @@ -382,7 +382,7 @@ def greater_equal( ----------- Parameters `x1` and `x2` are supported as either scalar, :class:`dpnp.ndarray` or :class:`dpctl.tensor.usm_ndarray`, but both `x1` and `x2` can not be scalars at the same time. - Parameters `out`, `where`, `dtype` and `subok` are supported with their default values. + Parameters `where`, `dtype` and `subok` are supported with their default values. Otherwise the function will be executed sequentially on CPU. Input array data types are limited by supported DPNP :ref:`Data types`. @@ -621,7 +621,7 @@ def less( ----------- Parameters `x1` and `x2` are supported as either scalar, :class:`dpnp.ndarray` or :class:`dpctl.tensor.usm_ndarray`, but both `x1` and `x2` can not be scalars at the same time. - Parameters `out`, `where`, `dtype` and `subok` are supported with their default values. + Parameters `where`, `dtype` and `subok` are supported with their default values. Otherwise the function will be executed sequentially on CPU. Input array data types are limited by supported DPNP :ref:`Data types`. @@ -683,7 +683,7 @@ def less_equal( ----------- Parameters `x1` and `x2` are supported as either scalar, :class:`dpnp.ndarray` or :class:`dpctl.tensor.usm_ndarray`, but both `x1` and `x2` can not be scalars at the same time. - Parameters `out`, `where`, `dtype` and `subok` are supported with their default values. + Parameters `where`, `dtype` and `subok` are supported with their default values. Otherwise the function will be executed sequentially on CPU. Input array data types are limited by supported DPNP :ref:`Data types`. @@ -1050,7 +1050,7 @@ def not_equal( ----------- Parameters `x1` and `x2` are supported as either scalar, :class:`dpnp.ndarray` or :class:`dpctl.tensor.usm_ndarray`, but both `x1` and `x2` can not be scalars at the same time. - Parameters `out`, `where`, `dtype` and `subok` are supported with their default values. + Parameters `where`, `dtype` and `subok` are supported with their default values. Otherwise the function will be executed sequentially on CPU. Input array data types are limited by supported DPNP :ref:`Data types`. diff --git a/dpnp/random/dpnp_algo_random.pyx b/dpnp/random/dpnp_algo_random.pyx index 6104395a41c..b46b4827f7e 100644 --- a/dpnp/random/dpnp_algo_random.pyx +++ b/dpnp/random/dpnp_algo_random.pyx @@ -463,7 +463,7 @@ cdef class MT19937(_Engine): max_val = numpy.iinfo(numpy.uint32).max if isinstance(value, dpnp_array): - max_val = dpnp.array(max_val, dtype=dpnp.uint32) + max_val = dpnp.array(max_val, dtype=numpy.uint32) return value <= max_val @@ -500,7 +500,7 @@ cdef class MCG59(_Engine): max_val = numpy.iinfo(numpy.uint64).max if isinstance(value, dpnp_array): - max_val = dpnp.array(max_val, dtype=dpnp.uint64) + max_val = dpnp.array(max_val, dtype=numpy.uint64) return value <= max_val From df3e44f32f801a7592c033554b2433e6b2ef1bb9 Mon Sep 17 00:00:00 2001 From: Natalia Polina Date: Thu, 29 Jun 2023 20:10:00 -0500 Subject: [PATCH 3/3] Skip part of test_bounds_fallback tests on Windows. --- tests/test_random_state.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/test_random_state.py b/tests/test_random_state.py index 5b3c937ac18..f6be26202fb 100644 --- a/tests/test_random_state.py +++ b/tests/test_random_state.py @@ -12,6 +12,7 @@ ) import dpnp +from dpnp.dpnp_array import dpnp_array from dpnp.random import RandomState from .helper import is_cpu_device @@ -547,6 +548,9 @@ def test_zero_size(self, zero_size): ids=["[2]", "dpnp.array([2])", "numpy.array([2])"], ) def test_bounds_fallback(self, low, high): + if isinstance(high, dpnp_array) and high.dtype == numpy.int32: + pytest.skip("NumPy fails: 'high' is out of bounds for int32") + seed = 15 size = (3, 2, 5)