diff --git a/dpnp/backend/include/dpnp_iface_fptr.hpp b/dpnp/backend/include/dpnp_iface_fptr.hpp index fbb18be244b..e7cdc0d6cea 100644 --- a/dpnp/backend/include/dpnp_iface_fptr.hpp +++ b/dpnp/backend/include/dpnp_iface_fptr.hpp @@ -132,9 +132,7 @@ enum class DPNPFuncName : size_t DPNP_FN_DET_EXT, /**< Used in numpy.linalg.det() impl, requires extra parameters */ DPNP_FN_DIAG, /**< Used in numpy.diag() impl */ - DPNP_FN_DIAG_EXT, /**< Used in numpy.diag() impl, requires extra parameters - */ - DPNP_FN_DIAG_INDICES, /**< Used in numpy.diag_indices() impl */ + DPNP_FN_DIAG_INDICES, /**< Used in numpy.diag_indices() impl */ DPNP_FN_DIAG_INDICES_EXT, /**< Used in numpy.diag_indices() impl, requires extra parameters */ DPNP_FN_DIAGONAL, /**< Used in numpy.diagonal() impl */ @@ -225,25 +223,24 @@ enum class DPNPFuncName : size_t DPNP_FN_MODF_EXT, /**< Used in numpy.modf() impl, requires extra parameters */ DPNP_FN_MULTIPLY, /**< Used in numpy.multiply() impl */ - DPNP_FN_MULTIPLY_EXT, /**< Used in numpy.multiply() impl, requires extra - parameters */ - DPNP_FN_NANVAR, /**< Used in numpy.nanvar() impl */ - DPNP_FN_NANVAR_EXT, /**< Used in numpy.nanvar() impl, requires extra - parameters */ - DPNP_FN_NEGATIVE, /**< Used in numpy.negative() impl */ - DPNP_FN_NONZERO, /**< Used in numpy.nonzero() impl */ - DPNP_FN_ONES, /**< Used in numpy.ones() impl */ - DPNP_FN_ONES_LIKE, /**< Used in numpy.ones_like() impl */ - DPNP_FN_PARTITION, /**< Used in numpy.partition() impl */ - DPNP_FN_PARTITION_EXT, /**< Used in numpy.partition() impl, requires extra - parameters */ - DPNP_FN_PLACE, /**< Used in numpy.place() impl */ - DPNP_FN_POWER, /**< Used in numpy.power() impl */ - DPNP_FN_PROD, /**< Used in numpy.prod() impl */ - DPNP_FN_PTP, /**< Used in numpy.ptp() impl */ - DPNP_FN_PTP_EXT, /**< Used in numpy.ptp() impl, requires extra parameters */ - DPNP_FN_PUT, /**< Used in numpy.put() impl */ - DPNP_FN_PUT_ALONG_AXIS, /**< Used in numpy.put_along_axis() impl */ + DPNP_FN_MULTIPLY_EXT, /**< Used in numpy.multiply() impl, requires extra + parameters */ + DPNP_FN_NANVAR, /**< Used in numpy.nanvar() impl */ + DPNP_FN_NANVAR_EXT, /**< Used in numpy.nanvar() impl, requires extra + parameters */ + DPNP_FN_NEGATIVE, /**< Used in numpy.negative() impl */ + DPNP_FN_NONZERO, /**< Used in numpy.nonzero() impl */ + DPNP_FN_ONES, /**< Used in numpy.ones() impl */ + DPNP_FN_ONES_LIKE, /**< Used in numpy.ones_like() impl */ + DPNP_FN_PARTITION, /**< Used in numpy.partition() impl */ + DPNP_FN_PARTITION_EXT, /**< Used in numpy.partition() impl, requires extra + parameters */ + DPNP_FN_PLACE, /**< Used in numpy.place() impl */ + DPNP_FN_POWER, /**< Used in numpy.power() impl */ + DPNP_FN_PROD, /**< Used in numpy.prod() impl */ + DPNP_FN_PTP, /**< Used in numpy.ptp() impl */ + DPNP_FN_PUT, /**< Used in numpy.put() impl */ + DPNP_FN_PUT_ALONG_AXIS, /**< Used in numpy.put_along_axis() impl */ DPNP_FN_PUT_ALONG_AXIS_EXT, /**< Used in numpy.put_along_axis() impl, requires extra parameters */ DPNP_FN_QR, /**< Used in numpy.linalg.qr() impl */ @@ -401,21 +398,19 @@ enum class DPNPFuncName : size_t DPNP_FN_TAKE, /**< Used in numpy.take() impl */ DPNP_FN_TAN, /**< Used in numpy.tan() impl */ DPNP_FN_TANH, /**< Used in numpy.tanh() impl */ - DPNP_FN_TRANSPOSE, /**< Used in numpy.transpose() impl */ - DPNP_FN_TRACE, /**< Used in numpy.trace() impl */ - DPNP_FN_TRACE_EXT, /**< Used in numpy.trace() impl, requires extra - parameters */ - DPNP_FN_TRAPZ, /**< Used in numpy.trapz() impl */ - DPNP_FN_TRAPZ_EXT, /**< Used in numpy.trapz() impl, requires extra - parameters */ - DPNP_FN_TRI, /**< Used in numpy.tri() impl */ - DPNP_FN_TRIL, /**< Used in numpy.tril() impl */ - DPNP_FN_TRIU, /**< Used in numpy.triu() impl */ - DPNP_FN_TRUNC, /**< Used in numpy.trunc() impl */ - DPNP_FN_VANDER, /**< Used in numpy.vander() impl */ - DPNP_FN_VANDER_EXT, /**< Used in numpy.vander() impl, requires extra - parameters */ - DPNP_FN_VAR, /**< Used in numpy.var() impl */ + DPNP_FN_TRANSPOSE, /**< Used in numpy.transpose() impl */ + DPNP_FN_TRACE, /**< Used in numpy.trace() impl */ + DPNP_FN_TRACE_EXT, /**< Used in numpy.trace() impl, requires extra + parameters */ + DPNP_FN_TRAPZ, /**< Used in numpy.trapz() impl */ + DPNP_FN_TRAPZ_EXT, /**< Used in numpy.trapz() impl, requires extra + parameters */ + DPNP_FN_TRI, /**< Used in numpy.tri() impl */ + DPNP_FN_TRIL, /**< Used in numpy.tril() impl */ + DPNP_FN_TRIU, /**< Used in numpy.triu() impl */ + DPNP_FN_TRUNC, /**< Used in numpy.trunc() impl */ + DPNP_FN_VANDER, /**< Used in numpy.vander() impl */ + DPNP_FN_VAR, /**< Used in numpy.var() impl */ DPNP_FN_VAR_EXT, /**< Used in numpy.var() impl, requires extra parameters */ DPNP_FN_ZEROS, /**< Used in numpy.zeros() impl */ DPNP_FN_ZEROS_LIKE, /**< Used in numpy.zeros_like() impl */ diff --git a/dpnp/backend/kernels/dpnp_krnl_arraycreation.cpp b/dpnp/backend/kernels/dpnp_krnl_arraycreation.cpp index a655c03100f..b1af79e019d 100644 --- a/dpnp/backend/kernels/dpnp_krnl_arraycreation.cpp +++ b/dpnp/backend/kernels/dpnp_krnl_arraycreation.cpp @@ -200,18 +200,6 @@ void (*dpnp_diag_default_c)(void *, const size_t, const size_t) = dpnp_diag_c<_DataType>; -template -DPCTLSyclEventRef (*dpnp_diag_ext_c)(DPCTLSyclQueueRef, - void *, - void *, - const int, - shape_elem_type *, - shape_elem_type *, - const size_t, - const size_t, - const DPCTLEventVectorRef) = - dpnp_diag_c<_DataType>; - template DPCTLSyclEventRef dpnp_eye_c(DPCTLSyclQueueRef q_ref, void *result1, @@ -569,23 +557,6 @@ void (*dpnp_ptp_default_c)(void *, const shape_elem_type *, const size_t) = dpnp_ptp_c<_DataType>; -template -DPCTLSyclEventRef (*dpnp_ptp_ext_c)(DPCTLSyclQueueRef, - void *, - const size_t, - const size_t, - const shape_elem_type *, - const shape_elem_type *, - const void *, - const size_t, - const size_t, - const shape_elem_type *, - const shape_elem_type *, - const shape_elem_type *, - const size_t, - const DPCTLEventVectorRef) = - dpnp_ptp_c<_DataType>; - template DPCTLSyclEventRef dpnp_vander_c(DPCTLSyclQueueRef q_ref, const void *array1_in, @@ -673,16 +644,6 @@ void (*dpnp_vander_default_c)(const void *, const int) = dpnp_vander_c<_DataType_input, _DataType_output>; -template -DPCTLSyclEventRef (*dpnp_vander_ext_c)(DPCTLSyclQueueRef, - const void *, - void *, - const size_t, - const size_t, - const int, - const DPCTLEventVectorRef) = - dpnp_vander_c<_DataType_input, _DataType_output>; - template class dpnp_trace_c_kernel; @@ -1192,15 +1153,6 @@ void func_map_init_arraycreation(func_map_t &fmap) fmap[DPNPFuncName::DPNP_FN_DIAG][eft_DBL][eft_DBL] = { eft_DBL, (void *)dpnp_diag_default_c}; - fmap[DPNPFuncName::DPNP_FN_DIAG_EXT][eft_INT][eft_INT] = { - eft_INT, (void *)dpnp_diag_ext_c}; - fmap[DPNPFuncName::DPNP_FN_DIAG_EXT][eft_LNG][eft_LNG] = { - eft_LNG, (void *)dpnp_diag_ext_c}; - fmap[DPNPFuncName::DPNP_FN_DIAG_EXT][eft_FLT][eft_FLT] = { - eft_FLT, (void *)dpnp_diag_ext_c}; - fmap[DPNPFuncName::DPNP_FN_DIAG_EXT][eft_DBL][eft_DBL] = { - eft_DBL, (void *)dpnp_diag_ext_c}; - fmap[DPNPFuncName::DPNP_FN_EYE][eft_INT][eft_INT] = { eft_INT, (void *)dpnp_eye_default_c}; fmap[DPNPFuncName::DPNP_FN_EYE][eft_LNG][eft_LNG] = { @@ -1284,15 +1236,6 @@ void func_map_init_arraycreation(func_map_t &fmap) fmap[DPNPFuncName::DPNP_FN_PTP][eft_DBL][eft_DBL] = { eft_DBL, (void *)dpnp_ptp_default_c}; - fmap[DPNPFuncName::DPNP_FN_PTP_EXT][eft_INT][eft_INT] = { - eft_INT, (void *)dpnp_ptp_ext_c}; - fmap[DPNPFuncName::DPNP_FN_PTP_EXT][eft_LNG][eft_LNG] = { - eft_LNG, (void *)dpnp_ptp_ext_c}; - fmap[DPNPFuncName::DPNP_FN_PTP_EXT][eft_FLT][eft_FLT] = { - eft_FLT, (void *)dpnp_ptp_ext_c}; - fmap[DPNPFuncName::DPNP_FN_PTP_EXT][eft_DBL][eft_DBL] = { - eft_DBL, (void *)dpnp_ptp_ext_c}; - fmap[DPNPFuncName::DPNP_FN_VANDER][eft_INT][eft_INT] = { eft_LNG, (void *)dpnp_vander_default_c}; fmap[DPNPFuncName::DPNP_FN_VANDER][eft_LNG][eft_LNG] = { @@ -1308,23 +1251,6 @@ void func_map_init_arraycreation(func_map_t &fmap) (void *) dpnp_vander_default_c, std::complex>}; - fmap[DPNPFuncName::DPNP_FN_VANDER_EXT][eft_INT][eft_INT] = { - eft_LNG, (void *)dpnp_vander_ext_c}; - fmap[DPNPFuncName::DPNP_FN_VANDER_EXT][eft_LNG][eft_LNG] = { - eft_LNG, (void *)dpnp_vander_ext_c}; - fmap[DPNPFuncName::DPNP_FN_VANDER_EXT][eft_FLT][eft_FLT] = { - eft_FLT, (void *)dpnp_vander_ext_c}; - fmap[DPNPFuncName::DPNP_FN_VANDER_EXT][eft_DBL][eft_DBL] = { - eft_DBL, (void *)dpnp_vander_ext_c}; - fmap[DPNPFuncName::DPNP_FN_VANDER_EXT][eft_BLN][eft_BLN] = { - eft_LNG, (void *)dpnp_vander_ext_c}; - fmap[DPNPFuncName::DPNP_FN_VANDER_EXT][eft_C64][eft_C64] = { - eft_C64, - (void *)dpnp_vander_ext_c, std::complex>}; - fmap[DPNPFuncName::DPNP_FN_VANDER_EXT][eft_C128][eft_C128] = { - eft_C128, - (void *)dpnp_vander_ext_c, std::complex>}; - fmap[DPNPFuncName::DPNP_FN_TRACE][eft_INT][eft_INT] = { eft_INT, (void *)dpnp_trace_default_c}; fmap[DPNPFuncName::DPNP_FN_TRACE][eft_LNG][eft_INT] = { diff --git a/dpnp/dpnp_algo/dpnp_algo.pxd b/dpnp/dpnp_algo/dpnp_algo.pxd index 7ff37794e93..d6d25fef1b9 100644 --- a/dpnp/dpnp_algo/dpnp_algo.pxd +++ b/dpnp/dpnp_algo/dpnp_algo.pxd @@ -64,8 +64,6 @@ cdef extern from "dpnp_iface_fptr.hpp" namespace "DPNPFuncName": # need this na DPNP_FN_DEGREES_EXT DPNP_FN_DET DPNP_FN_DET_EXT - DPNP_FN_DIAG - DPNP_FN_DIAG_EXT DPNP_FN_DIAG_INDICES DPNP_FN_DIAG_INDICES_EXT DPNP_FN_DIAGONAL @@ -120,8 +118,6 @@ cdef extern from "dpnp_iface_fptr.hpp" namespace "DPNPFuncName": # need this na DPNP_FN_PARTITION DPNP_FN_PARTITION_EXT DPNP_FN_PLACE - DPNP_FN_PTP - DPNP_FN_PTP_EXT DPNP_FN_QR DPNP_FN_QR_EXT DPNP_FN_RADIANS @@ -218,8 +214,6 @@ cdef extern from "dpnp_iface_fptr.hpp" namespace "DPNPFuncName": # need this na DPNP_FN_TRIL_EXT DPNP_FN_TRIU DPNP_FN_TRIU_EXT - DPNP_FN_VANDER - DPNP_FN_VANDER_EXT DPNP_FN_VAR DPNP_FN_VAR_EXT DPNP_FN_ZEROS diff --git a/dpnp/dpnp_algo/dpnp_algo_arraycreation.pxi b/dpnp/dpnp_algo/dpnp_algo_arraycreation.pxi index 7b90ff1285f..1322b1ccea5 100644 --- a/dpnp/dpnp_algo/dpnp_algo_arraycreation.pxi +++ b/dpnp/dpnp_algo/dpnp_algo_arraycreation.pxi @@ -37,10 +37,7 @@ and the rest of the library __all__ += [ "dpnp_copy", - "dpnp_diag", - "dpnp_ptp", "dpnp_trace", - "dpnp_vander", ] @@ -88,136 +85,6 @@ cpdef utils.dpnp_descriptor dpnp_copy(utils.dpnp_descriptor x1): return call_fptr_1in_1out_strides(DPNP_FN_COPY_EXT, x1) -cpdef utils.dpnp_descriptor dpnp_diag(utils.dpnp_descriptor v, int k): - cdef shape_type_c input_shape = v.shape - cdef shape_type_c result_shape - - if v.ndim == 1: - n = v.shape[0] + abs(k) - - result_shape = (n, n) - else: - n = min(v.shape[0], v.shape[0] + k, v.shape[1], v.shape[1] - k) - if n < 0: - n = 0 - - result_shape = (n, ) - - v_obj = v.get_array() - - result_obj = dpnp_container.zeros(result_shape, dtype=v.dtype, device=v_obj.sycl_device) - cdef utils.dpnp_descriptor result = dpnp_descriptor(result_obj) - - cdef DPNPFuncType param1_type = dpnp_dtype_to_DPNPFuncType(v.dtype) - - cdef DPNPFuncData kernel_data = get_dpnp_function_ptr(DPNP_FN_DIAG_EXT, param1_type, param1_type) - - result_sycl_queue = result.get_array().sycl_queue - - cdef c_dpctl.SyclQueue q = result_sycl_queue - cdef c_dpctl.DPCTLSyclQueueRef q_ref = q.get_queue_ref() - - cdef custom_1in_1out_func_ptr_t func = kernel_data.ptr - - cdef c_dpctl.DPCTLSyclEventRef event_ref = func(q_ref, - v.get_data(), - result.get_data(), - k, - input_shape.data(), - result_shape.data(), - v.ndim, - result.ndim, - NULL) # dep_events_ref - - with nogil: c_dpctl.DPCTLEvent_WaitAndThrow(event_ref) - c_dpctl.DPCTLEvent_Delete(event_ref) - - return result - - -cpdef dpnp_ptp(utils.dpnp_descriptor arr, axis=None): - cdef shape_type_c shape_arr = arr.shape - cdef shape_type_c output_shape - if axis is None: - axis_ = axis - output_shape = (1,) - else: - if isinstance(axis, int): - if axis < 0: - axis_ = tuple([arr.ndim - axis]) - else: - axis_ = tuple([axis]) - else: - _axis_ = [] - for i in range(len(axis)): - if axis[i] < 0: - _axis_.append(arr.ndim - axis[i]) - else: - _axis_.append(axis[i]) - axis_ = tuple(_axis_) - - out_shape = [] - ind = 0 - for id, shape_axis in enumerate(shape_arr): - if id not in axis_: - out_shape.append(shape_axis) - output_shape = tuple(out_shape) - - cdef DPNPFuncType param1_type = dpnp_dtype_to_DPNPFuncType(arr.dtype) - - cdef DPNPFuncData kernel_data = get_dpnp_function_ptr(DPNP_FN_PTP_EXT, param1_type, param1_type) - - arr_obj = arr.get_array() - - cdef utils.dpnp_descriptor result = utils.create_output_descriptor(output_shape, - kernel_data.return_type, - None, - device=arr_obj.sycl_device, - usm_type=arr_obj.usm_type, - sycl_queue=arr_obj.sycl_queue) - - cdef shape_type_c axis1 - cdef Py_ssize_t axis_size = 0 - cdef shape_type_c axis2 = axis1 - if axis_ is not None: - axis1 = axis_ - axis2.reserve(len(axis1)) - for shape_it in axis1: - if shape_it < 0: - raise ValueError("DPNP dparray::__init__(): Negative values in 'shape' are not allowed") - axis2.push_back(shape_it) - axis_size = len(axis1) - - cdef shape_type_c result_strides = utils.strides_to_vector(result.strides, result.shape) - cdef shape_type_c arr_strides = utils.strides_to_vector(arr.strides, arr.shape) - - result_sycl_queue = result.get_array().sycl_queue - - cdef c_dpctl.SyclQueue q = result_sycl_queue - cdef c_dpctl.DPCTLSyclQueueRef q_ref = q.get_queue_ref() - - cdef custom_arraycreation_1in_1out_func_ptr_t func = kernel_data.ptr - cdef c_dpctl.DPCTLSyclEventRef event_ref = func(q_ref, - result.get_data(), - result.size, - result.ndim, - output_shape.data(), - result_strides.data(), - arr.get_data(), - arr.size, - arr.ndim, - shape_arr.data(), - arr_strides.data(), - axis2.data(), - axis_size, - NULL) # dep_events_ref - - with nogil: c_dpctl.DPCTLEvent_WaitAndThrow(event_ref) - c_dpctl.DPCTLEvent_Delete(event_ref) - - return result - - cpdef utils.dpnp_descriptor dpnp_trace(utils.dpnp_descriptor arr, offset=0, axis1=0, axis2=1, dtype=None, out=None): if dtype is None: dtype_ = arr.dtype @@ -262,38 +129,3 @@ cpdef utils.dpnp_descriptor dpnp_trace(utils.dpnp_descriptor arr, offset=0, axis c_dpctl.DPCTLEvent_Delete(event_ref) return result - - -cpdef utils.dpnp_descriptor dpnp_vander(utils.dpnp_descriptor x1, int N, int increasing): - cdef DPNPFuncType param1_type = dpnp_dtype_to_DPNPFuncType(x1.dtype) - cdef DPNPFuncData kernel_data = get_dpnp_function_ptr(DPNP_FN_VANDER_EXT, param1_type, DPNP_FT_NONE) - - x1_obj = x1.get_array() - - # create result array with type given by FPTR data - cdef shape_type_c result_shape = (x1.size, N) - cdef utils.dpnp_descriptor result = utils.create_output_descriptor(result_shape, - kernel_data.return_type, - None, - device=x1_obj.sycl_device, - usm_type=x1_obj.usm_type, - sycl_queue=x1_obj.sycl_queue) - - result_sycl_queue = result.get_array().sycl_queue - - cdef c_dpctl.SyclQueue q = result_sycl_queue - cdef c_dpctl.DPCTLSyclQueueRef q_ref = q.get_queue_ref() - - cdef ftpr_custom_vander_1in_1out_t func = kernel_data.ptr - cdef c_dpctl.DPCTLSyclEventRef event_ref = func(q_ref, - x1.get_data(), - result.get_data(), - x1.size, - N, - increasing, - NULL) # dep_events_ref - - with nogil: c_dpctl.DPCTLEvent_WaitAndThrow(event_ref) - c_dpctl.DPCTLEvent_Delete(event_ref) - - return result diff --git a/dpnp/dpnp_array.py b/dpnp/dpnp_array.py index f6bd27a99a2..2d359b4a625 100644 --- a/dpnp/dpnp_array.py +++ b/dpnp/dpnp_array.py @@ -1039,8 +1039,6 @@ def prod( return dpnp.prod(self, axis, dtype, out, keepdims, initial, where) - # 'ptp' - def put(self, indices, vals, /, *, axis=None, mode="wrap"): """ Puts values of an array into another array along a given axis. diff --git a/dpnp/dpnp_container.py b/dpnp/dpnp_container.py index b36b64a5113..fac883a775b 100644 --- a/dpnp/dpnp_container.py +++ b/dpnp/dpnp_container.py @@ -218,6 +218,7 @@ def full( ): """Validate input parameters before passing them into `dpctl.tensor` module""" dpu.validate_usm_type(usm_type, allow_none=True) + sycl_queue_normalized = dpnp.get_normalized_queue_device( fill_value, sycl_queue=sycl_queue, device=device ) diff --git a/dpnp/dpnp_iface_arraycreation.py b/dpnp/dpnp_iface_arraycreation.py index 0ed1187cb1d..edcfe7ab3fc 100644 --- a/dpnp/dpnp_iface_arraycreation.py +++ b/dpnp/dpnp_iface_arraycreation.py @@ -1,5 +1,3 @@ -# cython: language_level=3 -# distutils: language = c++ # -*- coding: utf-8 -*- # ***************************************************************************** # Copyright (c) 2016-2023, Intel Corporation @@ -86,7 +84,6 @@ "ogrid", "ones", "ones_like", - "ptp", "trace", "tri", "tril", @@ -582,12 +579,30 @@ def copy(a, order="K", subok=False): return array(a, order=order, subok=subok, copy=True) -def diag(x1, k=0): +def diag(v, /, k=0, *, device=None, usm_type=None, sycl_queue=None): """ Extract a diagonal or construct a diagonal array. For full documentation refer to :obj:`numpy.diag`. + Returns + ------- + out : dpnp.ndarray + The extracted diagonal or constructed diagonal array. + + Limitations + ----------- + Parameter `k` is only supported as integer data type. + Otherwise ``TypeError`` exception will be raised. + + See Also + -------- + :obj:`diagonal` : Return specified diagonals. + :obj:`diagflat` : Create a 2-D array with the flattened input as a diagonal. + :obj:`trace` : Return sum along diagonals. + :obj:`triu` : Return upper triangle of an array. + :obj:`tril` : Return lower triangle of an array. + Examples -------- >>> import dpnp as np @@ -611,50 +626,92 @@ def diag(x1, k=0): """ - x1_desc = dpnp.get_dpnp_descriptor(x1, copy_when_nondefault_queue=False) - if x1_desc: - if not isinstance(k, int): - pass - elif x1_desc.ndim != 1 and x1_desc.ndim != 2: - pass - else: - return dpnp_diag(x1_desc, k).get_pyobj() + if not isinstance(k, int): + raise TypeError("An integer is required, but got {}".format(type(k))) + else: + v = dpnp.asarray( + v, device=device, usm_type=usm_type, sycl_queue=sycl_queue + ) - return call_origin(numpy.diag, x1, k) + init0 = max(0, -k) + init1 = max(0, k) + if v.ndim == 1: + size = v.shape[0] + abs(k) + m = dpnp.zeros( + (size, size), + dtype=v.dtype, + usm_type=v.usm_type, + sycl_queue=v.sycl_queue, + ) + for i in range(v.shape[0]): + m[(init0 + i), init1 + i] = v[i] + return m + elif v.ndim == 2: + size = min(v.shape[0], v.shape[0] + k, v.shape[1], v.shape[1] - k) + if size < 0: + size = 0 + m = dpnp.zeros( + (size,), + dtype=v.dtype, + usm_type=v.usm_type, + sycl_queue=v.sycl_queue, + ) + for i in range(size): + m[i] = v[(init0 + i), init1 + i] + return m + else: + raise ValueError("Input must be a 1-D or 2-D array.") -def diagflat(x1, k=0): +def diagflat(v, /, k=0, *, device=None, usm_type=None, sycl_queue=None): """ Create a two-dimensional array with the flattened input as a diagonal. For full documentation refer to :obj:`numpy.diagflat`. + Returns + ------- + out : dpnp.ndarray + The 2-D output array. + + See Also + -------- + :obj:`diag` : Return the extracted diagonal or constructed diagonal array. + :obj:`diagonal` : Return specified diagonals. + :obj:`trace` : Return sum along diagonals. + + Limitations + ----------- + Parameter `k` is only supported as integer data type. + Otherwise ``TypeError`` exception will be raised. + Examples -------- >>> import dpnp as np - >>> np.diagflat([[1,2], [3,4]]) + >>> x = np.array([[1,2], [3,4]]) + >>> np.diagflat(x) array([[1, 0, 0, 0], [0, 2, 0, 0], [0, 0, 3, 0], [0, 0, 0, 4]]) - >>> np.diagflat([1,2], 1) - array([[0, 1, 0], - [0, 0, 2], - [0, 0, 0]]) + >>> np.diagflat(x, 1) + array([[0, 1, 0, 0, 0], + [0, 0, 2, 0, 0], + [0, 0, 0, 3, 0], + [0, 0, 0, 0, 4], + [0, 0, 0, 0, 0]]) """ - x1_desc = dpnp.get_dpnp_descriptor(x1, copy_when_nondefault_queue=False) - if x1_desc: - input_ravel = dpnp.ravel(x1) - input_ravel_desc = dpnp.get_dpnp_descriptor( - input_ravel, copy_when_nondefault_queue=False + if not isinstance(k, int): + raise TypeError("An integer is required, but got {}".format(type(k))) + else: + v = dpnp.asarray( + v, device=device, usm_type=usm_type, sycl_queue=sycl_queue ) - - return dpnp_diag(input_ravel_desc, k).get_pyobj() - - return call_origin(numpy.diagflat, x1, k) + v = dpnp.ravel(v) + return dpnp.diag(v, k, usm_type=v.usm_type, sycl_queue=v.sycl_queue) def empty( @@ -778,12 +835,12 @@ def empty_like( def eye( N, - M=None, /, - *, + M=None, k=0, dtype=None, order="C", + *, like=None, device=None, usm_type="device", @@ -800,6 +857,18 @@ def eye( Parameter `like` is supported only with default value ``None``. Otherwise the function will be executed sequentially on CPU. + Examples + -------- + >>> import dpnp as np + >>> np.eye(2, dtype=int) + array([[1, 0], + [0, 1]]) + + >>> np.eye(3, k=1) + array([[0., 1., 0.], + [0., 0., 1.], + [0., 0., 0.]]) + """ if order not in ("C", "c", "F", "f", None): pass @@ -941,6 +1010,7 @@ def full( [10, 10, 10, 10] """ + if like is not None: pass elif order not in ("C", "c", "F", "f", None): @@ -1095,7 +1165,14 @@ def geomspace( def identity( - n, dtype=None, *, device=None, usm_type="device", sycl_queue=None, like=None + n, + /, + dtype=None, + *, + like=None, + device=None, + usm_type="device", + sycl_queue=None, ): """ Return the identity array. @@ -1552,36 +1629,6 @@ def ones_like( return call_origin(numpy.ones_like, x1, dtype, order, subok, shape) -def ptp(arr, axis=None, out=None, keepdims=numpy._NoValue): - """ - Range of values (maximum - minimum) along an axis. - - For full documentation refer to :obj:`numpy.ptp`. - - Limitations - ----------- - Input array is supported as :obj:`dpnp.ndarray`. - Parameters `out` and `keepdims` are supported only with default values. - - """ - arr_desc = dpnp.get_dpnp_descriptor(arr, copy_when_nondefault_queue=False) - if not arr_desc: - pass - elif axis is not None and not isinstance(axis, int): - pass - elif out is not None: - pass - elif keepdims is not numpy._NoValue: - pass - else: - result_obj = dpnp_ptp(arr_desc, axis=axis).get_pyobj() - result = dpnp.convert_single_elem_array_to_scalar(result_obj) - - return result - - return call_origin(numpy.ptp, arr, axis, out, keepdims) - - def trace(x1, offset=0, axis1=0, axis2=1, dtype=None, out=None): """ Return the sum along diagonals of the array. @@ -1616,9 +1663,11 @@ def trace(x1, offset=0, axis1=0, axis2=1, dtype=None, out=None): def tri( N, + /, M=None, k=0, dtype=dpnp.float, + *, device=None, usm_type="device", sycl_queue=None, @@ -1636,7 +1685,7 @@ def tri( Limitations ----------- - Parameter `M`, `N`, and `k` are only supported as integer data type. + Parameter `M`, `N`, and `k` are only supported as integer data type and when they are positive. Keyword argument `kwargs` is currently unsupported. Otherwise the function will be executed sequentially on CPU. @@ -1781,12 +1830,31 @@ def triu(x1, /, *, k=0): return call_origin(numpy.triu, x1, k) -def vander(x1, N=None, increasing=False): +def vander( + x1, + /, + N=None, + increasing=False, + *, + device=None, + usm_type=None, + sycl_queue=None, +): """ Generate a Vandermonde matrix. For full documentation refer to :obj:`numpy.vander`. + Returns + ------- + out : dpnp.ndarray + Vandermonde matrix. + + Limitations + ----------- + Parameter `N`, if it is not ``None``, is only supported as integer data type. + Otherwise ``TypeError`` exception will be raised. + Examples -------- >>> import dpnp as np @@ -1797,12 +1865,14 @@ def vander(x1, N=None, increasing=False): [ 4, 2, 1], [ 9, 3, 1], [25, 5, 1]]) + >>> x = np.array([1, 2, 3, 5]) >>> np.vander(x) array([[ 1, 1, 1, 1], [ 8, 4, 2, 1], [ 27, 9, 3, 1], [125, 25, 5, 1]]) + >>> np.vander(x, increasing=True) array([[ 1, 1, 1, 1], [ 1, 2, 4, 8], @@ -1810,17 +1880,33 @@ def vander(x1, N=None, increasing=False): [ 1, 5, 25, 125]]) """ - x1_desc = dpnp.get_dpnp_descriptor(x1, copy_when_nondefault_queue=False) - if x1_desc: - if x1.ndim != 1: - pass - else: - if N is None: - N = x1.size + x1 = dpnp.asarray( + x1, device=device, usm_type=usm_type, sycl_queue=sycl_queue + ) + + if N is not None and not isinstance(N, int): + raise TypeError("An integer is required, but got {}".format(type(N))) + elif x1.ndim != 1: + raise ValueError("x1 must be a one-dimensional array or sequence.") + else: + if N is None: + N = x1.size - return dpnp_vander(x1_desc, N, increasing).get_pyobj() + _dtype = int if x1.dtype == bool else x1.dtype + m = empty( + (x1.size, N), + dtype=_dtype, + usm_type=x1.usm_type, + sycl_queue=x1.sycl_queue, + ) + tmp = m[:, ::-1] if not increasing else m + dpnp.power( + x1.reshape(-1, 1), + dpnp.arange(N, dtype=_dtype, sycl_queue=x1.sycl_queue), + out=tmp, + ) - return call_origin(numpy.vander, x1, N=N, increasing=increasing) + return m def zeros( diff --git a/dpnp/dpnp_iface_statistics.py b/dpnp/dpnp_iface_statistics.py index 653b323c9e1..cc6f848ae9f 100644 --- a/dpnp/dpnp_iface_statistics.py +++ b/dpnp/dpnp_iface_statistics.py @@ -60,6 +60,7 @@ "mean", "median", "min", + "ptp", "nanvar", "std", "var", @@ -692,6 +693,49 @@ def min(a, axis=None, out=None, keepdims=False, initial=None, where=True): return out +def ptp( + a, + /, + axis=None, + out=None, + keepdims=False, +): + """ + Range of values (maximum - minimum) along an axis. + + For full documentation refer to :obj:`numpy.ptp`. + + Returns + ------- + ptp : dpnp.ndarray + The range of a given array. + + Limitations + ----------- + Input array is supported as :class:`dpnp.dpnp_array` or :class:`dpctl.tensor.usm_ndarray`. + + Examples + -------- + >>> import dpnp as np + >>> x = np.array([[4, 9, 2, 10],[6, 9, 7, 12]]) + >>> np.ptp(x, axis=1) + array([8, 6]) + + >>> np.ptp(x, axis=0) + array([2, 0, 5, 2]) + + >>> np.ptp(x) + array(10) + + """ + + return dpnp.subtract( + dpnp.max(a, axis=axis, keepdims=keepdims, out=out), + dpnp.min(a, axis=axis, keepdims=keepdims), + out=out, + ) + + def nanvar(x1, axis=None, dtype=None, out=None, ddof=0, keepdims=False): """ Compute the variance along the specified axis, while ignoring NaNs. diff --git a/tests/skipped_tests.tbl b/tests/skipped_tests.tbl index 3b9a6a95de9..e20654e877a 100644 --- a/tests/skipped_tests.tbl +++ b/tests/skipped_tests.tbl @@ -118,18 +118,6 @@ tests/third_party/cupy/core_tests/test_ndarray_copy_and_view.py::TestArrayFlatte tests/third_party/cupy/core_tests/test_ndarray_copy_and_view.py::TestArrayFlatten::test_flatten_order_copied tests/third_party/cupy/core_tests/test_ndarray_copy_and_view.py::TestArrayFlatten::test_flatten_order_transposed -tests/third_party/cupy/core_tests/test_ndarray_reduction.py::TestArrayReduction::test_ptp_all -tests/third_party/cupy/core_tests/test_ndarray_reduction.py::TestArrayReduction::test_ptp_all_keepdims -tests/third_party/cupy/core_tests/test_ndarray_reduction.py::TestArrayReduction::test_ptp_axis0 -tests/third_party/cupy/core_tests/test_ndarray_reduction.py::TestArrayReduction::test_ptp_axis1 -tests/third_party/cupy/core_tests/test_ndarray_reduction.py::TestArrayReduction::test_ptp_axis2 -tests/third_party/cupy/core_tests/test_ndarray_reduction.py::TestArrayReduction::test_ptp_axis_large -tests/third_party/cupy/core_tests/test_ndarray_reduction.py::TestArrayReduction::test_ptp_multiple_axes -tests/third_party/cupy/core_tests/test_ndarray_reduction.py::TestArrayReduction::test_ptp_multiple_axes_keepdims -tests/third_party/cupy/core_tests/test_ndarray_reduction.py::TestArrayReduction::test_ptp_nan -tests/third_party/cupy/core_tests/test_ndarray_reduction.py::TestArrayReduction::test_ptp_nan_imag -tests/third_party/cupy/core_tests/test_ndarray_reduction.py::TestArrayReduction::test_ptp_nan_real - tests/third_party/cupy/core_tests/test_ndarray_reduction.py::TestCubReduction_param_0_{order='C', shape=(10,)}::test_cub_max tests/third_party/cupy/core_tests/test_ndarray_reduction.py::TestCubReduction_param_0_{order='C', shape=(10,)}::test_cub_min tests/third_party/cupy/core_tests/test_ndarray_reduction.py::TestCubReduction_param_1_{order='C', shape=(10, 20)}::test_cub_max @@ -167,11 +155,6 @@ tests/third_party/cupy/creation_tests/test_basic.py::TestBasic::test_ones_like_s tests/third_party/cupy/creation_tests/test_basic.py::TestBasic::test_zeros_like_subok tests/third_party/cupy/creation_tests/test_basic.py::TestBasic::test_zeros_strides -tests/third_party/cupy/creation_tests/test_matrix.py::TestMatrix::test_diag_construction_from_list -tests/third_party/cupy/creation_tests/test_matrix.py::TestMatrix::test_diag_construction_from_tuple -tests/third_party/cupy/creation_tests/test_matrix.py::TestMatrix::test_diag_extraction_from_nested_list -tests/third_party/cupy/creation_tests/test_matrix.py::TestMatrix::test_diag_extraction_from_nested_tuple - tests/third_party/cupy/creation_tests/test_ranges.py::TestMeshgrid_param_0_{copy=False, indexing='xy', sparse=False}::test_meshgrid0 tests/third_party/cupy/creation_tests/test_ranges.py::TestMeshgrid_param_0_{copy=False, indexing='xy', sparse=False}::test_meshgrid1 tests/third_party/cupy/creation_tests/test_ranges.py::TestMeshgrid_param_0_{copy=False, indexing='xy', sparse=False}::test_meshgrid2 diff --git a/tests/skipped_tests_gpu.tbl b/tests/skipped_tests_gpu.tbl index c7820b56af1..cb35f064334 100644 --- a/tests/skipped_tests_gpu.tbl +++ b/tests/skipped_tests_gpu.tbl @@ -109,12 +109,6 @@ tests/third_party/cupy/core_tests/test_ndarray_conversion.py::TestNdarrayToBytes tests/third_party/cupy/core_tests/test_ndarray_conversion.py::TestNdarrayToBytes_param_3_{order='C', shape=(2, 3)}::test_item tests/third_party/cupy/core_tests/test_ndarray_conversion.py::TestNdarrayToBytes_param_4_{order='F', shape=(2, 3)}::test_item -tests/third_party/cupy/creation_tests/test_matrix.py::TestMatrix::test_diag_construction -tests/third_party/cupy/creation_tests/test_matrix.py::TestMatrix::test_diag_construction_from_list -tests/third_party/cupy/creation_tests/test_matrix.py::TestMatrix::test_diag_construction_from_tuple -tests/third_party/cupy/creation_tests/test_matrix.py::TestMatrix::test_diag_extraction_from_nested_list -tests/third_party/cupy/creation_tests/test_matrix.py::TestMatrix::test_diag_extraction_from_nested_tuple - tests/third_party/cupy/indexing_tests/test_insert.py::TestFillDiagonal_param_4_{shape=(3, 3), val=(2,), wrap=True}::test_1darray tests/third_party/cupy/indexing_tests/test_insert.py::TestFillDiagonal_param_4_{shape=(3, 3), val=(2,), wrap=True}::test_fill_diagonal tests/third_party/cupy/indexing_tests/test_insert.py::TestFillDiagonal_param_5_{shape=(3, 3), val=(2,), wrap=False}::test_1darray @@ -200,17 +194,7 @@ tests/third_party/cupy/core_tests/test_ndarray_copy_and_view.py::TestArrayFlatte tests/third_party/cupy/core_tests/test_ndarray_copy_and_view.py::TestArrayFlatten::test_flatten_order_copied tests/third_party/cupy/core_tests/test_ndarray_copy_and_view.py::TestArrayFlatten::test_flatten_order_transposed -tests/third_party/cupy/core_tests/test_ndarray_reduction.py::TestArrayReduction::test_ptp_all -tests/third_party/cupy/core_tests/test_ndarray_reduction.py::TestArrayReduction::test_ptp_all_keepdims -tests/third_party/cupy/core_tests/test_ndarray_reduction.py::TestArrayReduction::test_ptp_axis0 -tests/third_party/cupy/core_tests/test_ndarray_reduction.py::TestArrayReduction::test_ptp_axis1 -tests/third_party/cupy/core_tests/test_ndarray_reduction.py::TestArrayReduction::test_ptp_axis2 -tests/third_party/cupy/core_tests/test_ndarray_reduction.py::TestArrayReduction::test_ptp_axis_large -tests/third_party/cupy/core_tests/test_ndarray_reduction.py::TestArrayReduction::test_ptp_multiple_axes -tests/third_party/cupy/core_tests/test_ndarray_reduction.py::TestArrayReduction::test_ptp_multiple_axes_keepdims -tests/third_party/cupy/core_tests/test_ndarray_reduction.py::TestArrayReduction::test_ptp_nan -tests/third_party/cupy/core_tests/test_ndarray_reduction.py::TestArrayReduction::test_ptp_nan_imag -tests/third_party/cupy/core_tests/test_ndarray_reduction.py::TestArrayReduction::test_ptp_nan_real + tests/third_party/cupy/core_tests/test_ndarray_reduction.py::TestCubReduction_param_0_{order='C', shape=(10,)}::test_cub_max tests/third_party/cupy/core_tests/test_ndarray_reduction.py::TestCubReduction_param_0_{order='C', shape=(10,)}::test_cub_min diff --git a/tests/test_arraycreation.py b/tests/test_arraycreation.py index 7c674d265da..779e62237a0 100644 --- a/tests/test_arraycreation.py +++ b/tests/test_arraycreation.py @@ -91,6 +91,7 @@ def test_arange(start, stop, step, dtype): assert_array_equal(exp_array, res_array) +@pytest.mark.parametrize("func", ["diag", "diagflat"]) @pytest.mark.parametrize( "k", [-6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6], @@ -117,11 +118,40 @@ def test_arange(start, stop, step, dtype): "[[0, 1, 2, 3, 4], [5, 6, 7, 8, 9]]", ], ) -def test_diag(v, k): +def test_diag_diagflat(func, v, k): a = numpy.array(v) ia = dpnp.array(a) - expected = numpy.diag(a, k) - result = dpnp.diag(ia, k) + expected = getattr(numpy, func)(a, k) + result = getattr(dpnp, func)(ia, k) + assert_array_equal(expected, result) + + +@pytest.mark.parametrize("func", ["diag", "diagflat"]) +def test_diag_diagflat_raise_error(func): + ia = dpnp.array([0, 1, 2, 3, 4]) + with pytest.raises(TypeError): + getattr(dpnp, func)(ia, k=2.0) + + +@pytest.mark.parametrize("func", ["diag", "diagflat"]) +@pytest.mark.parametrize( + "seq", + [ + [0, 1, 2, 3, 4], + (0, 1, 2, 3, 4), + [[0, 1, 2], [3, 4, 5], [6, 7, 8]], + [[0, 1, 2, 3, 4], [5, 6, 7, 8, 9]], + ], + ids=[ + "[0, 1, 2, 3, 4]", + "(0, 1, 2, 3, 4)", + "[[0, 1, 2], [3, 4, 5], [6, 7, 8]]", + "[[0, 1, 2, 3, 4], [5, 6, 7, 8, 9]]", + ], +) +def test_diag_diagflat_seq(func, seq): + expected = getattr(numpy, func)(seq) + result = getattr(dpnp, func)(seq) assert_array_equal(expected, result) @@ -426,12 +456,36 @@ def test_triu_size_null(k): @pytest.mark.parametrize("n", [0, 1, 4, None], ids=["0", "1", "4", "None"]) @pytest.mark.parametrize("increase", [True, False], ids=["True", "False"]) def test_vander(array, dtype, n, increase): - create_array = lambda xp: xp.array(array, dtype=dtype) + if dtype in [dpnp.complex64, dpnp.complex128] and array == [0, 3, 5]: + pytest.skip( + "per array API dpnp.power(complex(0,0)), 0) returns nan+nanj while NumPy returns 1+0j" + ) vander_func = lambda xp, x: xp.vander(x, N=n, increasing=increase) a_np = numpy.array(array, dtype=dtype) a_dpnp = dpnp.array(array, dtype=dtype) - assert_array_equal(vander_func(numpy, a_np), vander_func(dpnp, a_dpnp)) + + assert_allclose(vander_func(numpy, a_np), vander_func(dpnp, a_dpnp)) + + +def test_vander_raise_error(): + a = dpnp.array([1, 2, 3, 4]) + with pytest.raises(TypeError): + dpnp.vander(a, N=1.0) + + a = dpnp.array([[1, 2], [3, 4]]) + with pytest.raises(ValueError): + dpnp.vander(a) + + +@pytest.mark.parametrize( + "sequence", + [[1, 2, 3, 4], (1, 2, 3, 4)], + ids=["[1, 2, 3, 4]", "(1, 2, 3, 4)"], +) +def test_vander_seq(sequence): + vander_func = lambda xp, x: xp.vander(x) + assert_allclose(vander_func(numpy, sequence), vander_func(dpnp, sequence)) @pytest.mark.parametrize( diff --git a/tests/test_statistics.py b/tests/test_statistics.py index 2894f24a37b..fdfea361e6f 100644 --- a/tests/test_statistics.py +++ b/tests/test_statistics.py @@ -1,7 +1,10 @@ import dpctl.tensor as dpt import numpy import pytest -from numpy.testing import assert_allclose +from numpy.testing import ( + assert_allclose, + assert_array_equal, +) import dpnp @@ -190,3 +193,64 @@ def test_cov_1D_rowvar(dtype): a = dpnp.array([[0, 1, 2]], dtype=dtype) b = numpy.array([[0, 1, 2]], dtype=dtype) assert_allclose(numpy.cov(b, rowvar=False), dpnp.cov(a, rowvar=False)) + + +@pytest.mark.parametrize( + "axis", + [None, 0, 1], + ids=["None", "0", "1"], +) +@pytest.mark.parametrize( + "v", + [ + [[0, 0], [0, 0]], + [[1, 2], [1, 2]], + [[1, 2], [3, 4]], + [[0, 1, 2], [3, 4, 5], [6, 7, 8]], + [[0, 1, 2, 3, 4], [5, 6, 7, 8, 9]], + ], + ids=[ + "[[0, 0], [0, 0]]", + "[[1, 2], [1, 2]]", + "[[1, 2], [3, 4]]", + "[[0, 1, 2], [3, 4, 5], [6, 7, 8]]", + "[[0, 1, 2, 3, 4], [5, 6, 7, 8, 9]]", + ], +) +def test_ptp(v, axis): + a = numpy.array(v) + ia = dpnp.array(a) + expected = numpy.ptp(a, axis) + result = dpnp.ptp(ia, axis) + assert_array_equal(expected, result) + + +@pytest.mark.parametrize( + "axis", + [None, 0, 1], + ids=["None", "0", "1"], +) +@pytest.mark.parametrize( + "v", + [ + [[0, 0], [0, 0]], + [[1, 2], [1, 2]], + [[1, 2], [3, 4]], + [[0, 1, 2], [3, 4, 5], [6, 7, 8]], + [[0, 1, 2, 3, 4], [5, 6, 7, 8, 9]], + ], + ids=[ + "[[0, 0], [0, 0]]", + "[[1, 2], [1, 2]]", + "[[1, 2], [3, 4]]", + "[[0, 1, 2], [3, 4, 5], [6, 7, 8]]", + "[[0, 1, 2, 3, 4], [5, 6, 7, 8, 9]]", + ], +) +def test_ptp_out(v, axis): + a = numpy.array(v) + ia = dpnp.array(a) + expected = numpy.ptp(a, axis) + result = dpnp.array(numpy.empty_like(expected)) + dpnp.ptp(ia, axis, out=result) + assert_array_equal(expected, result) diff --git a/tests/test_sycl_queue.py b/tests/test_sycl_queue.py index 2a4a814b6f7..083616cbf85 100644 --- a/tests/test_sycl_queue.py +++ b/tests/test_sycl_queue.py @@ -141,6 +141,7 @@ def test_empty_like(device_x, device_y): @pytest.mark.parametrize( "func, args, kwargs", [ + pytest.param("diag", ["x0"], {}), pytest.param("full_like", ["x0"], {"fill_value": 5}), pytest.param("geomspace", ["x0[0:3]", "8", "4"], {}), pytest.param("geomspace", ["1", "x0[2:4]", "4"], {}), @@ -151,6 +152,9 @@ def test_empty_like(device_x, device_y): pytest.param("ones_like", ["x0"], {}), pytest.param("tril", ["x0.reshape((2,2))"], {}), pytest.param("triu", ["x0.reshape((2,2))"], {}), + pytest.param("linspace", ["x0", "4", "4"], {}), + pytest.param("linspace", ["1", "x0", "4"], {}), + pytest.param("vander", ["x0"], {}), pytest.param("zeros_like", ["x0"], {}), ], ) @@ -192,15 +196,43 @@ def test_array_creation_follow_device_logspace_base(device): assert_sycl_queue_equal(y.sycl_queue, x.sycl_queue) +@pytest.mark.parametrize( + "func, args, kwargs", + [ + pytest.param("diag", ["x0"], {}), + pytest.param("diagflat", ["x0"], {}), + ], +) +@pytest.mark.parametrize( + "device", + valid_devices, + ids=[device.filter_string for device in valid_devices], +) +def test_array_creation_follow_device_2d_array(func, args, kwargs, device): + x_orig = numpy.arange(9).reshape(3, 3) + numpy_args = [eval(val, {"x0": x_orig}) for val in args] + y_orig = getattr(numpy, func)(*numpy_args, **kwargs) + + x = dpnp.arange(9, device=device).reshape(3, 3) + dpnp_args = [eval(val, {"x0": x}) for val in args] + + y = getattr(dpnp, func)(*dpnp_args, **kwargs) + assert_allclose(y_orig, y) + assert_sycl_queue_equal(y.sycl_queue, x.sycl_queue) + + @pytest.mark.skip("muted until the issue reported by SAT-5969 is resolved") @pytest.mark.parametrize( "func, args, kwargs", [ + pytest.param("diag", ["x0"], {}), + pytest.param("full", ["10", "x0[3]"], {}), pytest.param("full_like", ["x0"], {"fill_value": 5}), pytest.param("ones_like", ["x0"], {}), pytest.param("zeros_like", ["x0"], {}), pytest.param("linspace", ["x0", "4", "4"], {}), pytest.param("linspace", ["1", "x0", "4"], {}), + pytest.param("vander", ["x0"], {}), ], ) @pytest.mark.parametrize( @@ -214,7 +246,7 @@ def test_array_creation_follow_device_logspace_base(device): ids=[device.filter_string for device in valid_devices], ) def test_array_creation_cross_device(func, args, kwargs, device_x, device_y): - if func is "linspace" and is_win_platform(): + if func == "linspace" and is_win_platform(): pytest.skip("CPU driver experiences an instability on Windows.") x_orig = numpy.array([1, 2, 3, 4]) @@ -225,8 +257,52 @@ def test_array_creation_cross_device(func, args, kwargs, device_x, device_y): dpnp_args = [eval(val, {"x0": x}) for val in args] dpnp_kwargs = dict(kwargs) + y = getattr(dpnp, func)(*dpnp_args, **dpnp_kwargs) + assert_sycl_queue_equal(y.sycl_queue, x.sycl_queue) + dpnp_kwargs["device"] = device_y + y = getattr(dpnp, func)(*dpnp_args, **dpnp_kwargs) + assert_allclose(y_orig, y) + + assert_sycl_queue_equal(y.sycl_queue, x.to_device(device_y).sycl_queue) + +@pytest.mark.skip("muted until the issue reported by SAT-5969 is resolved") +@pytest.mark.parametrize( + "func, args, kwargs", + [ + pytest.param("diag", ["x0"], {}), + pytest.param("diagflat", ["x0"], {}), + ], +) +@pytest.mark.parametrize( + "device_x", + valid_devices, + ids=[device.filter_string for device in valid_devices], +) +@pytest.mark.parametrize( + "device_y", + valid_devices, + ids=[device.filter_string for device in valid_devices], +) +def test_array_creation_cross_device_2d_array( + func, args, kwargs, device_x, device_y +): + if func == "linspace" and is_win_platform(): + pytest.skip("CPU driver experiences an instability on Windows.") + + x_orig = numpy.arange(9).reshape(3, 3) + numpy_args = [eval(val, {"x0": x_orig}) for val in args] + y_orig = getattr(numpy, func)(*numpy_args, **kwargs) + + x = dpnp.arange(9, device=device_x).reshape(3, 3) + dpnp_args = [eval(val, {"x0": x}) for val in args] + + dpnp_kwargs = dict(kwargs) + y = getattr(dpnp, func)(*dpnp_args, **dpnp_kwargs) + assert_sycl_queue_equal(y.sycl_queue, x.sycl_queue) + + dpnp_kwargs["device"] = device_y y = getattr(dpnp, func)(*dpnp_args, **dpnp_kwargs) assert_allclose(y_orig, y) @@ -295,6 +371,7 @@ def test_meshgrid(device_x, device_y): pytest.param("negative", [1.0, 0.0, -1.0]), pytest.param("positive", [1.0, 0.0, -1.0]), pytest.param("prod", [1.0, 2.0]), + pytest.param("ptp", [1.0, 2.0, 4.0, 7.0]), pytest.param( "real", [complex(1.0, 2.0), complex(3.0, 4.0), complex(5.0, 6.0)] ), diff --git a/tests/test_usm_type.py b/tests/test_usm_type.py index 99a39acae88..fd26d3e1c05 100644 --- a/tests/test_usm_type.py +++ b/tests/test_usm_type.py @@ -140,6 +140,7 @@ def test_coerced_usm_types_power(usm_type_x, usm_type_y): @pytest.mark.parametrize( "func, args", [ + pytest.param("diag", ["x0"]), pytest.param("empty_like", ["x0"]), pytest.param("full", ["10", "x0[3]"]), pytest.param("full_like", ["x0", "4"]), @@ -150,12 +151,13 @@ def test_coerced_usm_types_power(usm_type_x, usm_type_y): pytest.param("logspace", ["x0[0:2]", "8", "4"]), pytest.param("logspace", ["0", "x0[3:5]", "4"]), pytest.param("ones_like", ["x0"]), + pytest.param("vander", ["x0"]), pytest.param("zeros_like", ["x0"]), ], ) @pytest.mark.parametrize("usm_type_x", list_of_usm_types, ids=list_of_usm_types) @pytest.mark.parametrize("usm_type_y", list_of_usm_types, ids=list_of_usm_types) -def test_array_creation_from_an_array(func, args, usm_type_x, usm_type_y): +def test_array_creation_from_1d_array(func, args, usm_type_x, usm_type_y): x0 = dp.full(10, 3, usm_type=usm_type_x) new_args = [eval(val, {"x0": x0}) for val in args] @@ -166,6 +168,26 @@ def test_array_creation_from_an_array(func, args, usm_type_x, usm_type_y): assert y.usm_type == usm_type_y +@pytest.mark.parametrize( + "func, args", + [ + pytest.param("diag", ["x0"]), + pytest.param("diagflat", ["x0"]), + ], +) +@pytest.mark.parametrize("usm_type_x", list_of_usm_types, ids=list_of_usm_types) +@pytest.mark.parametrize("usm_type_y", list_of_usm_types, ids=list_of_usm_types) +def test_array_creation_from_2d_array(func, args, usm_type_x, usm_type_y): + x0 = dp.arange(25, usm_type=usm_type_x).reshape(5, 5) + new_args = [eval(val, {"x0": x0}) for val in args] + + x = getattr(dp, func)(*new_args) + y = getattr(dp, func)(*new_args, usm_type=usm_type_y) + + assert x.usm_type == usm_type_x + assert y.usm_type == usm_type_y + + @pytest.mark.parametrize( "func, arg, kwargs", [ @@ -374,6 +396,7 @@ def test_meshgrid(usm_type_x, usm_type_y): pytest.param("positive", [1.0, 0.0, -1.0]), pytest.param("prod", [1.0, 2.0]), pytest.param("proj", [complex(1.0, 2.0), complex(dp.inf, -1.0)]), + pytest.param("ptp", [1.0, 2.0, 4.0, 7.0]), pytest.param( "real", [complex(1.0, 2.0), complex(3.0, 4.0), complex(5.0, 6.0)] ), diff --git a/tests/third_party/cupy/core_tests/test_ndarray_reduction.py b/tests/third_party/cupy/core_tests/test_ndarray_reduction.py index 952398575f1..f22864bfef5 100644 --- a/tests/third_party/cupy/core_tests/test_ndarray_reduction.py +++ b/tests/third_party/cupy/core_tests/test_ndarray_reduction.py @@ -9,210 +9,222 @@ from tests.third_party.cupy import testing -@pytest.mark.usefixtures("allow_fall_back_on_numpy") @testing.gpu +@testing.parameterize( + *testing.product( + { + "order": ("C", "F"), + } + ) +) class TestArrayReduction(unittest.TestCase): @testing.for_all_dtypes() - @testing.numpy_cupy_allclose() + @testing.numpy_cupy_allclose(contiguous_check=False) def test_max_all(self, xp, dtype): - a = testing.shaped_random((2, 3), xp, dtype) + a = testing.shaped_random((2, 3), xp, dtype, order=self.order) return a.max() @testing.for_all_dtypes() - @testing.numpy_cupy_allclose() + @testing.numpy_cupy_allclose(contiguous_check=False) def test_max_all_keepdims(self, xp, dtype): - a = testing.shaped_random((2, 3), xp, dtype) + a = testing.shaped_random((2, 3), xp, dtype, order=self.order) return a.max(keepdims=True) @testing.for_all_dtypes() - @testing.numpy_cupy_allclose() + @testing.numpy_cupy_allclose(contiguous_check=False) def test_max_axis_large(self, xp, dtype): - a = testing.shaped_random((3, 1000), xp, dtype) + a = testing.shaped_random((3, 1000), xp, dtype, order=self.order) return a.max(axis=0) @testing.for_all_dtypes() - @testing.numpy_cupy_allclose() + @testing.numpy_cupy_allclose(contiguous_check=False) def test_max_axis0(self, xp, dtype): - a = testing.shaped_random((2, 3, 4), xp, dtype) + a = testing.shaped_random((2, 3, 4), xp, dtype, order=self.order) return a.max(axis=0) @testing.for_all_dtypes() - @testing.numpy_cupy_allclose() + @testing.numpy_cupy_allclose(contiguous_check=False) def test_max_axis1(self, xp, dtype): - a = testing.shaped_random((2, 3, 4), xp, dtype) + a = testing.shaped_random((2, 3, 4), xp, dtype, order=self.order) return a.max(axis=1) @testing.for_all_dtypes() - @testing.numpy_cupy_allclose() + @testing.numpy_cupy_allclose(contiguous_check=False) def test_max_axis2(self, xp, dtype): - a = testing.shaped_random((2, 3, 4), xp, dtype) + a = testing.shaped_random((2, 3, 4), xp, dtype, order=self.order) return a.max(axis=2) @testing.for_all_dtypes() - @testing.numpy_cupy_allclose() + @testing.numpy_cupy_allclose(contiguous_check=False) def test_max_multiple_axes(self, xp, dtype): - a = testing.shaped_random((2, 3, 4), xp, dtype) + a = testing.shaped_random((2, 3, 4), xp, dtype, order=self.order) return a.max(axis=(1, 2)) @testing.for_all_dtypes() - @testing.numpy_cupy_allclose() + @testing.numpy_cupy_allclose(contiguous_check=False) def test_max_multiple_axes_keepdims(self, xp, dtype): - a = testing.shaped_random((2, 3, 4), xp, dtype) + a = testing.shaped_random((2, 3, 4), xp, dtype, order=self.order) return a.max(axis=(1, 2), keepdims=True) @testing.for_float_dtypes() - @testing.numpy_cupy_allclose() + @testing.numpy_cupy_allclose(contiguous_check=False) def test_max_nan(self, xp, dtype): - a = xp.array([float("nan"), 1, -1], dtype) + a = xp.array([float("nan"), 1, -1], dtype, order=self.order) return a.max() @testing.for_complex_dtypes() - @testing.numpy_cupy_allclose() + @testing.numpy_cupy_allclose(contiguous_check=False) def test_max_nan_real(self, xp, dtype): - a = xp.array([float("nan"), 1, -1], dtype) + a = xp.array([float("nan"), 1, -1], dtype, order=self.order) return a.max() @testing.for_complex_dtypes() - @testing.numpy_cupy_allclose() + @testing.numpy_cupy_allclose(contiguous_check=False) def test_max_nan_imag(self, xp, dtype): - a = xp.array([float("nan") * 1.0j, 1.0j, -1.0j], dtype) + a = xp.array( + [float("nan") * 1.0j, 1.0j, -1.0j], dtype, order=self.order + ) return a.max() @testing.for_all_dtypes() - @testing.numpy_cupy_allclose() + @testing.numpy_cupy_allclose(contiguous_check=False) def test_min_all(self, xp, dtype): - a = testing.shaped_random((2, 3), xp, dtype) + a = testing.shaped_random((2, 3), xp, dtype, order=self.order) return a.min() @testing.for_all_dtypes() - @testing.numpy_cupy_allclose() + @testing.numpy_cupy_allclose(contiguous_check=False) def test_min_all_keepdims(self, xp, dtype): - a = testing.shaped_random((2, 3), xp, dtype) + a = testing.shaped_random((2, 3), xp, dtype, order=self.order) return a.min(keepdims=True) @testing.for_all_dtypes() - @testing.numpy_cupy_allclose() + @testing.numpy_cupy_allclose(contiguous_check=False) def test_min_axis_large(self, xp, dtype): - a = testing.shaped_random((3, 1000), xp, dtype) + a = testing.shaped_random((3, 1000), xp, dtype, order=self.order) return a.min(axis=0) @testing.for_all_dtypes() - @testing.numpy_cupy_allclose() + @testing.numpy_cupy_allclose(contiguous_check=False) def test_min_axis0(self, xp, dtype): - a = testing.shaped_random((2, 3, 4), xp, dtype) + a = testing.shaped_random((2, 3, 4), xp, dtype, order=self.order) return a.min(axis=0) @testing.for_all_dtypes() - @testing.numpy_cupy_allclose() + @testing.numpy_cupy_allclose(contiguous_check=False) def test_min_axis1(self, xp, dtype): - a = testing.shaped_random((2, 3, 4), xp, dtype) + a = testing.shaped_random((2, 3, 4), xp, dtype, order=self.order) return a.min(axis=1) @testing.for_all_dtypes() - @testing.numpy_cupy_allclose() + @testing.numpy_cupy_allclose(contiguous_check=False) def test_min_axis2(self, xp, dtype): - a = testing.shaped_random((2, 3, 4), xp, dtype) + a = testing.shaped_random((2, 3, 4), xp, dtype, order=self.order) return a.min(axis=2) @testing.for_all_dtypes() - @testing.numpy_cupy_allclose() + @testing.numpy_cupy_allclose(contiguous_check=False) def test_min_multiple_axes(self, xp, dtype): - a = testing.shaped_random((2, 3, 4), xp, dtype) + a = testing.shaped_random((2, 3, 4), xp, dtype, order=self.order) return a.min(axis=(1, 2)) @testing.for_all_dtypes() - @testing.numpy_cupy_allclose() + @testing.numpy_cupy_allclose(contiguous_check=False) def test_min_multiple_axes_keepdims(self, xp, dtype): - a = testing.shaped_random((2, 3, 4), xp, dtype) + a = testing.shaped_random((2, 3, 4), xp, dtype, order=self.order) return a.min(axis=(1, 2), keepdims=True) @testing.for_float_dtypes() - @testing.numpy_cupy_allclose() + @testing.numpy_cupy_allclose(contiguous_check=False) def test_min_nan(self, xp, dtype): - a = xp.array([float("nan"), 1, -1], dtype) + a = xp.array([float("nan"), 1, -1], dtype, order=self.order) return a.min() @testing.for_complex_dtypes() - @testing.numpy_cupy_allclose() + @testing.numpy_cupy_allclose(contiguous_check=False) def test_min_nan_real(self, xp, dtype): - a = xp.array([float("nan"), 1, -1], dtype) + a = xp.array([float("nan"), 1, -1], dtype, order=self.order) return a.min() @testing.for_complex_dtypes() - @testing.numpy_cupy_allclose() + @testing.numpy_cupy_allclose(contiguous_check=False) def test_min_nan_imag(self, xp, dtype): - a = xp.array([float("nan") * 1.0j, 1.0j, -1.0j], dtype) + a = xp.array( + [float("nan") * 1.0j, 1.0j, -1.0j], dtype, order=self.order + ) return a.min() # skip bool: numpy's ptp raises a TypeError on bool inputs @testing.for_all_dtypes(no_bool=True) - @testing.numpy_cupy_allclose() + @testing.numpy_cupy_allclose(contiguous_check=False) def test_ptp_all(self, xp, dtype): - a = testing.shaped_random((2, 3), xp, dtype) - return a.ptp() + a = testing.shaped_random((2, 3), xp, dtype, order=self.order) + return xp.ptp(a) @testing.with_requires("numpy>=1.15") @testing.for_all_dtypes(no_bool=True) - @testing.numpy_cupy_allclose() + @testing.numpy_cupy_allclose(contiguous_check=False) def test_ptp_all_keepdims(self, xp, dtype): - a = testing.shaped_random((2, 3), xp, dtype) - return a.ptp(keepdims=True) + a = testing.shaped_random((2, 3), xp, dtype, order=self.order) + return xp.ptp(a, keepdims=True) @testing.for_all_dtypes(no_bool=True) - @testing.numpy_cupy_allclose() + @testing.numpy_cupy_allclose(contiguous_check=False) def test_ptp_axis_large(self, xp, dtype): - a = testing.shaped_random((3, 1000), xp, dtype) - return a.ptp(axis=0) + a = testing.shaped_random((3, 1000), xp, dtype, order=self.order) + return xp.ptp(a, axis=0) @testing.for_all_dtypes(no_bool=True) - @testing.numpy_cupy_allclose() + @testing.numpy_cupy_allclose(contiguous_check=False) def test_ptp_axis0(self, xp, dtype): - a = testing.shaped_random((2, 3, 4), xp, dtype) - return a.ptp(axis=0) + a = testing.shaped_random((2, 3, 4), xp, dtype, order=self.order) + return xp.ptp(a, axis=0) @testing.for_all_dtypes(no_bool=True) - @testing.numpy_cupy_allclose() + @testing.numpy_cupy_allclose(contiguous_check=False) def test_ptp_axis1(self, xp, dtype): - a = testing.shaped_random((2, 3, 4), xp, dtype) - return a.ptp(axis=1) + a = testing.shaped_random((2, 3, 4), xp, dtype, order=self.order) + return xp.ptp(a, axis=1) @testing.for_all_dtypes(no_bool=True) - @testing.numpy_cupy_allclose() + @testing.numpy_cupy_allclose(contiguous_check=False) def test_ptp_axis2(self, xp, dtype): - a = testing.shaped_random((2, 3, 4), xp, dtype) - return a.ptp(axis=2) + a = testing.shaped_random((2, 3, 4), xp, dtype, order=self.order) + return xp.ptp(a, axis=2) @testing.with_requires("numpy>=1.15") @testing.for_all_dtypes(no_bool=True) - @testing.numpy_cupy_allclose() + @testing.numpy_cupy_allclose(contiguous_check=False) def test_ptp_multiple_axes(self, xp, dtype): - a = testing.shaped_random((2, 3, 4), xp, dtype) - return a.ptp(axis=(1, 2)) + a = testing.shaped_random((2, 3, 4), xp, dtype, order=self.order) + return xp.ptp(a, axis=(1, 2)) @testing.with_requires("numpy>=1.15") @testing.for_all_dtypes(no_bool=True) - @testing.numpy_cupy_allclose() + @testing.numpy_cupy_allclose(contiguous_check=False) def test_ptp_multiple_axes_keepdims(self, xp, dtype): - a = testing.shaped_random((2, 3, 4), xp, dtype) - return a.ptp(axis=(1, 2), keepdims=True) + a = testing.shaped_random((2, 3, 4), xp, dtype, order=self.order) + return xp.ptp(a, axis=(1, 2), keepdims=True) @testing.for_float_dtypes() - @testing.numpy_cupy_allclose() + @testing.numpy_cupy_allclose(contiguous_check=False) def test_ptp_nan(self, xp, dtype): - a = xp.array([float("nan"), 1, -1], dtype) - return a.ptp() + a = xp.array([float("nan"), 1, -1], dtype, order=self.order) + return xp.ptp(a) @testing.for_complex_dtypes() - @testing.numpy_cupy_allclose() + @testing.numpy_cupy_allclose(contiguous_check=False) def test_ptp_nan_real(self, xp, dtype): - a = xp.array([float("nan"), 1, -1], dtype) - return a.ptp() + a = xp.array([float("nan"), 1, -1], dtype, order=self.order) + return xp.ptp(a) @testing.for_complex_dtypes() - @testing.numpy_cupy_allclose() + @testing.numpy_cupy_allclose(contiguous_check=False) def test_ptp_nan_imag(self, xp, dtype): - a = xp.array([float("nan") * 1.0j, 1.0j, -1.0j], dtype) - return a.ptp() + a = xp.array( + [float("nan") * 1.0j, 1.0j, -1.0j], dtype, order=self.order + ) + return xp.ptp(a) @testing.parameterize( diff --git a/tests/third_party/cupy/creation_tests/test_matrix.py b/tests/third_party/cupy/creation_tests/test_matrix.py index 7123989d7c5..2308ecee00c 100644 --- a/tests/third_party/cupy/creation_tests/test_matrix.py +++ b/tests/third_party/cupy/creation_tests/test_matrix.py @@ -59,19 +59,16 @@ def test_diag_construction_from_tuple(self, xp): self.assertIsInstance(r, xp.ndarray) return r - @pytest.mark.usefixtures("allow_fall_back_on_numpy") def test_diag_scaler(self): for xp in (numpy, cupy): with pytest.raises(ValueError): xp.diag(1) - @pytest.mark.usefixtures("allow_fall_back_on_numpy") def test_diag_0dim(self): for xp in (numpy, cupy): with pytest.raises(ValueError): xp.diag(xp.zeros(())) - @pytest.mark.usefixtures("allow_fall_back_on_numpy") def test_diag_3dim(self): for xp in (numpy, cupy): with pytest.raises(ValueError): @@ -92,17 +89,14 @@ def test_diagflat3(self, xp): a = testing.shaped_arange((3, 3), xp) return xp.diagflat(a, -2) - @pytest.mark.skip("Scalar input is not supported") @testing.numpy_cupy_array_equal() def test_diagflat_from_scalar(self, xp): return xp.diagflat(3) - @pytest.mark.skip("Scalar input is not supported") @testing.numpy_cupy_array_equal() def test_diagflat_from_scalar_with_k0(self, xp): return xp.diagflat(3, 0) - @pytest.mark.skip("Scalar input is not supported") @testing.numpy_cupy_array_equal() def test_diagflat_from_scalar_with_k1(self, xp): return xp.diagflat(3, 1) @@ -183,3 +177,41 @@ def test_triu_nega(self, xp, dtype): def test_triu_posi(self, xp, dtype): m = testing.shaped_arange(self.shape, xp, dtype) return xp.triu(m, k=1) + + +@testing.parameterize( + *testing.product({"N": [None, 0, 1, 2, 3], "increasing": [False, True]}) +) +class TestVander(unittest.TestCase): + @testing.for_all_dtypes(no_bool=True) + @testing.numpy_cupy_allclose(type_check=False) + def test_vander(self, xp, dtype): + a = testing.shaped_arange((3,), xp, dtype=dtype) + return xp.vander(a, N=self.N, increasing=self.increasing) + + @testing.numpy_cupy_allclose() + def test_vander_array_like_list(self, xp): + a = [0, 1, 2, 3, 4, 5, 6] + return xp.vander(a, N=self.N, increasing=self.increasing) + + @testing.numpy_cupy_allclose() + def test_vander_array_like_tuple(self, xp): + a = (0, 1, 2, 3, 4, 5, 6) + return xp.vander(a, N=self.N, increasing=self.increasing) + + def test_vander_scalar(self): + for xp in (numpy, cupy): + with pytest.raises(ValueError): + xp.vander(1, N=self.N, increasing=self.increasing) + + def test_vander_0dim(self): + for xp in (numpy, cupy): + a = xp.zeros(()) + with pytest.raises(ValueError): + xp.vander(a, N=self.N, increasing=self.increasing) + + def test_vander_2dim(self): + for xp in (numpy, cupy): + m = xp.zeros((2, 2)) + with pytest.raises(ValueError): + xp.vander(m, N=self.N, increasing=self.increasing)