diff --git a/dpnp/dpnp_algo/dpnp_algo.pyx b/dpnp/dpnp_algo/dpnp_algo.pyx index 9fd17b6c91e6..60bbd2149d3b 100644 --- a/dpnp/dpnp_algo/dpnp_algo.pyx +++ b/dpnp/dpnp_algo/dpnp_algo.pyx @@ -219,7 +219,7 @@ cpdef dpnp_queue_initialize(): # TODO: # choose seed number as is in numpy seed_from_time = time(NULL) - dpnp_rng_srand_c(seed_from_time) + dpnp_rng_srand_c(< size_t > seed_from_time) """ diff --git a/dpnp/dpnp_iface_bitwise.py b/dpnp/dpnp_iface_bitwise.py index eded1984809b..bac53b2cbc6a 100644 --- a/dpnp/dpnp_iface_bitwise.py +++ b/dpnp/dpnp_iface_bitwise.py @@ -90,7 +90,7 @@ def bitwise_and( 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 `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. Data type of input arrays `x1` and `x2` has to be an integer or boolean data type. @@ -160,7 +160,7 @@ def bitwise_or( 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 `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. Data type of input arrays `x1` and `x2` has to be an integer or boolean data type. @@ -225,7 +225,7 @@ def bitwise_xor( 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 `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. Data type of input arrays `x1` and `x2` has to be an integer or boolean data type. @@ -286,7 +286,7 @@ def invert( Parameter `x` is 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. Data type of input array `x` has to be an integer data type. @@ -358,7 +358,7 @@ def left_shift( 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 `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 data is supported as integer only. @@ -421,7 +421,7 @@ def right_shift( 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 `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 data is supported as integer only. diff --git a/dpnp/dpnp_iface_mathematical.py b/dpnp/dpnp_iface_mathematical.py index eafb90e292d3..e51ef47f89ee 100644 --- a/dpnp/dpnp_iface_mathematical.py +++ b/dpnp/dpnp_iface_mathematical.py @@ -157,7 +157,7 @@ def absolute(x, /, out=None, *, where=True, dtype=None, subok=True, **kwargs): ----------- Parameters `x` is only supported as either :class:`dpnp.ndarray` or :class:`dpctl.tensor.usm_ndarray`. Parameters `out`, `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`. @@ -232,7 +232,7 @@ def add( 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 `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`. @@ -334,7 +334,7 @@ def ceil( ----------- 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 real-value data types. @@ -442,58 +442,96 @@ def convolve(a, v, mode="full"): return call_origin(numpy.convolve, a=a, v=v, mode=mode) -def copysign(x1, x2, dtype=None, out=None, where=True, **kwargs): +def copysign( + x1, x2, /, out=None, *, where=True, dtype=None, subok=True, **kwargs +): """ - Change the sign of x1 to that of x2, element-wise. + Change the sign of `x1` to that of `x2`, element-wise. For full documentation refer to :obj:`numpy.copysign`. + Returns + ------- + out : dpnp.ndarray + The values of `x1` with the sign of `x2`. + Limitations ----------- - Parameters `x1` and `x2` are supported as either :class:`dpnp.ndarray` or scalar. - Parameters `dtype`, `out` and `where` are supported with their default values. - Keyword arguments `kwargs` are currently unsupported. + 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 `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.copysign(np.array([1, -2, 6, -9]), np.array([-1, -1, 1, 1])) - >>> [x for x in result] - [-1.0, -2.0, 6.0, 9.0] + >>> np.copysign(np.array(1.3), np.array(-1)) + array(-1.3) + >>> 1 / np.copysign(np.array(0), 1) + array(inf) + >>> 1 / np.copysign(np.array(0), -1) + array(-inf) + + >>> x = np.array([-1, 0, 1]) + >>> np.copysign(x, -1.1) + array([-1., -0., -1.]) + >>> np.copysign(x, np.arange(3) - 1) + array([-1., 0., 1.]) """ - x1_is_scalar = dpnp.isscalar(x1) - x2_is_scalar = dpnp.isscalar(x2) - x1_desc = dpnp.get_dpnp_descriptor( - x1, copy_when_strides=False, copy_when_nondefault_queue=False - ) - x2_desc = dpnp.get_dpnp_descriptor( - x2, copy_when_strides=False, copy_when_nondefault_queue=False - ) + if kwargs: + 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: + if out is not None: + if not dpnp.is_supported_array_type(out): + raise TypeError( + "return array must be of supported array type" + ) + out_desc = ( + dpnp.get_dpnp_descriptor( + out, copy_when_nondefault_queue=False + ) + or None + ) + else: + out_desc = None - if x1_desc and x2_desc and not kwargs: - if not x1_desc and not x1_is_scalar: - pass - elif not x2_desc and not x2_is_scalar: - pass - elif x1_is_scalar and x2_is_scalar: - pass - elif x1_desc and x1_desc.ndim == 0: - pass - elif x2_desc and x2_desc.ndim == 0: - pass - elif dtype is not None: - pass - elif out is not None: - pass - elif not where: - pass - else: return dpnp_copysign( - x1_desc, x2_desc, dtype=dtype, out=out, where=where + x1_desc, x2_desc, dtype=dtype, out=out_desc, where=where ).get_pyobj() return call_origin( @@ -510,7 +548,7 @@ def cross(x1, x2, axisa=-1, axisb=-1, axisc=-1, axis=None): Limitations ----------- Parameters `x1` and `x2` are supported as :class:`dpnp.ndarray`. - Keyword arguments `kwargs` are currently unsupported. + Keyword argument `kwargs` is currently unsupported. Sizes of input arrays are limited by `x1.size == 3 and x2.size == 3`. Shapes of input arrays are limited by `x1.shape == (3,) and x2.shape == (3,)`. Otherwise the function will be executed sequentially on CPU. @@ -558,7 +596,7 @@ def cumprod(x1, **kwargs): Limitations ----------- Parameter `x` is supported as :class:`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`. @@ -592,7 +630,7 @@ def cumsum(x1, **kwargs): Limitations ----------- Parameter `x` 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`. @@ -773,7 +811,7 @@ def fabs(x1, **kwargs): Limitations ----------- Parameter `x1` is supported as :class:`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`. @@ -824,7 +862,7 @@ def floor( ----------- 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 real-value data types. @@ -887,7 +925,7 @@ def floor_divide( 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 `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`. @@ -972,17 +1010,23 @@ def fmin(*args, **kwargs): return dpnp.minimum(*args, **kwargs) -def fmod(x1, x2, dtype=None, out=None, where=True, **kwargs): +def fmod(x1, x2, /, out=None, *, where=True, dtype=None, subok=True, **kwargs): """ - Calculate the element-wise remainder of division. + Returns the element-wise remainder of division. For full documentation refer to :obj:`numpy.fmod`. + Returns + ------- + out : dpnp.ndarray + The remainder of the division of `x1` by `x2`. + Limitations ----------- - Parameters `x1` and `x2` are supported as either :class:`dpnp.ndarray` or scalar. - Parameters `dtype`, `out` and `where` are supported with their default values. - Keyword arguments `kwargs` are currently unsupported. + 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 `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`. @@ -994,48 +1038,80 @@ def fmod(x1, x2, dtype=None, out=None, where=True, **kwargs): Examples -------- >>> import dpnp as np - >>> a = np.array([2, -3, 4, 5, -4.5]) - >>> b = np.array([2, 2, 2, 2, 2]) - >>> result = np.fmod(a, b) - >>> [x for x in result] - [0.0, -1.0, 0.0, 1.0, -0.5] + >>> a = np.array([-3, -2, -1, 1, 2, 3]) + >>> np.fmod(a, 2) + array([-1, 0, -1, 1, 0, 1]) + >>> np.remainder(a, 2) + array([1, 0, 1, 1, 0, 1]) + + >>> a = np.array([5, 3]) + >>> b = np.array([2, 2.]) + >>> np.fmod(a, b) + array([1., 1.]) + + >>> a = np.arange(-3, 3).reshape(3, 2) + >>> a + array([[-3, -2], + [-1, 0], + [ 1, 2]]) + >>> b = np.array([2, 2]) + >>> np.fmod(a, b) + array([[-1, 0], + [-1, 0], + [ 1, 0]]) """ - x1_is_scalar = dpnp.isscalar(x1) - x2_is_scalar = dpnp.isscalar(x2) - x1_desc = dpnp.get_dpnp_descriptor( - x1, copy_when_strides=False, copy_when_nondefault_queue=False - ) - x2_desc = dpnp.get_dpnp_descriptor( - x2, copy_when_strides=False, copy_when_nondefault_queue=False - ) + if kwargs: + 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: + if out is not None: + if not dpnp.is_supported_array_type(out): + raise TypeError( + "return array must be of supported array type" + ) + out_desc = ( + dpnp.get_dpnp_descriptor( + out, copy_when_nondefault_queue=False + ) + or None + ) + else: + out_desc = None - if x1_desc and x2_desc and not kwargs: - if not x1_desc and not x1_is_scalar: - pass - elif not x2_desc and not x2_is_scalar: - pass - elif x1_is_scalar and x2_is_scalar: - pass - elif x1_desc and x1_desc.ndim == 0: - pass - elif x2_desc and x2_desc.ndim == 0: - pass - elif dtype is not None: - pass - elif out is not None: - pass - elif not where: - pass - else: - out_desc = ( - dpnp.get_dpnp_descriptor(out, copy_when_nondefault_queue=False) - if out is not None - else None - ) return dpnp_fmod( - x1_desc, x2_desc, dtype, out_desc, where + x1_desc, x2_desc, dtype=dtype, out=out_desc, where=where ).get_pyobj() return call_origin( @@ -1053,7 +1129,7 @@ def gradient(x1, *varargs, **kwargs): ----------- Parameter `y1` is supported as :class:`dpnp.ndarray`. Argument `varargs[0]` is supported as `int`. - 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`. @@ -1085,64 +1161,112 @@ def gradient(x1, *varargs, **kwargs): return call_origin(numpy.gradient, x1, *varargs, **kwargs) -def maximum(x1, x2, dtype=None, out=None, where=True, **kwargs): +def maximum( + x1, x2, /, out=None, *, where=True, dtype=None, subok=True, **kwargs +): """ Element-wise maximum of array elements. For full documentation refer to :obj:`numpy.maximum`. + Returns + ------- + out : dpnp.ndarray + The maximum of `x1` and `x2`, element-wise. + Limitations ----------- - Parameters `x1` and `x2` are supported as either :class:`dpnp.ndarray` or scalar. - Parameters `dtype`, `out` and `where` are supported with their default values. - Keyword arguments `kwargs` are currently unsupported. + 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 `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`. See Also -------- - :obj:`dpnp.fmax` : Element-wise maximum of array elements. - :obj:`dpnp.fmin` : Element-wise minimum of array elements. - :obj:`dpnp.fmod` : Calculate the element-wise remainder of division. + :obj:`dpnp.minimum` : Element-wise minimum of two arrays, propagates NaNs. + :obj:`dpnp.fmax` : Element-wise maximum of two arrays, ignores NaNs. + :obj:`dpnp.amax` : The maximum value of an array along a given axis, propagates NaNs. + :obj:`dpnp.nanmax` : The maximum value of an array along a given axis, ignores NaNs. + :obj:`dpnp.fmin` : Element-wise minimum of two arrays, ignores NaNs. + :obj:`dpnp.amix` : The minimum value of an array along a given axis, propagates NaNs. + :obj:`dpnp.nanmix` : The minimum value of an array along a given axis, ignores NaNs. Example ------- >>> import dpnp as np - >>> result = np.fmax(np.array([-2, 3, 4]), np.array([1, 5, 2])) - >>> [x for x in result] - [1, 5, 4] + >>> x1 = np.array([2, 3, 4]) + >>> x2 = np.array([1, 5, 2]) + >>> np.maximum(x1, x2) + array([2, 5, 4]) + + >>> x1 = np.eye(2) + >>> x2 = np.array([0.5, 2]) + >>> np.maximum(x1, x2) # broadcasting + array([[1. , 2. ], + [0.5, 2. ]]) + + >>> x1 = np.array([np.nan, 0, np.nan]) + >>> x2 = np.array([0, np.nan, np.nan]) + >>> np.maximum(x1, x2) + array([ 0., 0., nan]) + + >>> np.maximum(np.array(np.Inf), 1) + array(inf) """ - x1_is_scalar = dpnp.isscalar(x1) - x2_is_scalar = dpnp.isscalar(x2) - x1_desc = dpnp.get_dpnp_descriptor( - x1, copy_when_strides=False, copy_when_nondefault_queue=False - ) - x2_desc = dpnp.get_dpnp_descriptor( - x2, copy_when_strides=False, copy_when_nondefault_queue=False - ) + if kwargs: + 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: + if out is not None: + if not dpnp.is_supported_array_type(out): + raise TypeError( + "return array must be of supported array type" + ) + out_desc = ( + dpnp.get_dpnp_descriptor( + out, copy_when_nondefault_queue=False + ) + or None + ) + else: + out_desc = None - if x1_desc and x2_desc and not kwargs: - if not x1_desc and not x1_is_scalar: - pass - elif not x2_desc and not x2_is_scalar: - pass - elif x1_is_scalar and x2_is_scalar: - pass - elif x1_desc and x1_desc.ndim == 0: - pass - elif x2_desc and x2_desc.ndim == 0: - pass - elif dtype is not None: - pass - elif out is not None: - pass - elif not where: - pass - else: return dpnp_maximum( - x1_desc, x2_desc, dtype=dtype, out=out, where=where + x1_desc, x2_desc, dtype=dtype, out=out_desc, where=where ).get_pyobj() return call_origin( @@ -1150,64 +1274,112 @@ def maximum(x1, x2, dtype=None, out=None, where=True, **kwargs): ) -def minimum(x1, x2, dtype=None, out=None, where=True, **kwargs): +def minimum( + x1, x2, /, out=None, *, where=True, dtype=None, subok=True, **kwargs +): """ Element-wise minimum of array elements. For full documentation refer to :obj:`numpy.minimum`. + Returns + ------- + out : dpnp.ndarray + The minimum of `x1` and `x2`, element-wise. + Limitations ----------- - Parameters `x1` and `x2` are supported as either :class:`dpnp.ndarray` or scalar. - Parameters `dtype`, `out` and `where` are supported with their default values. - Keyword arguments `kwargs` are currently unsupported. + 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 `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`. See Also -------- - :obj:`dpnp.fmax` : Element-wise maximum of array elements. - :obj:`dpnp.fmin` : Element-wise minimum of array elements. - :obj:`dpnp.fmod` : Calculate the element-wise remainder of division. + :obj:`dpnp.maximum` : Element-wise maximum of two arrays, propagates NaNs. + :obj:`dpnp.fmin` : Element-wise minimum of two arrays, ignores NaNs. + :obj:`dpnp.amin` : The minimum value of an array along a given axis, propagates NaNs. + :obj:`dpnp.nanmin` : The minimum value of an array along a given axis, ignores NaNs. + :obj:`dpnp.fmax` : Element-wise maximum of two arrays, ignores NaNs. + :obj:`dpnp.amax` : The maximum value of an array along a given axis, propagates NaNs. + :obj:`dpnp.nanmax` : The maximum value of an array along a given axis, ignores NaNs. Example ------- >>> import dpnp as np - >>> result = np.fmin(np.array([-2, 3, 4]), np.array([1, 5, 2])) - >>> [x for x in result] - [-2, 3, 2] + >>> x1 = np.array([2, 3, 4]) + >>> x2 = np.array([1, 5, 2]) + >>> np.minimum(x1, x2) + array([1, 3, 2]) + + >>> x1 = np.eye(2) + >>> x2 = np.array([0.5, 2]) + >>> np.minimum(x1, x2) # broadcasting + array([[0.5, 0. ], + [0. , 1. ]] + + >>> x1 = np.array([np.nan, 0, np.nan]) + >>> x2 = np.array([0, np.nan, np.nan]) + >>> np.minimum(x1, x2) + array([ 0., 0., nan]) + + >>> np.minimum(np.array(-np.Inf), 1) + array(-inf) """ - x1_is_scalar = dpnp.isscalar(x1) - x2_is_scalar = dpnp.isscalar(x2) - x1_desc = dpnp.get_dpnp_descriptor( - x1, copy_when_strides=False, copy_when_nondefault_queue=False - ) - x2_desc = dpnp.get_dpnp_descriptor( - x2, copy_when_strides=False, copy_when_nondefault_queue=False - ) + if kwargs: + 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: + if out is not None: + if not dpnp.is_supported_array_type(out): + raise TypeError( + "return array must be of supported array type" + ) + out_desc = ( + dpnp.get_dpnp_descriptor( + out, copy_when_nondefault_queue=False + ) + or None + ) + else: + out_desc = None - if x1_desc and x2_desc and not kwargs: - if not x1_desc and not x1_is_scalar: - pass - elif not x2_desc and not x2_is_scalar: - pass - elif x1_is_scalar and x2_is_scalar: - pass - elif x1_desc and x1_desc.ndim == 0: - pass - elif x2_desc and x2_desc.ndim == 0: - pass - elif dtype is not None: - pass - elif out is not None: - pass - elif not where: - pass - else: return dpnp_minimum( - x1_desc, x2_desc, dtype=dtype, out=out, where=where + x1_desc, x2_desc, dtype=dtype, out=out_desc, where=where ).get_pyobj() return call_origin( @@ -1242,7 +1414,7 @@ def mod( 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 `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`. @@ -1279,7 +1451,7 @@ def modf(x1, **kwargs): Limitations ----------- Parameter `x` 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`. @@ -1328,7 +1500,7 @@ def multiply( 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 `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`. @@ -1378,7 +1550,7 @@ def nancumprod(x1, **kwargs): Limitations ----------- Parameter `x` is supported as :class:`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`. @@ -1415,7 +1587,7 @@ def nancumsum(x1, **kwargs): Limitations ----------- Parameter `x` is supported as :class:`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`. @@ -1453,7 +1625,7 @@ def nanprod(x1, **kwargs): Limitations ----------- Parameter `x1` 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`. @@ -1483,7 +1655,7 @@ def nansum(x1, **kwargs): Limitations ----------- Parameter `x1` is supported as :class:`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`. @@ -1531,7 +1703,7 @@ def negative( ----------- 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. + 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`. @@ -1594,7 +1766,7 @@ def proj( ----------- 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. + Keyword argument `kwargs` is currently unsupported. Input array data types are limited by supported DPNP :ref:`Data types`. See Also @@ -1644,7 +1816,7 @@ def power(x1, x2, /, out=None, *, where=True, dtype=None, subok=True, **kwargs): 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 `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`. @@ -2281,7 +2453,7 @@ def trapz(y1, x1=None, dx=1.0, axis=-1): Limitations ----------- Parameters `y` and `x` are supported as :class:`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`. @@ -2376,7 +2548,7 @@ def trunc( ----------- 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 real-value data types. diff --git a/dpnp/dpnp_iface_trigonometric.py b/dpnp/dpnp_iface_trigonometric.py index 82df251ad3d5..f01ff69a4801 100644 --- a/dpnp/dpnp_iface_trigonometric.py +++ b/dpnp/dpnp_iface_trigonometric.py @@ -651,16 +651,22 @@ def expm1(x1): return call_origin(numpy.expm1, x1) -def hypot(x1, x2, dtype=None, out=None, where=True, **kwargs): +def hypot(x1, x2, /, out=None, *, where=True, dtype=None, subok=True, **kwargs): """ Given the "legs" of a right triangle, return its hypotenuse. For full documentation refer to :obj:`numpy.hypot`. + Returns + ------- + out : dpnp.ndarray + The hypotenuse of the triangle(s). + 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. + 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 `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`. @@ -668,48 +674,72 @@ def hypot(x1, x2, dtype=None, out=None, where=True, **kwargs): Examples -------- >>> import dpnp as np - >>> x1 = 3 * np.ones(3) - >>> x2 = 4 * np.ones(3) - >>> out = np.hypot(x1, x2) - >>> [i for i in out] - [5.0, 5.0, 5.0] + >>> x1 = 3 * np.ones((3, 3)) + >>> x2 = 4 * np.ones((3, 3)) + >>> np.hypot(x1, x2) + array([[5., 5., 5.], + [5., 5., 5.], + [5., 5., 5.]]) + + Example showing broadcast of scalar argument: + + >>> np.hypot(x1, 4) + array([[ 5., 5., 5.], + [ 5., 5., 5.], + [ 5., 5., 5.]]) """ - x1_is_scalar = dpnp.isscalar(x1) - x2_is_scalar = dpnp.isscalar(x2) - x1_desc = dpnp.get_dpnp_descriptor( - x1, copy_when_strides=False, copy_when_nondefault_queue=False - ) - x2_desc = dpnp.get_dpnp_descriptor( - x2, copy_when_strides=False, copy_when_nondefault_queue=False - ) + if kwargs: + 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: + if out is not None: + if not dpnp.is_supported_array_type(out): + raise TypeError( + "return array must be of supported array type" + ) + out_desc = ( + dpnp.get_dpnp_descriptor( + out, copy_when_nondefault_queue=False + ) + or None + ) + else: + out_desc = None - if x1_desc and x2_desc and not kwargs: - if not x1_desc and not x1_is_scalar: - pass - elif not x2_desc and not x2_is_scalar: - pass - elif x1_is_scalar and x2_is_scalar: - pass - elif x1_desc and x1_desc.ndim == 0: - pass - elif x2_desc and x2_desc.ndim == 0: - pass - elif dtype is not None: - pass - elif out is not None: - pass - elif not where: - pass - else: - out_desc = ( - dpnp.get_dpnp_descriptor(out, copy_when_nondefault_queue=False) - if out is not None - else None - ) return dpnp_hypot( - x1_desc, x2_desc, dtype, out_desc, where + x1_desc, x2_desc, dtype=dtype, out=out_desc, where=where ).get_pyobj() return call_origin( diff --git a/tests/test_mathematical.py b/tests/test_mathematical.py index f8e285ff24e6..65af3d50cf42 100644 --- a/tests/test_mathematical.py +++ b/tests/test_mathematical.py @@ -167,7 +167,7 @@ def test_divide(self, dtype, lhs, rhs): "dtype", get_all_dtypes(no_bool=True, no_complex=True) ) def test_fmod(self, dtype, lhs, rhs): - if dtype == None and rhs == 0.3 and not has_support_aspect64(): + if rhs == 0.3: """ Due to accuracy reason, the results are different for `float32` and `float64` >>> numpy.fmod(numpy.array([3.9], dtype=numpy.float32), 0.3) diff --git a/tests/third_party/cupy/math_tests/test_arithmetic.py b/tests/third_party/cupy/math_tests/test_arithmetic.py index f15682b9a675..6f20056b722c 100644 --- a/tests/third_party/cupy/math_tests/test_arithmetic.py +++ b/tests/third_party/cupy/math_tests/test_arithmetic.py @@ -126,7 +126,7 @@ def test_unary(self, xp): class ArithmeticBinaryBase: - @testing.numpy_cupy_allclose(atol=1e-4, type_check=has_support_aspect64()) + @testing.numpy_cupy_allclose(atol=1e-4, type_check=False) def check_binary(self, xp): arg1 = self.arg1 arg2 = self.arg2