diff --git a/.github/workflows/conda-package.yml b/.github/workflows/conda-package.yml index 8ff31e7205e..d4754ff151c 100644 --- a/.github/workflows/conda-package.yml +++ b/.github/workflows/conda-package.yml @@ -107,7 +107,7 @@ jobs: strategy: matrix: - python: ['3.9', '3.10', '3.11', '3.12'] + python: ['3.9', '3.10', '3.11'] continue-on-error: true @@ -148,7 +148,7 @@ jobs: - name: Test conda channel run: | - mamba search ${{ env.PACKAGE_NAME }} -c ${{ env.channel-path }} --override-channels --info --json > ${{ env.ver-json-path }} + conda search ${{ env.PACKAGE_NAME }} -c ${{ env.channel-path }} --override-channels --info --json > ${{ env.ver-json-path }} cat ${{ env.ver-json-path }} - name: Get package version @@ -182,7 +182,7 @@ jobs: id: run_tests_linux uses: nick-fields/retry@7152eba30c6575329ac0576536151aca5a72780e # v3.0.0 with: - timeout_minutes: 10 + timeout_minutes: 12 max_attempts: ${{ env.RUN_TESTS_MAX_ATTEMPTS }} retry_on: any command: | @@ -193,7 +193,7 @@ jobs: python -m pytest -n auto -ra --pyargs ${{ env.PACKAGE_NAME }}.tests test_linux_all_dtypes: - name: Test ['ubuntu-latest', python='${{ matrix.python }}'] + name: Test ['ubuntu-latest-all-dtypes', python='${{ matrix.python }}'] needs: build @@ -274,7 +274,7 @@ jobs: env: DPNP_TEST_ALL_INT_TYPES: 1 run: | - pytest -n auto -ra --pyargs ${{ env.PACKAGE_NAME }}.tests + pytest -ra --pyargs ${{ env.PACKAGE_NAME }}.tests test_windows: name: Test ['windows-2019', python='${{ matrix.python }}'] @@ -289,7 +289,7 @@ jobs: strategy: matrix: - python: ['3.9', '3.10', '3.11', '3.12'] + python: ['3.9', '3.10', '3.11'] continue-on-error: true @@ -348,7 +348,7 @@ jobs: - name: Test conda channel run: | @echo on - mamba search ${{ env.PACKAGE_NAME }} -c ${{ env.channel-path }} --override-channels --info --json > ${{ env.ver-json-path }} + conda search ${{ env.PACKAGE_NAME }} -c ${{ env.channel-path }} --override-channels --info --json > ${{ env.ver-json-path }} - name: Dump version.json run: more ${{ env.ver-json-path }} @@ -409,7 +409,7 @@ jobs: python -m pytest -n auto -ra --pyargs ${{ env.PACKAGE_NAME }}.tests test_windows_all_dtypes: - name: Test ['windows-2019', python='${{ matrix.python }}'] + name: Test ['windows-2019-all-dtypes', python='${{ matrix.python }}'] needs: build diff --git a/dpnp/backend/kernels/dpnp_krnl_common.cpp b/dpnp/backend/kernels/dpnp_krnl_common.cpp index 0c25716a236..22f50986c2c 100644 --- a/dpnp/backend/kernels/dpnp_krnl_common.cpp +++ b/dpnp/backend/kernels/dpnp_krnl_common.cpp @@ -40,7 +40,7 @@ * sycl::ext::oneapi::experimental::properties was added. */ #ifndef __SYCL_COMPILER_REDUCTION_PROPERTIES_SUPPORT -#define __SYCL_COMPILER_REDUCTION_PROPERTIES_SUPPORT 20241129 +#define __SYCL_COMPILER_REDUCTION_PROPERTIES_SUPPORT 20241208L #endif namespace mkl_blas = oneapi::mkl::blas; diff --git a/dpnp/backend/kernels/elementwise_functions/i0.hpp b/dpnp/backend/kernels/elementwise_functions/i0.hpp index ddb81d88cbc..68bc41ea377 100644 --- a/dpnp/backend/kernels/elementwise_functions/i0.hpp +++ b/dpnp/backend/kernels/elementwise_functions/i0.hpp @@ -32,7 +32,7 @@ * sycl::ext::intel::math::cyl_bessel_i0(x) is fully resolved. */ #ifndef __SYCL_COMPILER_BESSEL_I0_SUPPORT -#define __SYCL_COMPILER_BESSEL_I0_SUPPORT 20241114L +#define __SYCL_COMPILER_BESSEL_I0_SUPPORT 20241208L #endif #if __SYCL_COMPILER_VERSION >= __SYCL_COMPILER_BESSEL_I0_SUPPORT diff --git a/dpnp/dpnp_iface_linearalgebra.py b/dpnp/dpnp_iface_linearalgebra.py index bb89f0769d9..588679b3468 100644 --- a/dpnp/dpnp_iface_linearalgebra.py +++ b/dpnp/dpnp_iface_linearalgebra.py @@ -37,10 +37,12 @@ """ +# pylint: disable=no-name-in-module import numpy import dpnp +from .dpnp_utils import map_dtype_to_device from .dpnp_utils.dpnp_utils_einsum import dpnp_einsum from .dpnp_utils.dpnp_utils_linearalgebra import ( dpnp_dot, @@ -64,6 +66,20 @@ ] +# TODO: implement a specific scalar-array kernel +def _call_multiply(a, b, out=None): + """Call multiply function for special cases of scalar-array dots.""" + + sc, arr = (a, b) if dpnp.isscalar(a) else (b, a) + sc_dtype = map_dtype_to_device(type(sc), arr.sycl_device) + res_dtype = dpnp.result_type(sc_dtype, arr) + if out is not None and out.dtype == arr.dtype: + res = dpnp.multiply(a, b, out=out) + else: + res = dpnp.multiply(a, b, dtype=res_dtype) + return dpnp.get_result_array(res, out, casting="no") + + def dot(a, b, out=None): """ Dot product of `a` and `b`. @@ -137,8 +153,7 @@ def dot(a, b, out=None): raise ValueError("Only C-contiguous array is acceptable.") if dpnp.isscalar(a) or dpnp.isscalar(b): - # TODO: use specific scalar-vector kernel - return dpnp.multiply(a, b, out=out) + return _call_multiply(a, b, out=out) a_ndim = a.ndim b_ndim = b.ndim @@ -627,8 +642,7 @@ def inner(a, b): dpnp.check_supported_arrays_type(a, b, scalar_type=True) if dpnp.isscalar(a) or dpnp.isscalar(b): - # TODO: use specific scalar-vector kernel - return dpnp.multiply(a, b) + return _call_multiply(a, b) if a.ndim == 0 or b.ndim == 0: # TODO: use specific scalar-vector kernel @@ -706,8 +720,7 @@ def kron(a, b): dpnp.check_supported_arrays_type(a, b, scalar_type=True) if dpnp.isscalar(a) or dpnp.isscalar(b): - # TODO: use specific scalar-vector kernel - return dpnp.multiply(a, b) + return _call_multiply(a, b) a_ndim = a.ndim b_ndim = b.ndim @@ -1043,8 +1056,7 @@ def tensordot(a, b, axes=2): raise ValueError( "One of the inputs is scalar, axes should be zero." ) - # TODO: use specific scalar-vector kernel - return dpnp.multiply(a, b) + return _call_multiply(a, b) return dpnp_tensordot(a, b, axes=axes) @@ -1107,13 +1119,13 @@ def vdot(a, b): if b.size != 1: raise ValueError("The second array should be of size one.") a_conj = numpy.conj(a) - return dpnp.multiply(a_conj, b) + return _call_multiply(a_conj, b) if dpnp.isscalar(b): if a.size != 1: raise ValueError("The first array should be of size one.") a_conj = dpnp.conj(a) - return dpnp.multiply(a_conj, b) + return _call_multiply(a_conj, b) if a.ndim == 1 and b.ndim == 1: return dpnp_dot(a, b, out=None, conjugate=True) diff --git a/dpnp/dpnp_iface_nanfunctions.py b/dpnp/dpnp_iface_nanfunctions.py index a808617469f..950e86b9d51 100644 --- a/dpnp/dpnp_iface_nanfunctions.py +++ b/dpnp/dpnp_iface_nanfunctions.py @@ -987,7 +987,7 @@ def nanstd( ddof : {int, float}, optional Means Delta Degrees of Freedom. The divisor used in calculations is ``N - ddof``, where ``N`` the number of non-NaN elements. - Default: `0.0`. + Default: ``0.0``. keepdims : {None, bool}, optional If ``True``, the reduced axes (dimensions) are included in the result as singleton dimensions, so that the returned array remains @@ -1087,7 +1087,7 @@ def nanvar( ddof : {int, float}, optional Means Delta Degrees of Freedom. The divisor used in calculations is ``N - ddof``, where ``N`` represents the number of non-NaN elements. - Default: `0.0`. + Default: ``0.0``. keepdims : {None, bool}, optional If ``True``, the reduced axes (dimensions) are included in the result as singleton dimensions, so that the returned array remains diff --git a/dpnp/fft/dpnp_utils_fft.py b/dpnp/fft/dpnp_utils_fft.py index e2855acd60c..43d46763f50 100644 --- a/dpnp/fft/dpnp_utils_fft.py +++ b/dpnp/fft/dpnp_utils_fft.py @@ -282,7 +282,10 @@ def _copy_array(x, complex_input): # r2c FFT, if input is integer or float16 dtype, convert to # float32 or float64 depending on device capabilities copy_flag = True - dtype = map_dtype_to_device(dpnp.float64, x.sycl_device) + if dtype == dpnp.float16: + dtype = dpnp.float32 + else: + dtype = map_dtype_to_device(dpnp.float64, x.sycl_device) if copy_flag: x_copy = dpnp.empty_like(x, dtype=dtype, order="C") diff --git a/dpnp/tests/helper.py b/dpnp/tests/helper.py index 44945dc4c8b..1ffa208227c 100644 --- a/dpnp/tests/helper.py +++ b/dpnp/tests/helper.py @@ -85,24 +85,19 @@ def assert_dtype_allclose( assert dpnp_arr.dtype == numpy_arr.dtype -def get_integer_dtypes(): +def get_integer_dtypes(no_unsigned=False): """ Build a list of integer types supported by DPNP. """ + dtypes = [dpnp.int32, dpnp.int64] + if config.all_int_types: - return [ - dpnp.int8, - dpnp.int16, - dpnp.int32, - dpnp.int64, - dpnp.uint8, - dpnp.uint16, - dpnp.uint32, - dpnp.uint64, - ] + dtypes += [dpnp.int8, dpnp.int16] + if not no_unsigned: + dtypes += [dpnp.uint8, dpnp.uint16, dpnp.uint32, dpnp.uint64] - return [dpnp.int32, dpnp.int64] + return dtypes def get_complex_dtypes(device=None): @@ -147,17 +142,25 @@ def get_float_complex_dtypes(no_float16=True, device=None): return dtypes +def get_abs_array(data, dtype=None): + if numpy.issubdtype(dtype, numpy.unsignedinteger): + data = numpy.abs(data) + return numpy.array(data, dtype=dtype) + + def get_all_dtypes( no_bool=False, no_float16=True, no_complex=False, no_none=False, - device=None, xfail_dtypes=None, exclude=None, + no_unsigned=False, + device=None, ): """ - Build a list of types supported by DPNP based on input flags and device capabilities. + Build a list of types supported by DPNP based on + input flags and device capabilities. """ dev = dpctl.select_default_device() if device is None else device @@ -166,7 +169,7 @@ def get_all_dtypes( dtypes = [dpnp.bool] if not no_bool else [] # add integer types - dtypes.extend(get_integer_dtypes()) + dtypes.extend(get_integer_dtypes(no_unsigned=no_unsigned)) # add floating types dtypes.extend(get_float_dtypes(no_float16=no_float16, device=dev)) @@ -194,7 +197,13 @@ def not_excluded(dtype): def generate_random_numpy_array( - shape, dtype=None, hermitian=False, seed_value=None, low=-10, high=10 + shape, + dtype=None, + order="C", + hermitian=False, + seed_value=None, + low=-10, + high=10, ): """ Generate a random numpy array with the specified shape and dtype. @@ -210,6 +219,9 @@ def generate_random_numpy_array( Desired data-type for the output array. If not specified, data type will be determined by numpy. Default : ``None`` + order : {"C", "F"}, optional + Specify the memory layout of the output array. + Default: ``"C"``. hermitian : bool, optional If True, generates a Hermitian (symmetric if `dtype` is real) matrix. Default : ``False`` @@ -226,7 +238,7 @@ def generate_random_numpy_array( Returns ------- out : numpy.ndarray - A random numpy array of the specified shape and dtype. + A random numpy array of the specified shape, dtype and memory layout. The array is Hermitian or symmetric if `hermitian` is True. Note: @@ -239,10 +251,13 @@ def generate_random_numpy_array( seed_value = 42 numpy.random.seed(seed_value) + if numpy.issubdtype(dtype, numpy.unsignedinteger): + low = 0 + # dtype=int is needed for 0d arrays size = numpy.prod(shape, dtype=int) a = numpy.random.uniform(low, high, size).astype(dtype) - if numpy.issubdtype(a.dtype, numpy.complexfloating): + if numpy.issubdtype(dtype, numpy.complexfloating): a += 1j * numpy.random.uniform(low, high, size) a = a.reshape(shape) @@ -256,6 +271,10 @@ def generate_random_numpy_array( a = a.reshape(orig_shape) else: a = numpy.conj(a.T) @ a + + # a.reshape(shape) returns an array in C order by default + if order != "C" and a.ndim > 1: + a = numpy.array(a, order=order) return a diff --git a/dpnp/tests/test_amin_amax.py b/dpnp/tests/test_amin_amax.py index 1b119ab225b..35f45cd4082 100644 --- a/dpnp/tests/test_amin_amax.py +++ b/dpnp/tests/test_amin_amax.py @@ -4,21 +4,19 @@ import dpnp -from .helper import get_all_dtypes +from .helper import get_abs_array, get_all_dtypes @pytest.mark.parametrize("func", ["amax", "amin"]) @pytest.mark.parametrize("keepdims", [True, False]) @pytest.mark.parametrize("dtype", get_all_dtypes()) def test_amax_amin(func, keepdims, dtype): - a = numpy.array( - [ - [[-2.0, 3.0], [9.1, 0.2]], - [[-2.0, 5.0], [-2, -1.2]], - [[1.0, -2.0], [5.0, -1.1]], - ], - dtype=dtype, - ) + a = [ + [[-2.0, 3.0], [9.1, 0.2]], + [[-2.0, 5.0], [-2, -1.2]], + [[1.0, -2.0], [5.0, -1.1]], + ] + a = get_abs_array(a, dtype) ia = dpnp.array(a) for axis in range(len(a)): @@ -28,20 +26,20 @@ def test_amax_amin(func, keepdims, dtype): def _get_min_max_input(type, shape): - size = 1 - for i in range(len(shape)): - size *= shape[i] - + size = numpy.prod(shape) a = numpy.arange(size, dtype=type) - a[int(size / 2)] = size * size - a[int(size / 3)] = -(size * size) + a[int(size / 2)] = size + 5 + if numpy.issubdtype(type, numpy.unsignedinteger): + a[int(size / 3)] = size + else: + a[int(size / 3)] = -(size + 5) return a.reshape(shape) @pytest.mark.parametrize("dtype", get_all_dtypes(no_bool=True)) @pytest.mark.parametrize( - "shape", [(4,), (2, 3), (4, 5, 6)], ids=["(4,)", "(2,3)", "(4,5,6)"] + "shape", [(4,), (2, 3), (4, 5, 6)], ids=["(4,)", "(2, 3)", "(4, 5, 6)"] ) def test_amax_diff_shape(dtype, shape): a = _get_min_max_input(dtype, shape) @@ -59,7 +57,7 @@ def test_amax_diff_shape(dtype, shape): @pytest.mark.parametrize("dtype", get_all_dtypes(no_bool=True)) @pytest.mark.parametrize( - "shape", [(4,), (2, 3), (4, 5, 6)], ids=["(4,)", "(2,3)", "(4,5,6)"] + "shape", [(4,), (2, 3), (4, 5, 6)], ids=["(4,)", "(2, 3)", "(4, 5, 6)"] ) def test_amin_diff_shape(dtype, shape): a = _get_min_max_input(dtype, shape) diff --git a/dpnp/tests/test_arraycreation.py b/dpnp/tests/test_arraycreation.py index 445c348a95d..1b4d97de624 100644 --- a/dpnp/tests/test_arraycreation.py +++ b/dpnp/tests/test_arraycreation.py @@ -14,10 +14,7 @@ import dpnp -from .helper import ( - assert_dtype_allclose, - get_all_dtypes, -) +from .helper import assert_dtype_allclose, get_all_dtypes from .third_party.cupy import testing @@ -176,16 +173,18 @@ def test_exception_subok(func, args): @pytest.mark.parametrize("start", [0, -5, 10, -2.5, 9.7]) -@pytest.mark.parametrize("stop", [None, 10, -2, 20.5, 1000]) -@pytest.mark.parametrize("step", [None, 1, 2.7, -1.6, 100]) +@pytest.mark.parametrize("stop", [None, 10, -2, 20.5, 100]) +@pytest.mark.parametrize("step", [None, 1, 2.7, -1.6, 80]) @pytest.mark.parametrize( "dtype", get_all_dtypes(no_bool=True, no_float16=False) ) def test_arange(start, stop, step, dtype): - rtol_mult = 2 - if dpnp.issubdtype(dtype, dpnp.float16): - # numpy casts to float32 type when computes float16 data - rtol_mult = 4 + if numpy.issubdtype(dtype, numpy.unsignedinteger): + start = abs(start) + stop = abs(stop) if stop else None + + # numpy casts to float32 type when computes float16 data + rtol_mult = 4 if dpnp.issubdtype(dtype, dpnp.float16) else 2 func = lambda xp: xp.arange(start, stop=stop, step=step, dtype=dtype) @@ -701,7 +700,7 @@ def test_dpctl_tensor_input(func, args): @pytest.mark.parametrize("start", [0, -5, 10, -2.5, 9.7]) -@pytest.mark.parametrize("stop", [0, 10, -2, 20.5, 1000]) +@pytest.mark.parametrize("stop", [0, 10, -2, 20.5, 120]) @pytest.mark.parametrize( "num", [1, 5, numpy.array(10), dpnp.array(17), dpt.asarray(100)], @@ -850,7 +849,7 @@ def test_space_num_error(): @pytest.mark.parametrize("endpoint", [True, False]) def test_geomspace(sign, dtype, num, endpoint): start = 2 * sign - stop = 256 * sign + stop = 127 * sign func = lambda xp: xp.geomspace( start, stop, num, endpoint=endpoint, dtype=dtype diff --git a/dpnp/tests/test_bitwise.py b/dpnp/tests/test_bitwise.py index 41f10c02354..33e327218d4 100644 --- a/dpnp/tests/test_bitwise.py +++ b/dpnp/tests/test_bitwise.py @@ -167,7 +167,8 @@ def test_bitwise_aliase2(self, lhs, rhs, dtype): @pytest.mark.parametrize("dtype", get_integer_dtypes()) def test_invert_out(dtype): - np_a = numpy.arange(-5, 5, dtype=dtype) + low = 0 if numpy.issubdtype(dtype, numpy.unsignedinteger) else -5 + np_a = numpy.arange(low, 5, dtype=dtype) dp_a = inp.array(np_a) expected = numpy.invert(np_a) diff --git a/dpnp/tests/test_fft.py b/dpnp/tests/test_fft.py index 8915daa43e2..33f81a7394d 100644 --- a/dpnp/tests/test_fft.py +++ b/dpnp/tests/test_fft.py @@ -380,7 +380,7 @@ def setup_method(self): @pytest.mark.parametrize("norm", [None, "forward", "backward", "ortho"]) @pytest.mark.parametrize("order", ["C", "F"]) def test_fft2(self, dtype, axes, norm, order): - a_np = generate_random_numpy_array((2, 3, 4), dtype) + a_np = generate_random_numpy_array((2, 3, 4), dtype, order) a = dpnp.array(a_np) result = dpnp.fft.fft2(a, axes=axes, norm=norm) @@ -442,7 +442,7 @@ def setup_method(self): @pytest.mark.parametrize("norm", [None, "backward", "forward", "ortho"]) @pytest.mark.parametrize("order", ["C", "F"]) def test_fftn(self, dtype, axes, norm, order): - a_np = generate_random_numpy_array((2, 3, 4, 5), dtype) + a_np = generate_random_numpy_array((2, 3, 4, 5), dtype, order) a = dpnp.array(a_np) result = dpnp.fft.fftn(a, axes=axes, norm=norm) @@ -696,8 +696,7 @@ def test_irfft_1D_on_2D_array(self, dtype, n, axis, norm, order): @pytest.mark.parametrize("norm", [None, "backward", "forward", "ortho"]) @pytest.mark.parametrize("order", ["C", "F"]) def test_irfft_1D_on_3D_array(self, dtype, n, axis, norm, order): - x = generate_random_numpy_array((4, 5, 6), dtype) - a_np = numpy.array(x, order=order) + a_np = generate_random_numpy_array((4, 5, 6), dtype, order) # each 1-D array of input should be Hermitian if axis == 0: a_np[0].imag = 0 @@ -816,7 +815,10 @@ def test_rfft_1D(self, dtype, n, norm): result = dpnp.fft.rfft(a, n=n, norm=norm) expected = numpy.fft.rfft(a_np, n=n, norm=norm) - assert_dtype_allclose(result, expected, check_only_type_kind=True) + factor = 120 if dtype in [dpnp.int8, dpnp.uint8] else 8 + assert_dtype_allclose( + result, expected, factor=factor, check_only_type_kind=True + ) @pytest.mark.parametrize("n", [None, 5, 20]) @pytest.mark.parametrize("norm", [None, "backward", "forward", "ortho"]) @@ -934,8 +936,7 @@ def setup_method(self): @pytest.mark.parametrize("norm", [None, "backward", "forward", "ortho"]) @pytest.mark.parametrize("order", ["C", "F"]) def test_rfft2(self, dtype, axes, norm, order): - x = generate_random_numpy_array((2, 3, 4), dtype) - a_np = numpy.array(x, order=order) + a_np = generate_random_numpy_array((2, 3, 4), dtype, order) a = dpnp.asarray(a_np) result = dpnp.fft.rfft2(a, axes=axes, norm=norm) @@ -999,8 +1000,7 @@ def setup_method(self): @pytest.mark.parametrize("norm", [None, "backward", "forward", "ortho"]) @pytest.mark.parametrize("order", ["C", "F"]) def test_rfftn(self, dtype, axes, norm, order): - x = generate_random_numpy_array((2, 3, 4, 5), dtype) - a_np = numpy.array(x, order=order) + a_np = generate_random_numpy_array((2, 3, 4, 5), dtype, order) a = dpnp.asarray(a_np) result = dpnp.fft.rfftn(a, axes=axes, norm=norm) diff --git a/dpnp/tests/test_histogram.py b/dpnp/tests/test_histogram.py index 6a4e8abceb6..3a87fc2402f 100644 --- a/dpnp/tests/test_histogram.py +++ b/dpnp/tests/test_histogram.py @@ -14,6 +14,7 @@ from .helper import ( assert_dtype_allclose, + get_abs_array, get_all_dtypes, get_float_dtypes, get_integer_dtypes, @@ -44,7 +45,12 @@ class TestDigitize: ], ) def test_digitize(self, x, bins, dtype, right): - x = x.astype(dtype) + x = get_abs_array(x, dtype) + if numpy.issubdtype(dtype, numpy.unsignedinteger): + min_bin = bins.min() + if min_bin < 0: + # bins should be monotonically increasing, cannot use get_abs_array + bins -= min_bin bins = bins.astype(dtype) x_dp = dpnp.array(x) bins_dp = dpnp.array(bins) @@ -527,18 +533,27 @@ def test_rand_data(self, dtype): v = numpy.random.randint(0, upper_bound, size=n, dtype=dtype) iv = dpnp.array(v) - expected_hist = numpy.bincount(v) - result_hist = dpnp.bincount(iv) - assert_array_equal(result_hist, expected_hist) + if numpy.issubdtype(dtype, numpy.uint64): + # discussed in numpy issue 17760 + assert_raises(TypeError, numpy.bincount, v) + assert_raises(ValueError, dpnp.bincount, iv) + else: + expected_hist = numpy.bincount(v) + result_hist = dpnp.bincount(iv) + assert_array_equal(result_hist, expected_hist) @pytest.mark.parametrize("dtype", get_integer_dtypes()) def test_arange_data(self, dtype): v = numpy.arange(100).astype(dtype) iv = dpnp.array(v) - expected_hist = numpy.bincount(v) - result_hist = dpnp.bincount(iv) - assert_array_equal(result_hist, expected_hist) + if numpy.issubdtype(dtype, numpy.uint64): + assert_raises(TypeError, numpy.bincount, v) + assert_raises(ValueError, dpnp.bincount, iv) + else: + expected_hist = numpy.bincount(v) + result_hist = dpnp.bincount(iv) + assert_array_equal(result_hist, expected_hist) @pytest.mark.parametrize("xp", [numpy, dpnp]) def test_negative_values(self, xp): diff --git a/dpnp/tests/test_indexing.py b/dpnp/tests/test_indexing.py index 61b91015461..02c6ff15a49 100644 --- a/dpnp/tests/test_indexing.py +++ b/dpnp/tests/test_indexing.py @@ -17,7 +17,14 @@ import dpnp from dpnp.dpnp_array import dpnp_array -from .helper import get_all_dtypes, get_integer_dtypes, has_support_aspect64 +from .helper import ( + get_abs_array, + get_all_dtypes, + get_integer_dtypes, + has_support_aspect64, + is_win_platform, + numpy_version, +) from .third_party.cupy import testing @@ -43,12 +50,12 @@ class TestDiagonal: "shape", [(2, 2), (3, 3), (2, 5), (3, 2, 2), (2, 2, 2, 2), (2, 2, 2, 3)], ids=[ - "(2,2)", - "(3,3)", - "(2,5)", - "(3,2,2)", - "(2,2,2,2)", - "(2,2,2,3)", + "(2, 2)", + "(3, 3)", + "(2, 5)", + "(3, 2, 2)", + "(2, 2, 2, 2)", + "(2, 2, 2, 3)", ], ) def test_diagonal_offset(self, shape, dtype, offset): @@ -122,8 +129,8 @@ def test_extract(self, dt): @pytest.mark.parametrize("a_dt", get_all_dtypes(no_none=True)) @pytest.mark.parametrize("cond_dt", get_all_dtypes(no_none=True)) def test_extract_diff_dtypes(self, a_dt, cond_dt): - a = numpy.array([-2, -1, 0, 1, 2, 3], dtype=a_dt) - cond = numpy.array([1, -1, 2, 0, -2, 3], dtype=cond_dt) + a = get_abs_array([-2, -1, 0, 1, 2, 3], a_dt) + cond = get_abs_array([1, -1, 2, 0, -2, 3], cond_dt) ia, icond = dpnp.array(a), dpnp.array(cond) result = dpnp.extract(icond, ia) @@ -132,7 +139,7 @@ def test_extract_diff_dtypes(self, a_dt, cond_dt): @pytest.mark.parametrize("a_dt", get_all_dtypes(no_none=True)) def test_extract_list_cond(self, a_dt): - a = numpy.array([-2, -1, 0, 1, 2, 3], dtype=a_dt) + a = get_abs_array([-2, -1, 0, 1, 2, 3], a_dt) cond = [1, -1, 2, 0, -2, 3] ia = dpnp.array(a) @@ -165,7 +172,7 @@ def test_place_diff_dtypes(self, a_dt, mask_dt, vals_dt): dtype=mask_dt, ) vals = numpy.array( - [100, 200, 300, 400, 500, 600, 800, 900], dtype=vals_dt + [101, 102, 103, 104, 105, 106, 108, 109], dtype=vals_dt ) ia, imask, ivals = dpnp.array(a), dpnp.array(mask), dpnp.array(vals) @@ -385,7 +392,7 @@ def test_0d(self, val): @pytest.mark.parametrize("dtype", get_all_dtypes(no_none=True)) def test_1d(self, dtype): - a = numpy.array([1, 0, 2, -1, 0, 0, 8], dtype=dtype) + a = get_abs_array([1, 0, 2, -1, 0, 0, 8], dtype) ia = dpnp.array(a) np_res = numpy.nonzero(a) @@ -437,22 +444,22 @@ def test_array_method(self, dtype): class TestPut: @pytest.mark.parametrize("a_dt", get_all_dtypes(no_none=True)) @pytest.mark.parametrize( - "indices", [[0, 2], [-5, 4]], ids=["[0, 2]", "[-5, 4]"] + "indices", [[0, 2], [-3, 4]], ids=["[0, 2]", "[-3, 4]"] ) @pytest.mark.parametrize("ind_dt", get_all_dtypes(no_none=True)) @pytest.mark.parametrize( "vals", [0, [1, 2], (2, 2), dpnp.array([1, 2])], - ids=["0", "[1, 2]", "(2, 2)", "dpnp.array([1,2])"], + ids=["0", "[1, 2]", "(2, 2)", "dpnp.array([1, 2])"], ) @pytest.mark.parametrize("mode", ["clip", "wrap"]) def test_input_1d(self, a_dt, indices, ind_dt, vals, mode): - a = numpy.array([-2, -1, 0, 1, 2], dtype=a_dt) + a = get_abs_array([-2, -1, 0, 1, 2], a_dt) b = numpy.copy(a) ia = dpnp.array(a) ib = dpnp.array(b) - ind = numpy.array(indices, dtype=ind_dt) + ind = get_abs_array(indices, ind_dt) if ind_dt == dpnp.bool and ind.all(): ind[0] = False # to get rid of duplicate indices iind = dpnp.array(ind) @@ -465,6 +472,18 @@ def test_input_1d(self, a_dt, indices, ind_dt, vals, mode): b.put(ind, vals, mode=mode) ib.put(iind, vals, mode=mode) assert_array_equal(ib, b) + elif numpy.issubdtype(ind_dt, numpy.uint64): + # For this special case, NumPy raises an error but dpnp works + assert_raises(TypeError, numpy.put, a, ind, vals, mode=mode) + assert_raises(TypeError, b.put, ind, vals, mode=mode) + + numpy.put(a, ind.astype(numpy.int64), vals, mode=mode) + dpnp.put(ia, iind, vals, mode=mode) + assert_array_equal(ia, a) + + b.put(ind.astype(numpy.int64), vals, mode=mode) + ib.put(iind, vals, mode=mode) + assert_array_equal(ib, b) else: assert_raises(TypeError, numpy.put, a, ind, vals, mode=mode) assert_raises(TypeError, dpnp.put, ia, iind, vals, mode=mode) @@ -475,30 +494,30 @@ def test_input_1d(self, a_dt, indices, ind_dt, vals, mode): @pytest.mark.parametrize("a_dt", get_all_dtypes(no_none=True)) @pytest.mark.parametrize( "indices", - [ - [0, 7], - [3, 4], - [-9, 8], - ], - ids=[ - "[0, 7]", - "[3, 4]", - "[-9, 8]", - ], + [[0, 7], [3, 4], [-7, 8]], + ids=["[0, 7]", "[3, 4]", "[-7, 8]"], ) @pytest.mark.parametrize("ind_dt", get_integer_dtypes()) - @pytest.mark.parametrize("vals", [[10, 20]], ids=["[10, 20]"]) @pytest.mark.parametrize("mode", ["clip", "wrap"]) - def test_input_2d(self, a_dt, indices, ind_dt, vals, mode): - a = numpy.array([[-1, 0, 1], [-2, -3, -4], [2, 3, 4]], dtype=a_dt) + def test_input_2d(self, a_dt, indices, ind_dt, mode): + a = get_abs_array([[-1, 0, 1], [-2, -3, -4], [2, 3, 4]], a_dt) ia = dpnp.array(a) + vals = [10, 20] - ind = numpy.array(indices, dtype=ind_dt) + ind = get_abs_array(indices, ind_dt) iind = dpnp.array(ind) - numpy.put(a, ind, vals, mode=mode) - dpnp.put(ia, iind, vals, mode=mode) - assert_array_equal(ia, a) + if numpy.issubdtype(ind_dt, numpy.uint64): + # For this special case, NumPy raises an error but dpnp works + assert_raises(TypeError, numpy.put, a, ind, vals, mode=mode) + + numpy.put(a, ind.astype(numpy.int64), vals, mode=mode) + dpnp.put(ia, iind, vals, mode=mode) + assert_array_equal(ia, a) + else: + numpy.put(a, ind, vals, mode=mode) + dpnp.put(ia, iind, vals, mode=mode) + assert_array_equal(ia, a) def test_indices_2d(self): a = numpy.arange(5) @@ -536,17 +555,7 @@ def test_empty_input(self, mode): with pytest.raises(IndexError): empty.put(1, 1, mode=mode) - @pytest.mark.parametrize( - "shape", - [ - (3,), - (4,), - ], - ids=[ - "(3,)", - "(4,)", - ], - ) + @pytest.mark.parametrize("shape", [(3,), (4,)], ids=["(3,)", "(4,)"]) @pytest.mark.parametrize("mode", ["clip", "wrap"]) def test_invalid_shape(self, shape, mode): a = dpnp.arange(7) @@ -558,17 +567,7 @@ def test_invalid_shape(self, shape, mode): @pytest.mark.parametrize("xp", [dpnp, numpy]) @pytest.mark.parametrize( - "axis", - [ - 1.0, - (0,), - [0, 1], - ], - ids=[ - "1.0", - "(0,)", - "[0, 1]", - ], + "axis", [1.0, (0,), [0, 1]], ids=["1.0", "(0,)", "[0, 1]"] ) def test_invalid_axis(self, xp, axis): a = xp.arange(6).reshape(2, 3) @@ -599,7 +598,8 @@ def test_replace_max(self, arr_dt, axis): # replace the max with a small value i_max = _add_keepdims(dpnp.argmax)(a, axis=axis) - dpnp.put_along_axis(a, i_max, -99, axis=axis) + val = 0 if numpy.issubdtype(arr_dt, numpy.unsignedinteger) else -99 + dpnp.put_along_axis(a, i_max, val, axis=axis) # find the new minimum, which should max i_min = _add_keepdims(dpnp.argmin)(a, axis=axis) @@ -613,8 +613,8 @@ def test_replace_max(self, arr_dt, axis): @pytest.mark.parametrize( "values", [ - 777, - [100, 200, 300, 400], + 77, + [101, 102, 103, 104], (42,), range(4), numpy.arange(4), @@ -655,9 +655,10 @@ def test_broadcast(self, arr_dt, idx_dt): ind = numpy.arange(10, dtype=idx_dt).reshape((1, 2, 5)) % 4 ia, iind = dpnp.array(a), dpnp.array(ind) - numpy.put_along_axis(a, ind, 20, axis=1) - dpnp.put_along_axis(ia, iind, 20, axis=1) - assert_array_equal(ia, a) + if numpy.issubdtype(idx_dt, numpy.uint64): + numpy.put_along_axis(a, ind, 20, axis=1) + dpnp.put_along_axis(ia, iind, 20, axis=1) + assert_array_equal(ia, a) def test_mode_wrap(self): a = numpy.array([-2, -1, 0, 1, 2]) @@ -687,18 +688,27 @@ class TestTake: @pytest.mark.parametrize("a_dt", get_all_dtypes(no_none=True)) @pytest.mark.parametrize("ind_dt", get_all_dtypes(no_none=True)) @pytest.mark.parametrize( - "indices", [[-2, 2], [-5, 4]], ids=["[-2, 2]", "[-5, 4]"] + "indices", [[-2, 2], [-4, 4]], ids=["[-2, 2]", "[-4, 4]"] ) @pytest.mark.parametrize("mode", ["clip", "wrap"]) def test_1d(self, a_dt, ind_dt, indices, mode): - a = numpy.array([-2, -1, 0, 1, 2], dtype=a_dt) - ind = numpy.array(indices, dtype=ind_dt) + a = get_abs_array([-2, -1, 0, 1, 2], a_dt) + ind = get_abs_array(indices, ind_dt) ia, iind = dpnp.array(a), dpnp.array(ind) if numpy.can_cast(ind_dt, numpy.intp, casting="safe"): result = dpnp.take(ia, iind, mode=mode) expected = numpy.take(a, ind, mode=mode) assert_array_equal(result, expected) + elif numpy.issubdtype(ind_dt, numpy.uint64): + # For this special case, although casting `ind_dt` to numpy.intp + # is not safe, both NumPy and dpnp work properly + # NumPy < "2.2.0" raises an error + if numpy_version() < "2.2.0": + ind = ind.astype(numpy.int64) + result = dpnp.take(ia, iind, mode=mode) + expected = numpy.take(a, ind, mode=mode) + assert_array_equal(result, expected) else: assert_raises(TypeError, ia.take, iind, mode=mode) assert_raises(TypeError, a.take, ind, mode=mode) @@ -706,28 +716,34 @@ def test_1d(self, a_dt, ind_dt, indices, mode): @pytest.mark.parametrize("a_dt", get_all_dtypes(no_none=True)) @pytest.mark.parametrize("ind_dt", get_integer_dtypes()) @pytest.mark.parametrize( - "indices", [[-1, 0], [-3, 2]], ids=["[-1, 0]", "[-3, 2]"] + "indices", [[-1, 0], [-2, 2]], ids=["[-1, 0]", "[-2, 2]"] ) @pytest.mark.parametrize("mode", ["clip", "wrap"]) - @pytest.mark.parametrize("axis", [0, 1], ids=["0", "1"]) + @pytest.mark.parametrize("axis", [0, 1]) def test_2d(self, a_dt, ind_dt, indices, mode, axis): - a = numpy.array([[-1, 0, 1], [-2, -3, -4], [2, 3, 4]], dtype=a_dt) - ind = numpy.array(indices, dtype=ind_dt) + a = get_abs_array([[-1, 0, 1], [-2, -3, -4], [2, 3, 4]], a_dt) + ind = get_abs_array(indices, ind_dt) ia, iind = dpnp.array(a), dpnp.array(ind) - result = ia.take(iind, axis=axis, mode=mode) - expected = a.take(ind, axis=axis, mode=mode) - assert_array_equal(result, expected) + if numpy.issubdtype(ind_dt, numpy.uint64): + # For this special case, NumPy raises an error on Windows + result = ia.take(iind, axis=axis, mode=mode) + expected = a.take(ind.astype(numpy.int64), axis=axis, mode=mode) + assert_array_equal(result, expected) + else: + result = ia.take(iind, axis=axis, mode=mode) + expected = a.take(ind, axis=axis, mode=mode) + assert_array_equal(result, expected) @pytest.mark.parametrize("a_dt", get_all_dtypes(no_none=True)) - @pytest.mark.parametrize("indices", [[-5, 5]], ids=["[-5, 5]"]) @pytest.mark.parametrize("mode", ["clip", "wrap"]) - def test_over_index(self, a_dt, indices, mode): - a = dpnp.array([-2, -1, 0, 1, 2], dtype=a_dt) - ind = dpnp.array(indices, dtype=numpy.intp) + def test_over_index(self, a_dt, mode): + a = get_abs_array([-2, -1, 0, 1, 2], a_dt) + a = dpnp.array(a) + ind = dpnp.array([-5, 5], dtype=numpy.intp) result = dpnp.take(a, ind, mode=mode) - expected = dpnp.array([-2, 2], dtype=a.dtype) + expected = get_abs_array([-2, 2], a_dt) assert_array_equal(result, expected) @pytest.mark.parametrize("xp", [numpy, dpnp]) @@ -887,7 +903,7 @@ def test_choose(): assert_array_equal(expected, result) -@pytest.mark.parametrize("val", [-1, 0, 1], ids=["-1", "0", "1"]) +@pytest.mark.parametrize("val", [-1, 0, 1]) @pytest.mark.parametrize( "array", [ @@ -936,7 +952,7 @@ def test_fill_diagonal(array, val): ], ) @pytest.mark.parametrize("dtype", get_all_dtypes(no_bool=True)) -@pytest.mark.parametrize("sparse", [True, False], ids=["True", "False"]) +@pytest.mark.parametrize("sparse", [True, False]) def test_indices(dimension, dtype, sparse): expected = numpy.indices(dimension, dtype=dtype, sparse=sparse) result = dpnp.indices(dimension, dtype=dtype, sparse=sparse) @@ -944,7 +960,6 @@ def test_indices(dimension, dtype, sparse): assert_array_equal(Xnp, X) -@pytest.mark.parametrize("vals", [[100, 200]], ids=["[100, 200]"]) @pytest.mark.parametrize( "mask", [ @@ -963,12 +978,12 @@ def test_indices(dimension, dtype, sparse): [[[0, 0], [0, 0]], [[1, 2], [1, 2]], [[1, 2], [3, 4]]], ids=["[[0, 0], [0, 0]]", "[[1, 2], [1, 2]]", "[[1, 2], [3, 4]]"], ) -def test_putmask1(arr, mask, vals): +def test_putmask1(arr, mask): a = numpy.array(arr) ia = dpnp.array(a) m = numpy.array(mask) im = dpnp.array(m) - v = numpy.array(vals) + v = numpy.array([100, 200]) iv = dpnp.array(v) numpy.putmask(a, m, v) dpnp.putmask(ia, im, iv) @@ -1067,24 +1082,16 @@ def test_putmask3(arr, mask, vals): assert_array_equal(a, ia) -@pytest.mark.parametrize( - "m", [None, 0, 1, 2, 3, 4], ids=["None", "0", "1", "2", "3", "4"] -) -@pytest.mark.parametrize( - "k", [-3, -2, -1, 0, 1, 2, 3], ids=["-3", "-2", "-1", "0", "1", "2", "3"] -) -@pytest.mark.parametrize( - "n", [1, 2, 3, 4, 5, 6], ids=["1", "2", "3", "4", "5", "6"] -) +@pytest.mark.parametrize("m", [None, 0, 1, 2, 3, 4]) +@pytest.mark.parametrize("k", [-3, -2, -1, 0, 1, 2, 3]) +@pytest.mark.parametrize("n", [1, 2, 3, 4, 5, 6]) def test_tril_indices(n, k, m): result = dpnp.tril_indices(n, k, m) expected = numpy.tril_indices(n, k, m) assert_array_equal(expected, result) -@pytest.mark.parametrize( - "k", [-3, -2, -1, 0, 1, 2, 3], ids=["-3", "-2", "-1", "0", "1", "2", "3"] -) +@pytest.mark.parametrize("k", [-3, -2, -1, 0, 1, 2, 3]) @pytest.mark.parametrize( "array", [ @@ -1102,24 +1109,16 @@ def test_tril_indices_from(array, k): assert_array_equal(expected, result) -@pytest.mark.parametrize( - "m", [None, 0, 1, 2, 3, 4], ids=["None", "0", "1", "2", "3", "4"] -) -@pytest.mark.parametrize( - "k", [-3, -2, -1, 0, 1, 2, 3], ids=["-3", "-2", "-1", "0", "1", "2", "3"] -) -@pytest.mark.parametrize( - "n", [1, 2, 3, 4, 5, 6], ids=["1", "2", "3", "4", "5", "6"] -) +@pytest.mark.parametrize("m", [None, 0, 1, 2, 3, 4]) +@pytest.mark.parametrize("k", [-3, -2, -1, 0, 1, 2, 3]) +@pytest.mark.parametrize("n", [1, 2, 3, 4, 5, 6]) def test_triu_indices(n, k, m): result = dpnp.triu_indices(n, k, m) expected = numpy.triu_indices(n, k, m) assert_array_equal(expected, result) -@pytest.mark.parametrize( - "k", [-3, -2, -1, 0, 1, 2, 3], ids=["-3", "-2", "-1", "0", "1", "2", "3"] -) +@pytest.mark.parametrize("k", [-3, -2, -1, 0, 1, 2, 3]) @pytest.mark.parametrize( "array", [ diff --git a/dpnp/tests/test_linalg.py b/dpnp/tests/test_linalg.py index f239adae84f..990ab59b173 100644 --- a/dpnp/tests/test_linalg.py +++ b/dpnp/tests/test_linalg.py @@ -503,10 +503,9 @@ def test_eigenvalues(self, func, shape, dtype, order): # non-symmetric for eig() and eigvals() is_hermitian = func in ("eigh, eigvalsh") a = generate_random_numpy_array( - shape, dtype, hermitian=is_hermitian, low=-4, high=4 + shape, dtype, order, hermitian=is_hermitian, low=-4, high=4 ) - a_order = numpy.array(a, order=order) - a_dp = dpnp.array(a, order=order) + a_dp = dpnp.array(a) # NumPy with OneMKL and with rocSOLVER sorts in ascending order, # so w's should be directly comparable. @@ -514,13 +513,13 @@ def test_eigenvalues(self, func, shape, dtype, order): # constructing eigenvectors, so v's are not directly comparable and # we verify them through the eigen equation A*v=w*v. if func in ("eig", "eigh"): - w, _ = getattr(numpy.linalg, func)(a_order) + w, _ = getattr(numpy.linalg, func)(a) w_dp, v_dp = getattr(dpnp.linalg, func)(a_dp) self.assert_eigen_decomposition(a_dp, w_dp, v_dp) else: # eighvals or eigvalsh - w = getattr(numpy.linalg, func)(a_order) + w = getattr(numpy.linalg, func)(a) w_dp = getattr(dpnp.linalg, func)(a_dp) assert_dtype_allclose(w_dp, w, factor=24) @@ -2124,9 +2123,7 @@ def test_0D(self, ord, axis): assert_dtype_allclose(result, expected) @pytest.mark.usefixtures("suppress_divide_numpy_warnings") - @pytest.mark.parametrize( - "dtype", get_all_dtypes(xfail_dtypes=[dpnp.uint64]) - ) + @pytest.mark.parametrize("dtype", get_all_dtypes(no_none=True)) @pytest.mark.parametrize( "ord", [None, -dpnp.inf, -2, -1, 0, 1, 2, 3.5, dpnp.inf] ) @@ -2141,9 +2138,7 @@ def test_1D(self, dtype, ord, axis, keepdims): assert_dtype_allclose(result, expected) @pytest.mark.usefixtures("suppress_divide_numpy_warnings") - @pytest.mark.parametrize( - "dtype", get_all_dtypes(xfail_dtypes=[dpnp.uint64]) - ) + @pytest.mark.parametrize("dtype", get_all_dtypes(no_none=True)) @pytest.mark.parametrize( "ord", [None, -dpnp.inf, -2, -1, 1, 2, 3, dpnp.inf, "fro", "nuc"] ) @@ -2170,9 +2165,7 @@ def test_2D(self, dtype, ord, axis, keepdims): @pytest.mark.usefixtures("suppress_divide_numpy_warnings") @pytest.mark.parametrize( "dtype", - get_all_dtypes( - no_none=True, xfail_dtypes=[dpnp.uint16, dpnp.uint32, dpnp.uint64] - ), + get_all_dtypes(no_none=True), ) @pytest.mark.parametrize( "ord", [None, -dpnp.inf, -2, -1, 1, 2, 3, dpnp.inf, "fro", "nuc"] @@ -2204,10 +2197,7 @@ def test_ND(self, dtype, ord, axis, keepdims): assert_dtype_allclose(result, expected) @pytest.mark.usefixtures("suppress_divide_numpy_warnings") - @pytest.mark.parametrize( - "dtype", - get_all_dtypes(xfail_dtypes=[dpnp.uint16, dpnp.uint32, dpnp.uint64]), - ) + @pytest.mark.parametrize("dtype", get_all_dtypes(no_none=True)) @pytest.mark.parametrize( "ord", [None, -dpnp.inf, -2, -1, 1, 2, 3, dpnp.inf, "fro", "nuc"] ) diff --git a/dpnp/tests/test_manipulation.py b/dpnp/tests/test_manipulation.py index 97c951ad156..52c307eaa57 100644 --- a/dpnp/tests/test_manipulation.py +++ b/dpnp/tests/test_manipulation.py @@ -30,7 +30,9 @@ ] testdata += [ ([1, -1, 0], dtype) - for dtype in get_all_dtypes(no_none=True, no_bool=True, no_complex=True) + for dtype in get_all_dtypes( + no_none=True, no_bool=True, no_complex=True, no_unsigned=True + ) ] testdata += [([0.1, 0.0, -0.1], dtype) for dtype in get_float_dtypes()] testdata += [([1j, -1j, 1 - 2j], dtype) for dtype in get_complex_dtypes()] @@ -1719,7 +1721,7 @@ def test_7d_axis_zeros(self, axis): expected = numpy.unique(a, axis=axis) assert_array_equal(result, expected) - @pytest.mark.parametrize("dt", get_integer_dtypes()) + @pytest.mark.parametrize("dt", get_integer_dtypes(no_unsigned=True)) def test_2d_axis_signed_inetger(self, dt): a = numpy.array([[-1], [0]], dtype=dt) ia = dpnp.array(a) diff --git a/dpnp/tests/test_mathematical.py b/dpnp/tests/test_mathematical.py index 756367c4bcb..737b3c4d63f 100644 --- a/dpnp/tests/test_mathematical.py +++ b/dpnp/tests/test_mathematical.py @@ -19,10 +19,12 @@ import dpnp from dpnp.dpnp_array import dpnp_array +from dpnp.dpnp_utils import map_dtype_to_device from .helper import ( assert_dtype_allclose, generate_random_numpy_array, + get_abs_array, get_all_dtypes, get_complex_dtypes, get_float_complex_dtypes, @@ -30,6 +32,7 @@ get_integer_dtypes, has_support_aspect16, has_support_aspect64, + numpy_version, ) from .test_umath import ( _get_numpy_arrays_1in_1out, @@ -39,8 +42,8 @@ from .third_party.cupy import testing +@pytest.mark.parametrize("deg", [True, False]) class TestAngle: - @pytest.mark.parametrize("deg", [True, False]) def test_angle_bool(self, deg): dp_a = dpnp.array([True, False]) np_a = dp_a.asnumpy() @@ -56,7 +59,6 @@ def test_angle_bool(self, deg): @pytest.mark.parametrize( "dtype", get_all_dtypes(no_bool=True, no_complex=True) ) - @pytest.mark.parametrize("deg", [True, False]) def test_angle(self, dtype, deg): dp_a = dpnp.arange(10, dtype=dtype) np_a = dp_a.asnumpy() @@ -64,10 +66,11 @@ def test_angle(self, dtype, deg): expected = numpy.angle(np_a, deg=deg) result = dpnp.angle(dp_a, deg=deg) - assert_dtype_allclose(result, expected) + # For dtype=int8, uint8, NumPy returns float16, but dpnp returns float32 + dt_int8 = dtype in [dpnp.int8, dpnp.uint8] + assert_dtype_allclose(result, expected, check_only_type_kind=dt_int8) @pytest.mark.parametrize("dtype", get_complex_dtypes()) - @pytest.mark.parametrize("deg", [True, False]) def test_angle_complex(self, dtype, deg): a = numpy.random.rand(10) b = numpy.random.rand(10) @@ -258,7 +261,8 @@ def test_basic(self, dtype, axis, include_initial): res = dpnp.cumlogsumexp(a, axis=axis, include_initial=include_initial) exp_dt = None - if dtype == dpnp.bool: + dtype_list = [dpnp.bool, dpnp.int8, dpnp.uint8, dpnp.int16, dpnp.uint16] + if dtype in dtype_list: exp_dt = dpnp.default_float_type(a.device) exp = self._get_exp_array(a, axis, exp_dt) @@ -311,7 +315,9 @@ def test_dtype(self, in_dtype, out_dtype): exp = numpy.logaddexp.accumulate(dpnp.asnumpy(a)) exp = exp.astype(out_dtype) - assert_allclose(res, exp, rtol=1e-06) + dtype_list = [dpnp.int8, dpnp.uint8, dpnp.int16, dpnp.uint16] + tol = 1e-2 if in_dtype in dtype_list else 1e-6 + assert_allclose(res, exp, rtol=tol) @pytest.mark.usefixtures("suppress_invalid_numpy_warnings") @pytest.mark.parametrize( @@ -391,7 +397,7 @@ def test_usm_ndarray(self, sh, xp_in, xp_out, check): @pytest.mark.parametrize("out_dt", get_all_dtypes(no_none=True)) @pytest.mark.parametrize("dtype", get_all_dtypes()) def test_out_dtype(self, arr_dt, out_dt, dtype): - a = numpy.arange(5, 10).astype(dtype=arr_dt) + a = numpy.arange(1, 6).astype(dtype=arr_dt) out = numpy.zeros_like(a, dtype=out_dt) ia = dpnp.array(a) @@ -495,7 +501,7 @@ def test_usm_ndarray(self, sh, xp_in, xp_out, check): @pytest.mark.parametrize("out_dt", get_all_dtypes(no_none=True)) @pytest.mark.parametrize("dtype", get_all_dtypes()) def test_out_dtype(self, arr_dt, out_dt, dtype): - a = numpy.arange(10, 20).astype(dtype=arr_dt) + a = numpy.arange(5, 15).astype(dtype=arr_dt) out = numpy.zeros_like(a, dtype=out_dt) ia = dpnp.array(a) @@ -869,9 +875,7 @@ class TestFix: "dt", get_all_dtypes(no_none=True, no_complex=True) ) def test_basic(self, dt): - a = numpy.array( - [[1.0, 1.1, 1.5, 1.8], [-1.0, -1.1, -1.5, -1.8]], dtype=dt - ) + a = get_abs_array([[1.0, 1.1, 1.5, 1.8], [-1.0, -1.1, -1.5, -1.8]], dt) ia = dpnp.array(a) result = dpnp.fix(ia) @@ -889,15 +893,12 @@ def test_complex(self, xp, dt): "a_dt", get_all_dtypes(no_none=True, no_bool=True, no_complex=True) ) def test_out(self, a_dt): - a = numpy.array( - [[1.0, 1.1, 1.5, 1.8], [-1.0, -1.1, -1.5, -1.8]], dtype=a_dt + a = get_abs_array( + [[1.0, 1.1, 1.5, 1.8], [-1.0, -1.1, -1.5, -1.8]], a_dt ) ia = dpnp.array(a) - if a.dtype != numpy.float32 and has_support_aspect64(): - out_dt = numpy.float64 - else: - out_dt = numpy.float32 + out_dt = _get_output_data_type(a.dtype) out = numpy.zeros_like(a, dtype=out_dt) iout = dpnp.array(out) @@ -1295,8 +1296,8 @@ def test_basic(self, val, dt): "b_dt", get_all_dtypes(no_none=True, no_complex=True) ) def test_both_input_as_arrays(self, a_dt, b_dt): - a = numpy.array([-1.5, 0, 2.0], dtype=a_dt) - b = numpy.array([-0, 0.5, 1.0], dtype=b_dt) + a = get_abs_array([-1.5, 0, 2.0], a_dt) + b = get_abs_array([-0, 0.5, 1.0], b_dt) ia, ib = dpnp.array(a), dpnp.array(b) result = dpnp.heaviside(ia, ib) @@ -1350,7 +1351,10 @@ def test_1d(self, dt): result = dpnp.i0(ia) expected = numpy.i0(a) - assert_dtype_allclose(result, expected) + # NumPy promotes result of integer inputs to float64, but dpnp + # follows Type Promotion Rules + flag = dt in [numpy.int8, numpy.int16, numpy.uint8, numpy.uint16] + assert_dtype_allclose(result, expected, check_only_type_kind=flag) @pytest.mark.parametrize("dt", get_float_dtypes()) def test_2d(self, dt): @@ -1405,7 +1409,7 @@ class TestLdexp: @pytest.mark.parametrize("exp_dt", get_integer_dtypes()) def test_basic(self, mant_dt, exp_dt): if ( - numpy.lib.NumpyVersion(numpy.__version__) < "2.0.0" + numpy_version() < "2.0.0" and exp_dt == numpy.int64 and numpy.dtype("l") != numpy.int64 ): @@ -1415,9 +1419,18 @@ def test_basic(self, mant_dt, exp_dt): exp = numpy.array(3, dtype=exp_dt) imant, iexp = dpnp.array(mant), dpnp.array(exp) - result = dpnp.ldexp(imant, iexp) - expected = numpy.ldexp(mant, exp) - assert_almost_equal(result, expected) + if dpnp.issubdtype(exp_dt, dpnp.uint64): + assert_raises(ValueError, dpnp.ldexp, imant, iexp) + assert_raises(TypeError, numpy.ldexp, mant, exp) + elif numpy_version() < "2.0.0" and dpnp.issubdtype(exp_dt, dpnp.uint32): + # For this special case, NumPy < "2.0.0" raises an error on Windows + result = dpnp.ldexp(imant, iexp) + expected = numpy.ldexp(mant, exp.astype(numpy.int32)) + assert_almost_equal(result, expected) + else: + result = dpnp.ldexp(imant, iexp) + expected = numpy.ldexp(mant, exp) + assert_almost_equal(result, expected) def test_float_scalar(self): a = numpy.array(3) @@ -1893,7 +1906,7 @@ def test_prod_out(self): @pytest.mark.parametrize("out_dt", get_all_dtypes(no_none=True)) @pytest.mark.parametrize("dtype", get_all_dtypes()) def test_prod_out_dtype(self, arr_dt, out_dt, dtype): - a = numpy.arange(10, 20).reshape((2, 5)).astype(dtype=arr_dt) + a = numpy.arange(1, 7).reshape((2, 3)).astype(dtype=arr_dt) out = numpy.zeros_like(a, shape=(2,), dtype=out_dt) ia = dpnp.array(a) @@ -1917,8 +1930,8 @@ def test_prod_Error(self): class TestRationalFunctions: @pytest.mark.parametrize("func", ["gcd", "lcm"]) - @pytest.mark.parametrize("dt1", get_integer_dtypes()) - @pytest.mark.parametrize("dt2", get_integer_dtypes()) + @pytest.mark.parametrize("dt1", get_integer_dtypes(no_unsigned=True)) + @pytest.mark.parametrize("dt2", get_integer_dtypes(no_unsigned=True)) def test_basic(self, func, dt1, dt2): a = numpy.array([12, 120], dtype=dt1) b = numpy.array([20, 120], dtype=dt2) @@ -2013,12 +2026,16 @@ class TestSinc: "dt", get_all_dtypes(no_none=True, no_bool=True, no_float16=False) ) def test_basic(self, dt): + low = 0 if dpnp.issubdtype(dt, dpnp.integer) else -1 a = numpy.linspace(-1, 1, 100, dtype=dt) ia = dpnp.array(a) result = dpnp.sinc(ia) expected = numpy.sinc(a) - assert_dtype_allclose(result, expected) + # numpy promotes result for integer inputs to float64 dtype, but dpnp + # follows Type Promotion Rules similar to other trigonometric functions + flag = dt in [numpy.int8, numpy.int16, numpy.uint8, numpy.uint16] + assert_dtype_allclose(result, expected, check_only_type_kind=flag) def test_bool(self): a = numpy.array([True, False, True]) @@ -2036,7 +2053,10 @@ def test_zero(self, dt): result = dpnp.sinc(ia) expected = numpy.sinc(a) - assert_dtype_allclose(result, expected) + # numpy promotes result for integer inputs to float64 dtype, but dpnp + # follows Type Promotion Rules similar to other trigonometric functions + flag = dt in [numpy.int8, numpy.int16, numpy.uint8, numpy.uint16] + assert_dtype_allclose(result, expected, check_only_type_kind=flag) # TODO: add a proper NumPy version once resolved @testing.with_requires("numpy>=2.0.0") @@ -2111,7 +2131,7 @@ def test_zeros(self, dt): result = dpnp.spacing(ia) expected = numpy.spacing(a) - if numpy.lib.NumpyVersion(numpy.__version__) < "2.0.0": + if numpy_version() < "2.0.0": assert_equal(result, expected) else: # numpy.spacing(-0.0) == numpy.spacing(0.0), i.e. NumPy returns @@ -2151,7 +2171,7 @@ def test_fp16(self): @pytest.mark.parametrize("dt", get_integer_dtypes()) def test_integer(self, dt): - a = numpy.array([1, 0, -3], dtype=dt) + a = get_abs_array([1, 0, -3], dt) ia = dpnp.array(a) result = dpnp.spacing(ia) @@ -2174,7 +2194,7 @@ def test_complex(self, xp): class TestTrapezoid: def get_numpy_func(self): - if numpy.lib.NumpyVersion(numpy.__version__) < "2.0.0": + if numpy_version() < "2.0.0": # `trapz` is deprecated in NumPy 2.0 return numpy.trapz return numpy.trapezoid @@ -2308,27 +2328,32 @@ def test_rand(self, dt): assert_dtype_allclose(result, expected) @pytest.mark.parametrize( - "dt", get_all_dtypes(no_none=True, no_bool=True, no_complex=True) + "dt", + get_all_dtypes( + no_none=True, no_bool=True, no_complex=True, no_unsigned=True + ), ) def test_period(self, dt): - a = numpy.array([1, 1 + 256], dtype=dt) + a = numpy.array([1, 1 + 108], dtype=dt) ia = dpnp.array(a) - # unwrap removes jumps greater than 255 - result = dpnp.unwrap(ia, period=255) - expected = numpy.unwrap(a, period=255) + # unwrap removes jumps greater than 107 + result = dpnp.unwrap(ia, period=107) + expected = numpy.unwrap(a, period=107) assert_array_equal(result, expected) @pytest.mark.parametrize( - "dt", get_all_dtypes(no_none=True, no_bool=True, no_complex=True) + "dt", + get_all_dtypes( + no_none=True, no_bool=True, no_complex=True, no_unsigned=True + ), ) def test_rand_period(self, dt): - a = generate_random_numpy_array(10) * 1000 - a = a.astype(dtype=dt) + a = generate_random_numpy_array(10, dt, low=-100, high=100) ia = dpnp.array(a) - result = dpnp.unwrap(ia, period=255) - expected = numpy.unwrap(a, period=255) + result = dpnp.unwrap(ia, period=25) + expected = numpy.unwrap(a, period=25) assert_dtype_allclose(result, expected) def test_simple_seq(self): @@ -2342,19 +2367,21 @@ def test_simple_seq(self): assert_array_equal(result, isimple_seq) @pytest.mark.parametrize( - "dt", get_all_dtypes(no_none=True, no_complex=True) + "dt", + get_all_dtypes( + no_bool=True, no_none=True, no_complex=True, no_unsigned=True + ), ) def test_discont(self, dt): - a = numpy.array([0, 75, 150, 225, 300, 430], dtype=dt) - a = numpy.mod(a, 250) + a = numpy.array([0, 8, 20, 25, 35, 50], dtype=dt) ia = dpnp.array(a) - result = dpnp.unwrap(ia, period=250) - expected = numpy.unwrap(a, period=250) + result = dpnp.unwrap(ia, period=20) + expected = numpy.unwrap(a, period=20) assert_array_equal(result, expected) - result = dpnp.unwrap(ia, period=250, discont=140) - expected = numpy.unwrap(a, period=250, discont=140) + result = dpnp.unwrap(ia, period=20, discont=14) + expected = numpy.unwrap(a, period=20, discont=14) assert_array_equal(result, expected) assert result.dtype == ia.dtype == a.dtype @@ -2469,10 +2496,12 @@ def test_divide_scalar(shape, dtype): [[[1.0, -1.0], [0.1, -0.1]], [-2, -1, 0, 1, 2]], ids=["[[1., -1.], [0.1, -0.1]]", "[-2, -1, 0, 1, 2]"], ) -@pytest.mark.parametrize("dtype", get_all_dtypes(no_bool=True)) +@pytest.mark.parametrize( + "dtype", get_all_dtypes(no_bool=True, no_unsigned=True) +) def test_negative(data, dtype): np_a = numpy.array(data, dtype=dtype) - dpnp_a = dpnp.array(data, dtype=dtype) + dpnp_a = dpnp.array(np_a) result = dpnp.negative(dpnp_a) expected = numpy.negative(np_a) @@ -2504,8 +2533,8 @@ def test_negative_boolean(): ) @pytest.mark.parametrize("dtype", get_all_dtypes(no_bool=True)) def test_positive(data, dtype): - np_a = numpy.array(data, dtype=dtype) - dpnp_a = dpnp.array(data, dtype=dtype) + np_a = get_abs_array(data, dtype=dtype) + dpnp_a = dpnp.array(np_a) result = dpnp.positive(dpnp_a) expected = numpy.positive(np_a) @@ -2581,7 +2610,9 @@ def test_float_remainder_fmod_nans_inf(func, dtype, lhs, rhs): [[2, 0, -2], [1.1, -1.1]], ids=["[2, 0, -2]", "[1.1, -1.1]"], ) -@pytest.mark.parametrize("dtype", get_all_dtypes(no_bool=True)) +@pytest.mark.parametrize( + "dtype", get_all_dtypes(no_bool=True, no_unsigned=True) +) def test_sign(data, dtype): np_a = numpy.array(data, dtype=dtype) dpnp_a = dpnp.array(data, dtype=dtype) @@ -2610,7 +2641,9 @@ def test_sign_boolean(): [[2, 0, -2], [1.1, -1.1]], ids=["[2, 0, -2]", "[1.1, -1.1]"], ) -@pytest.mark.parametrize("dtype", get_all_dtypes(no_complex=True)) +@pytest.mark.parametrize( + "dtype", get_all_dtypes(no_complex=True, no_unsigned=True) +) def test_signbit(data, dtype): np_a = numpy.array(data, dtype=dtype) dpnp_a = dpnp.array(data, dtype=dtype) @@ -2719,10 +2752,7 @@ def test_out(self, func_params, dtype): # NumPy < 2.0.0 while output has the dtype of input for NumPy >= 2.0.0 # (dpnp follows the latter behavior except for boolean dtype where it # returns int8) - if ( - numpy.lib.NumpyVersion(numpy.__version__) < "2.0.0" - or dtype == numpy.bool - ): + if numpy_version() < "2.0.0" or dtype == numpy.bool: check_type = False else: check_type = True @@ -2822,7 +2852,10 @@ def test_divide(self, dtype): dp_array1 = dpnp.array(np_array1) dp_array2 = dpnp.array(np_array2) - out_dtype = _get_output_data_type(dtype) + if numpy.issubdtype(dtype, numpy.integer): + out_dtype = map_dtype_to_device(dpnp.float64, dp_array1.sycl_device) + else: + out_dtype = _get_output_data_type(dtype) dp_out = dpnp.empty(expected.shape, dtype=out_dtype) result = dpnp.divide(dp_array1, dp_array2, out=dp_out) @@ -3152,11 +3185,14 @@ class TestLogSumExp: def test_logsumexp(self, dtype, axis, keepdims): a = dpnp.ones((3, 4, 5, 6, 7), dtype=dtype) res = dpnp.logsumexp(a, axis=axis, keepdims=keepdims) - exp_dtype = ( - dpnp.default_float_type(a.device) if dtype == dpnp.bool else None - ) + + exp_dt = None + dtype_list = [dpnp.bool, dpnp.int8, dpnp.uint8, dpnp.int16, dpnp.uint16] + if dtype in dtype_list: + exp_dt = dpnp.default_float_type(a.device) + exp = numpy.logaddexp.reduce( - dpnp.asnumpy(a), axis=axis, keepdims=keepdims, dtype=exp_dtype + dpnp.asnumpy(a), axis=axis, keepdims=keepdims, dtype=exp_dt ) assert_dtype_allclose(res, exp) @@ -3166,17 +3202,18 @@ def test_logsumexp(self, dtype, axis, keepdims): @pytest.mark.parametrize("keepdims", [True, False]) def test_logsumexp_out(self, dtype, axis, keepdims): a = dpnp.ones((3, 4, 5, 6, 7), dtype=dtype) - exp_dtype = ( - dpnp.default_float_type(a.device) if dtype == dpnp.bool else None - ) + exp_dt = None + dtype_list = [dpnp.bool, dpnp.int8, dpnp.uint8, dpnp.int16, dpnp.uint16] + if dtype in dtype_list: + exp_dt = dpnp.default_float_type(a.device) exp = numpy.logaddexp.reduce( - dpnp.asnumpy(a), axis=axis, keepdims=keepdims, dtype=exp_dtype + dpnp.asnumpy(a), axis=axis, keepdims=keepdims, dtype=exp_dt ) - exp_dtype = exp.dtype - if exp_dtype == numpy.float64 and not has_support_aspect64(): - exp_dtype = numpy.float32 - dpnp_out = dpnp.empty_like(a, shape=exp.shape, dtype=exp_dtype) + exp_dt = exp.dtype + if exp_dt == numpy.float64 and not has_support_aspect64(): + exp_dt = numpy.float32 + dpnp_out = dpnp.empty_like(a, shape=exp.shape, dtype=exp_dt) res = dpnp.logsumexp(a, axis=axis, out=dpnp_out, keepdims=keepdims) assert res is dpnp_out @@ -3192,7 +3229,9 @@ def test_logsumexp_dtype(self, in_dtype, out_dtype): exp = numpy.logaddexp.reduce(dpnp.asnumpy(a)) exp = exp.astype(out_dtype) - assert_allclose(res, exp, rtol=1e-06) + dtype_list = [dpnp.int8, dpnp.uint8, dpnp.int16, dpnp.uint16] + tol = 1e-2 if in_dtype in dtype_list else 1e-6 + assert_allclose(res, exp, rtol=tol) @testing.with_requires("numpy>=1.26.4") @pytest.mark.usefixtures("suppress_invalid_numpy_warnings") @@ -3204,15 +3243,23 @@ def test_logsumexp_dtype(self, in_dtype, out_dtype): ) @pytest.mark.parametrize("dtype", get_all_dtypes()) def test_logsumexp_out_dtype(self, arr_dt, out_dt, dtype): - a = numpy.arange(10, 20).reshape((2, 5)).astype(dtype=arr_dt) + a = numpy.arange(1, 11).reshape((2, 5)).astype(dtype=arr_dt) out = numpy.zeros_like(a, shape=(2,), dtype=out_dt) ia = dpnp.array(a) iout = dpnp.array(out) result = dpnp.logsumexp(ia, out=iout, dtype=dtype, axis=1) - exp = numpy.logaddexp.reduce(a, out=out, axis=1) - assert_allclose(result, exp.astype(dtype), rtol=1e-06) + if numpy.issubdtype(out_dt, numpy.uint64): + # NumPy returns incorrect results for this case if out kwarg is used + exp = numpy.logaddexp.reduce(a, axis=1) + exp = exp.astype(out_dt) + else: + exp = numpy.logaddexp.reduce(a, out=out, axis=1) + + dtype_list = [dpnp.int8, dpnp.uint8, dpnp.int16, dpnp.uint16] + tol = 1e-2 if arr_dt in dtype_list else 1e-6 + assert_allclose(result, exp.astype(dtype), rtol=tol) assert result is iout @@ -3223,11 +3270,14 @@ class TestReduceHypot: def test_reduce_hypot(self, dtype, axis, keepdims): a = dpnp.ones((3, 4, 5, 6, 7), dtype=dtype) res = dpnp.reduce_hypot(a, axis=axis, keepdims=keepdims) - exp_dtype = ( - dpnp.default_float_type(a.device) if dtype == dpnp.bool else None - ) + + exp_dt = None + dtype_list = [dpnp.bool, dpnp.int8, dpnp.uint8, dpnp.int16, dpnp.uint16] + if dtype in dtype_list: + exp_dt = dpnp.default_float_type(a.device) + exp = numpy.hypot.reduce( - dpnp.asnumpy(a), axis=axis, keepdims=keepdims, dtype=exp_dtype + dpnp.asnumpy(a), axis=axis, keepdims=keepdims, dtype=exp_dt ) assert_dtype_allclose(res, exp) @@ -3237,17 +3287,18 @@ def test_reduce_hypot(self, dtype, axis, keepdims): @pytest.mark.parametrize("keepdims", [True, False]) def test_reduce_hypot_out(self, dtype, axis, keepdims): a = dpnp.ones((3, 4, 5, 6, 7), dtype=dtype) - exp_dtype = ( - dpnp.default_float_type(a.device) if dtype == dpnp.bool else None - ) + exp_dt = None + dtype_list = [dpnp.bool, dpnp.int8, dpnp.uint8, dpnp.int16, dpnp.uint16] + if dtype in dtype_list: + exp_dt = dpnp.default_float_type(a.device) exp = numpy.hypot.reduce( - dpnp.asnumpy(a), axis=axis, keepdims=keepdims, dtype=exp_dtype + dpnp.asnumpy(a), axis=axis, keepdims=keepdims, dtype=exp_dt ) - exp_dtype = exp.dtype - if exp_dtype == numpy.float64 and not has_support_aspect64(): - exp_dtype = numpy.float32 - dpnp_out = dpnp.empty_like(a, shape=exp.shape, dtype=exp_dtype) + exp_dt = exp.dtype + if exp_dt == numpy.float64 and not has_support_aspect64(): + exp_dt = numpy.float32 + dpnp_out = dpnp.empty_like(a, shape=exp.shape, dtype=exp_dt) res = dpnp.reduce_hypot(a, axis=axis, out=dpnp_out, keepdims=keepdims) assert res is dpnp_out @@ -3263,7 +3314,9 @@ def test_reduce_hypot_dtype(self, in_dtype, out_dtype): exp = numpy.hypot.reduce(dpnp.asnumpy(a)) exp = exp.astype(out_dtype) - assert_allclose(res, exp, rtol=1e-06) + dtype_list = [dpnp.int8, dpnp.uint8] + tol = 1e-2 if in_dtype in dtype_list else 1e-6 + assert_allclose(res, exp, rtol=tol) @pytest.mark.parametrize( "arr_dt", get_all_dtypes(no_none=True, no_complex=True) @@ -3348,7 +3401,7 @@ def test_invalid_out(self, out): class TestPower: @pytest.mark.parametrize("val_type", get_all_dtypes(no_none=True)) @pytest.mark.parametrize("data_type", get_all_dtypes()) - @pytest.mark.parametrize("val", [1.5, 1, 5], ids=["1.5", "1", "5"]) + @pytest.mark.parametrize("val", [1.5, 1, 3], ids=["1.5", "1", "3"]) @pytest.mark.parametrize( "array", [ @@ -3690,8 +3743,8 @@ def test_matmul_bool(self, shape1, shape2): ], ) def test_matmul_axes_ND_ND(self, dtype, axes): - a = generate_random_numpy_array((2, 5, 3, 4), dtype) - b = generate_random_numpy_array((4, 2, 5, 3), dtype) + a = generate_random_numpy_array((2, 5, 3, 4), dtype, low=-5, high=5) + b = generate_random_numpy_array((4, 2, 5, 3), dtype, low=-5, high=5) ia = dpnp.array(a) ib = dpnp.array(b) @@ -3759,8 +3812,8 @@ def test_matmul_axes_1D_1D(self): ], ) def test_matmul_axes_out(self, dtype, axes, out_shape): - a = generate_random_numpy_array((2, 5, 3, 4), dtype) - b = generate_random_numpy_array((4, 2, 5, 3), dtype) + a = generate_random_numpy_array((2, 5, 3, 4), dtype, low=-5, high=5) + b = generate_random_numpy_array((4, 2, 5, 3), dtype, low=-5, high=5) ia = dpnp.array(a) ib = dpnp.array(b) @@ -3811,8 +3864,8 @@ def test_matmul_axes_out_1D(self, axes, b_shape, out_shape): ], ) def test_matmul_dtype_matrix_inout(self, in_dt, out_dt, shape1, shape2): - a1 = generate_random_numpy_array(shape1, in_dt) - a2 = generate_random_numpy_array(shape2, in_dt) + a1 = generate_random_numpy_array(shape1, in_dt, low=-5, high=5) + a2 = generate_random_numpy_array(shape2, in_dt, low=-5, high=5) b1 = dpnp.asarray(a1) b2 = dpnp.asarray(a2) @@ -3840,8 +3893,8 @@ def test_matmul_dtype_matrix_inout(self, in_dt, out_dt, shape1, shape2): ], ) def test_matmul_dtype_matrix_inputs(self, dtype1, dtype2, shape1, shape2): - a1 = generate_random_numpy_array(shape1, dtype1) - a2 = generate_random_numpy_array(shape2, dtype2) + a1 = generate_random_numpy_array(shape1, dtype1, low=-5, high=5) + a2 = generate_random_numpy_array(shape2, dtype2, low=-5, high=5) b1 = dpnp.asarray(a1) b2 = dpnp.asarray(a2) @@ -4054,9 +4107,10 @@ def test_matmul_strided_vec_mat(self, shape, incx, incy, transpose): ) def test_matmul_out1(self, order1, order2, out_order, dtype): # test gemm with out keyword - a1 = numpy.arange(20, dtype=dtype).reshape(5, 4, order=order1) - a2 = numpy.arange(28, dtype=dtype).reshape(4, 7, order=order2) - + a1 = generate_random_numpy_array((5, 4), dtype, low=-5, high=5) + a2 = generate_random_numpy_array((4, 7), dtype, low=-5, high=5) + a1 = numpy.array(a1, order=order1) + a2 = numpy.array(a2, order=order2) b1 = dpnp.asarray(a1) b2 = dpnp.asarray(a2) @@ -4078,8 +4132,8 @@ def test_matmul_out2(self, trans, dtype): # test gemm_batch with out keyword # the base of input arrays is c-contiguous # the base of output array is c-contiguous or f-contiguous - a1 = numpy.arange(24, dtype=dtype).reshape(2, 3, 4) - a2 = numpy.arange(40, dtype=dtype).reshape(2, 4, 5) + a1 = generate_random_numpy_array((2, 3, 4), dtype, low=-5, high=5) + a2 = generate_random_numpy_array((2, 4, 5), dtype, low=-5, high=5) b1 = dpnp.asarray(a1) b2 = dpnp.asarray(a2) @@ -4106,8 +4160,8 @@ def test_matmul_out3(self, trans, dtype): # test gemm_batch with out keyword # the base of input arrays is f-contiguous # the base of output array is c-contiguous or f-contiguous - a1 = numpy.arange(24, dtype=dtype).reshape(2, 4, 3) - a2 = numpy.arange(40, dtype=dtype).reshape(2, 5, 4) + a1 = generate_random_numpy_array((2, 4, 3), dtype, low=-5, high=5) + a2 = generate_random_numpy_array((2, 5, 4), dtype, low=-5, high=5) b1 = dpnp.asarray(a1) b2 = dpnp.asarray(a2) diff --git a/dpnp/tests/test_nanfunctions.py b/dpnp/tests/test_nanfunctions.py index 5645586219e..a8eccc81c87 100644 --- a/dpnp/tests/test_nanfunctions.py +++ b/dpnp/tests/test_nanfunctions.py @@ -15,6 +15,7 @@ from .helper import ( assert_dtype_allclose, + get_abs_array, get_all_dtypes, get_complex_dtypes, get_float_complex_dtypes, @@ -586,7 +587,7 @@ def test_nanprod_out(self): @pytest.mark.parametrize("out_dt", get_all_dtypes(no_none=True)) @pytest.mark.parametrize("dtype", get_all_dtypes()) def test_nanprod_out_dtype(self, arr_dt, out_dt, dtype): - a = numpy.arange(10, 20).reshape((2, 5)).astype(dtype=arr_dt) + a = numpy.arange(1, 7).reshape((2, 3)).astype(dtype=arr_dt) out = numpy.zeros_like(a, shape=(2,), dtype=out_dt) ia = dpnp.array(a) @@ -648,7 +649,7 @@ class TestNanStd: ) def test_nanstd(self, array, dtype): try: - a = numpy.array(array, dtype=dtype) + a = get_abs_array(array, dtype=dtype) except: pytest.skip("floating datat type is needed to store NaN") ia = dpnp.array(a) @@ -835,9 +836,9 @@ class TestNanVar: ) def test_nanvar(self, array, dtype): try: - a = numpy.array(array, dtype=dtype) + a = get_abs_array(array, dtype=dtype) except: - pytest.skip("floating datat type is needed to store NaN") + pytest.skip("floating data type is needed to store NaN") ia = dpnp.array(a) for ddof in range(a.ndim): expected = numpy.nanvar(a, ddof=ddof) diff --git a/dpnp/tests/test_ndarray.py b/dpnp/tests/test_ndarray.py index 153b3d0c2e9..3d3c3ee8b63 100644 --- a/dpnp/tests/test_ndarray.py +++ b/dpnp/tests/test_ndarray.py @@ -6,6 +6,7 @@ import dpnp from .helper import ( + get_abs_array, get_all_dtypes, get_complex_dtypes, get_float_dtypes, @@ -23,7 +24,7 @@ ids=["[-2, -1, 0, 1, 2]", "[[-2, -1], [1, 2]]", "[]"], ) def test_astype(arr, arr_dtype, res_dtype): - numpy_array = numpy.array(arr, dtype=arr_dtype) + numpy_array = get_abs_array(arr, arr_dtype) dpnp_array = dpnp.array(numpy_array) expected = numpy_array.astype(res_dtype) result = dpnp_array.astype(res_dtype) @@ -43,8 +44,8 @@ def test_astype_subok_error(): ids=["[-2, -1, 0, 1, 2]", "[[-2, -1], [1, 2]]", "[]"], ) def test_flatten(arr, arr_dtype): - numpy_array = numpy.array(arr, dtype=arr_dtype) - dpnp_array = dpnp.array(arr, dtype=arr_dtype) + numpy_array = get_abs_array(arr, arr_dtype) + dpnp_array = dpnp.array(numpy_array) expected = numpy_array.flatten() result = dpnp_array.flatten() assert_array_equal(expected, result) diff --git a/dpnp/tests/test_outer.py b/dpnp/tests/test_outer.py index 77f57ebf7dd..bcdc8091ed0 100644 --- a/dpnp/tests/test_outer.py +++ b/dpnp/tests/test_outer.py @@ -59,14 +59,14 @@ class TestScalarOuter(unittest.TestCase): @testing.numpy_cupy_allclose(type_check=False) def test_first_is_scalar(self, xp, dtype): scalar = 4 - a = xp.arange(5**3, dtype=dtype).reshape(5, 5, 5) + a = xp.arange(24, dtype=dtype).reshape(2, 3, 4) return xp.outer(scalar, a) @testing.for_all_dtypes() @testing.numpy_cupy_allclose(type_check=False) def test_second_is_scalar(self, xp, dtype): - scalar = 7 - a = xp.arange(5**3, dtype=dtype).reshape(5, 5, 5) + scalar = 5 + a = xp.arange(24, dtype=dtype).reshape(2, 3, 4) return xp.outer(a, scalar) diff --git a/dpnp/tests/test_product.py b/dpnp/tests/test_product.py index 95c643a6494..762d2dbb992 100644 --- a/dpnp/tests/test_product.py +++ b/dpnp/tests/test_product.py @@ -5,28 +5,19 @@ from numpy.testing import assert_raises import dpnp +from dpnp.dpnp_utils import map_dtype_to_device from .helper import ( assert_dtype_allclose, generate_random_numpy_array, get_all_dtypes, get_complex_dtypes, + is_win_platform, + numpy_version, ) from .third_party.cupy import testing -def _assert_selective_dtype_allclose(result, expected, dtype): - # For numpy.dot, numpy.vdot, numpy.kron, numpy.inner, and numpy.tensordot, - # when inputs are an scalar (which has the default dtype of platform) and - # an array, the scalar dtype precision determines the output dtype - # precision. In dpnp, we rely on dpnp.multiply for scalar-array product - # and array (not scalar) determines output dtype precision of dpnp.multiply - if dtype in [numpy.int32, numpy.float32, numpy.complex64]: - assert_dtype_allclose(result, expected, check_only_type_kind=True) - else: - assert_dtype_allclose(result, expected) - - class TestCross: def setup_method(self): numpy.random.seed(42) @@ -221,11 +212,11 @@ def test_scalar(self, dtype): result = dpnp.dot(a, ib) expected = numpy.dot(a, b) - _assert_selective_dtype_allclose(result, expected, dtype) + assert_dtype_allclose(result, expected) result = dpnp.dot(ib, a) expected = numpy.dot(b, a) - _assert_selective_dtype_allclose(result, expected, dtype) + assert_dtype_allclose(result, expected) @pytest.mark.parametrize("dtype", get_all_dtypes(no_none=True)) @pytest.mark.parametrize( @@ -256,8 +247,8 @@ def test_scalar(self, dtype): ], ) def test_basic(self, dtype, shape1, shape2): - a = generate_random_numpy_array(shape1, dtype) - b = generate_random_numpy_array(shape2, dtype) + a = generate_random_numpy_array(shape1, dtype, low=-5, high=5) + b = generate_random_numpy_array(shape2, dtype, low=-5, high=5) ia = dpnp.array(a) ib = dpnp.array(b) @@ -288,12 +279,15 @@ def test_out_scalar(self, dtype): b = generate_random_numpy_array(10, dtype) ib = dpnp.array(b) - dp_out = dpnp.empty(10, dtype=dtype) + np_res_dtype = numpy.result_type(type(a), b) + out = numpy.empty(10, dtype=np_res_dtype) + dp_res_dtype = map_dtype_to_device(np_res_dtype, ib.sycl_device) + dp_out = dpnp.array(out, dtype=dp_res_dtype) result = dpnp.dot(a, ib, out=dp_out) - expected = numpy.dot(a, b) + expected = numpy.dot(a, b, out=out) assert result is dp_out - _assert_selective_dtype_allclose(result, expected, dtype) + assert_dtype_allclose(result, expected) @pytest.mark.parametrize("dtype", get_all_dtypes()) @pytest.mark.parametrize( @@ -324,8 +318,8 @@ def test_out_scalar(self, dtype): ], ) def test_out(self, dtype, shape1, shape2, out_shape): - a = generate_random_numpy_array(shape1, dtype) - b = generate_random_numpy_array(shape2, dtype) + a = generate_random_numpy_array(shape1, dtype, low=-5, high=5) + b = generate_random_numpy_array(shape2, dtype, low=-5, high=5) ia = dpnp.array(a) ib = dpnp.array(b) @@ -376,7 +370,9 @@ def test_out_error_scalar(self, ia): # output data type is incorrect dp_out = dpnp.empty((10,), dtype=dpnp.complex64) out = numpy.empty((10,), dtype=numpy.complex64) - assert_raises(ValueError, dpnp.dot, ia, ib, out=dp_out) + # For scalar dpnp raises TypeError, and for empty array raises ValueError + # NumPy raises ValueError for both cases + assert_raises((TypeError, ValueError), dpnp.dot, ia, ib, out=dp_out) assert_raises(ValueError, numpy.dot, a, b, out=out) # output shape is incorrect @@ -442,11 +438,11 @@ def test_scalar(self, dtype): result = dpnp.inner(a, ib) expected = numpy.inner(a, b) - _assert_selective_dtype_allclose(result, expected, dtype) + assert_dtype_allclose(result, expected) result = dpnp.inner(ib, a) expected = numpy.inner(b, a) - _assert_selective_dtype_allclose(result, expected, dtype) + assert_dtype_allclose(result, expected) @pytest.mark.parametrize("dtype", get_all_dtypes(no_none=True)) @pytest.mark.parametrize( @@ -460,8 +456,8 @@ def test_scalar(self, dtype): ], ) def test_basic(self, dtype, shape1, shape2): - a = generate_random_numpy_array(shape1, dtype) - b = generate_random_numpy_array(shape2, dtype) + a = generate_random_numpy_array(shape1, dtype, low=-5, high=5) + b = generate_random_numpy_array(shape2, dtype, low=-5, high=5) ia = dpnp.array(a) ib = dpnp.array(b) @@ -510,11 +506,14 @@ def test_scalar(self, dtype): result = dpnp.kron(a, ib) expected = numpy.kron(a, b) - _assert_selective_dtype_allclose(result, expected, dtype) + assert_dtype_allclose(result, expected) result = dpnp.kron(ib, a) expected = numpy.kron(b, a) - _assert_selective_dtype_allclose(result, expected, dtype) + # NumPy returns incorrect dtype for numpy_version() < "2.0.0" + flag = dtype in [numpy.int64, numpy.float64, numpy.complex128] + flag = flag or numpy_version() >= "2.0.0" + assert_dtype_allclose(result, expected, check_type=flag) @pytest.mark.parametrize("dtype", get_all_dtypes(no_none=True)) @pytest.mark.parametrize( @@ -611,7 +610,7 @@ def setup_method(self): ((6,), (6, 10), (10, 7), (7, 8)), ((4, 6), (6, 10), (10, 7), (7,)), ((6,), (6, 10), (10, 7), (7,)), - ((4, 6), (6, 9), (9, 7), (7, 8), (8, 3)), + ((4, 6), (6, 2), (2, 7), (7, 5), (5, 3)), ], ids=[ "two_arrays", @@ -631,7 +630,7 @@ def test_basic(self, shapes, dtype): numpy_array_list = [] dpnp_array_list = [] for shape in shapes: - a = generate_random_numpy_array(shape, dtype) + a = generate_random_numpy_array(shape, dtype, low=-2, high=2) ia = dpnp.array(a) numpy_array_list.append(a) @@ -655,7 +654,7 @@ def test_basic(self, shapes, dtype): ((6,), (6, 10), (10, 7), (7, 8), (8,)), ((4, 6), (6, 10), (10, 7), (7,), (4,)), ((6,), (6, 10), (10, 7), (7,), ()), - ((4, 6), (6, 9), (9, 7), (7, 8), (8, 3), (4, 3)), + ((4, 6), (6, 2), (2, 7), (7, 5), (5, 3), (4, 3)), ], ids=[ "two_arrays", @@ -675,7 +674,7 @@ def test_out(self, shapes, dtype): numpy_array_list = [] dpnp_array_list = [] for shape in shapes[:-1]: - a = generate_random_numpy_array(shape, dtype) + a = generate_random_numpy_array(shape, dtype, low=-2, high=2) ia = dpnp.array(a) numpy_array_list.append(a) @@ -762,17 +761,17 @@ def test_scalar(self, dtype): result = dpnp.tensordot(a, ib, axes=0) expected = numpy.tensordot(a, b, axes=0) - _assert_selective_dtype_allclose(result, expected, dtype) + assert_dtype_allclose(result, expected) result = dpnp.tensordot(ib, a, axes=0) expected = numpy.tensordot(b, a, axes=0) - _assert_selective_dtype_allclose(result, expected, dtype) + assert_dtype_allclose(result, expected) @pytest.mark.parametrize("dtype", get_all_dtypes(no_none=True)) @pytest.mark.parametrize("axes", [0, 1, 2]) def test_basic(self, dtype, axes): - a = generate_random_numpy_array((4, 4, 4), dtype) - b = generate_random_numpy_array((4, 4, 4), dtype) + a = generate_random_numpy_array((4, 4, 4), dtype, low=-5, high=5) + b = generate_random_numpy_array((4, 4, 4), dtype, low=-5, high=5) ia = dpnp.array(a) ib = dpnp.array(b) @@ -792,8 +791,8 @@ def test_basic(self, dtype, axes): ], ) def test_axes(self, dtype, axes): - a = generate_random_numpy_array((2, 5, 3, 4), dtype) - b = generate_random_numpy_array((4, 2, 5, 3), dtype) + a = generate_random_numpy_array((2, 5, 3, 4), dtype, low=-5, high=5) + b = generate_random_numpy_array((4, 2, 5, 3), dtype, low=-5, high=5) ia = dpnp.array(a) ib = dpnp.array(b) @@ -804,8 +803,8 @@ def test_axes(self, dtype, axes): @pytest.mark.parametrize("dtype1", get_all_dtypes()) @pytest.mark.parametrize("dtype2", get_all_dtypes()) def test_input_dtype_matrix(self, dtype1, dtype2): - a = generate_random_numpy_array((3, 4, 5), dtype1) - b = generate_random_numpy_array((4, 5, 2), dtype2) + a = generate_random_numpy_array((3, 4, 5), dtype1, low=-5, high=5) + b = generate_random_numpy_array((4, 5, 2), dtype2, low=-5, high=5) ia = dpnp.array(a) ib = dpnp.array(b) @@ -896,11 +895,11 @@ def test_scalar(self, dtype): result = dpnp.vdot(ia, b) expected = numpy.vdot(a, b) - _assert_selective_dtype_allclose(result, expected, dtype) + assert_dtype_allclose(result, expected) result = dpnp.vdot(b, ia) expected = numpy.vdot(b, a) - _assert_selective_dtype_allclose(result, expected, dtype) + assert_dtype_allclose(result, expected) @pytest.mark.parametrize("dtype", get_all_dtypes(no_none=True)) @pytest.mark.parametrize( diff --git a/dpnp/tests/test_sort.py b/dpnp/tests/test_sort.py index 0a4fdfec528..665ab8bee45 100644 --- a/dpnp/tests/test_sort.py +++ b/dpnp/tests/test_sort.py @@ -369,8 +369,13 @@ def test_complex(self, dtype): assert result.dtype == expected.dtype -@pytest.mark.parametrize("kth", [0, 1], ids=["0", "1"]) -@pytest.mark.parametrize("dtype", get_all_dtypes(no_none=True)) +@pytest.mark.parametrize("kth", [0, 1]) +@pytest.mark.parametrize( + "dtype", + get_all_dtypes( + no_none=True, no_unsigned=True, xfail_dtypes=[dpnp.int8, dpnp.int16] + ), +) @pytest.mark.parametrize( "array", [ diff --git a/dpnp/tests/test_strides.py b/dpnp/tests/test_strides.py index 0f6732ab9a4..beacf6109fa 100644 --- a/dpnp/tests/test_strides.py +++ b/dpnp/tests/test_strides.py @@ -161,7 +161,10 @@ def test_logsumexp(dtype): result = dpnp.logsumexp(dpa) expected = numpy.logaddexp.reduce(a) - assert_allclose(result, expected) + # for int8, uint8, NumPy returns float16 but dpnp returns float64 + # for int16, uint16, NumPy returns float32 but dpnp returns float64 + flag = dtype in [dpnp.int8, dpnp.uint8, dpnp.int16, dpnp.uint16] + assert_dtype_allclose(result, expected, check_only_type_kind=flag) @pytest.mark.parametrize("dtype", get_all_dtypes(no_bool=True, no_complex=True)) @@ -171,7 +174,10 @@ def test_cumlogsumexp(dtype): result = dpnp.cumlogsumexp(dpa) expected = numpy.logaddexp.accumulate(a) - assert_allclose(result, expected) + # for int8, uint8, NumPy returns float16 but dpnp returns float64 + # for int16, uint16, NumPy returns float32 but dpnp returns float64 + flag = dtype in [dpnp.int8, dpnp.uint8, dpnp.int16, dpnp.uint16] + assert_dtype_allclose(result, expected, check_only_type_kind=flag) @pytest.mark.parametrize("dtype", get_all_dtypes(no_bool=True, no_complex=True)) @@ -181,15 +187,24 @@ def test_reduce_hypot(dtype): result = dpnp.reduce_hypot(dpa) expected = numpy.hypot.reduce(a) - assert_allclose(result, expected) + # for int8, uint8, NumPy returns float16 but dpnp returns float64 + # for int16, uint16, NumPy returns float32 but dpnp returns float64 + flag = dtype in [dpnp.int8, dpnp.uint8, dpnp.int16, dpnp.uint16] + assert_dtype_allclose(result, expected, check_only_type_kind=flag) -@pytest.mark.parametrize("dtype", get_all_dtypes(no_bool=True, no_complex=True)) -@pytest.mark.parametrize("shape", [(10,)], ids=["(10,)"]) -def test_strides_erf(dtype, shape): - a = dpnp.reshape( - dpnp.linspace(-1, 1, num=numpy.prod(shape), dtype=dtype), shape - ) +@pytest.mark.parametrize( + "dtype", + get_all_dtypes( + no_none=True, + no_bool=True, + no_complex=True, + no_unsigned=True, + xfail_dtypes=[dpnp.int8, dpnp.int16], + ), +) +def test_strides_erf(dtype): + a = dpnp.linspace(-1, 1, num=10, dtype=dtype) b = a[::2] result = dpnp.erf(b) diff --git a/dpnp/tests/test_sum.py b/dpnp/tests/test_sum.py index 21ecab42a6a..54a998bfa3a 100644 --- a/dpnp/tests/test_sum.py +++ b/dpnp/tests/test_sum.py @@ -2,14 +2,13 @@ import numpy import pytest -from numpy.testing import ( - assert_array_equal, -) +from numpy.testing import assert_array_equal import dpnp from .helper import ( assert_dtype_allclose, + generate_random_numpy_array, get_all_dtypes, get_float_dtypes, ) @@ -32,14 +31,13 @@ (40, 35), ], ) -@pytest.mark.parametrize("dtype_in", get_all_dtypes()) +@pytest.mark.parametrize("dtype_in", get_all_dtypes(no_none=True)) @pytest.mark.parametrize("dtype_out", get_all_dtypes()) @pytest.mark.parametrize("transpose", [True, False]) @pytest.mark.parametrize("keepdims", [True, False]) @pytest.mark.parametrize("order", ["C", "F"]) def test_sum(shape, dtype_in, dtype_out, transpose, keepdims, order): - size = numpy.prod(shape) - a_np = numpy.arange(size).astype(dtype_in).reshape(shape, order=order) + a_np = generate_random_numpy_array(shape, dtype_in, order) a = dpnp.asarray(a_np) if transpose: @@ -53,9 +51,18 @@ def test_sum(shape, dtype_in, dtype_out, transpose, keepdims, order): axes.append(tuple(axes_range)) for axis in axes: + if ( + numpy.issubdtype(dtype_out, numpy.bool_) + and numpy.issubdtype(dtype_in, numpy.signedinteger) + and not a_np.sum(axis=axis).all() + ): + # TODO: remove workaround when dpctl-issue#1944 is resolved + a = a.astype(dpnp.bool) + dpnp_res = a.sum(axis=axis, dtype=dtype_out, keepdims=keepdims) + else: + dpnp_res = a.sum(axis=axis, dtype=dtype_out, keepdims=keepdims) numpy_res = a_np.sum(axis=axis, dtype=dtype_out, keepdims=keepdims) - dpnp_res = a.sum(axis=axis, dtype=dtype_out, keepdims=keepdims) - assert_array_equal(numpy_res, dpnp_res.asnumpy()) + assert_dtype_allclose(dpnp_res, numpy_res, factor=16) @pytest.mark.parametrize("dtype", get_all_dtypes(no_bool=True)) diff --git a/dpnp/tests/test_umath.py b/dpnp/tests/test_umath.py index 65b7908b09f..46ab9681e5d 100644 --- a/dpnp/tests/test_umath.py +++ b/dpnp/tests/test_umath.py @@ -12,6 +12,7 @@ from .helper import ( assert_dtype_allclose, + get_abs_array, get_all_dtypes, get_float_complex_dtypes, get_float_dtypes, @@ -180,8 +181,16 @@ def _get_numpy_arrays_2in_1out(func_name, dtype, range): def _get_output_data_type(dtype): """Return a data type specified by input `dtype` and device capabilities.""" - if dpnp.issubdtype(dtype, dpnp.bool): + dtype_float16 = any( + dpnp.issubdtype(dtype, t) for t in (dpnp.bool, dpnp.int8, dpnp.uint8) + ) + dtype_float32 = any( + dpnp.issubdtype(dtype, t) for t in (dpnp.int16, dpnp.uint16) + ) + if dtype_float16: out_dtype = dpnp.float16 if has_support_aspect16() else dpnp.float32 + elif dtype_float32: + out_dtype = dpnp.float32 elif dpnp.issubdtype(dtype, dpnp.complexfloating): out_dtype = dpnp.complex64 if has_support_aspect64() and dtype != dpnp.complex64: @@ -317,7 +326,7 @@ class TestDegrees: "dtype", get_all_dtypes(no_none=True, no_complex=True) ) def test_basic(self, dtype): - a = numpy.array([numpy.pi, -0.5 * numpy.pi], dtype=dtype) + a = get_abs_array([numpy.pi, -0.5 * numpy.pi], dtype) ia = dpnp.array(a) result = dpnp.degrees(ia) @@ -356,7 +365,9 @@ def test_type_conversion(self, dt1, dt2): assert_dtype_allclose(result, expected, check_only_type_kind=True) @pytest.mark.usefixtures("suppress_invalid_numpy_warnings") - @pytest.mark.parametrize("dt", get_all_dtypes(no_none=True)) + @pytest.mark.parametrize( + "dt", get_all_dtypes(no_none=True, no_unsigned=True) + ) def test_negative_base_value(self, dt): a = numpy.array([-1, -4], dtype=dt) ia = dpnp.array(a) @@ -365,7 +376,9 @@ def test_negative_base_value(self, dt): expected = numpy.float_power(a, 1.5) assert_allclose(result, expected) - @pytest.mark.parametrize("dt", get_all_dtypes(no_none=True)) + @pytest.mark.parametrize( + "dt", get_all_dtypes(no_none=True, no_unsigned=True) + ) def test_negative_base_value_complex_dtype(self, dt): a = numpy.array([-1, -4], dtype=dt) ia = dpnp.array(a) @@ -460,7 +473,8 @@ def test_values(self, dt): assert_dtype_allclose(result, expected) @pytest.mark.parametrize( - "dt", get_all_dtypes(no_none=True, no_complex=True) + "dt", + [numpy.bool_, numpy.int32, numpy.int64, numpy.float32, numpy.float64], ) def test_range(self, dt): a = numpy.array([1000000, -1000000, 1000200, -1000200], dtype=dt) @@ -508,7 +522,7 @@ class TestRadians: "dtype", get_all_dtypes(no_none=True, no_complex=True) ) def test_basic(self, dtype): - a = numpy.array([180.0, -90.0], dtype=dtype) + a = get_abs_array([120.0, -90.0], dtype) ia = dpnp.array(a) result = dpnp.radians(ia) @@ -712,6 +726,7 @@ class TestUmath: def func_params(self, request): return request.param + @pytest.mark.filterwarnings("ignore:overflow encountered:RuntimeWarning") @pytest.mark.usefixtures("suppress_divide_invalid_numpy_warnings") @pytest.mark.parametrize("dtype", get_all_dtypes()) def test_out(self, func_params, dtype): diff --git a/dpnp/tests/third_party/cupy/testing/_loops.py b/dpnp/tests/third_party/cupy/testing/_loops.py index e9a0fde7104..603ec22b1a2 100644 --- a/dpnp/tests/third_party/cupy/testing/_loops.py +++ b/dpnp/tests/third_party/cupy/testing/_loops.py @@ -1082,30 +1082,17 @@ def _get_int_bool_dtypes(): _complex_dtypes = _get_supported_complex_dtypes() _regular_float_dtypes = _get_supported_float_dtypes() -_float_dtypes = _get_float_dtypes() -_signed_dtypes = _get_signed_dtypes() -_unsigned_dtypes = _get_unsigned_dtypes() -_int_dtypes = _get_int_dtypes() -_int_bool_dtypes = _get_int_bool_dtypes() +_float_dtypes = _regular_float_dtypes +_signed_dtypes = () +_unsigned_dtypes = tuple(numpy.dtype(i).type for i in "BHILQ") +_int_dtypes = _signed_dtypes + _unsigned_dtypes +_int_bool_dtypes = _int_dtypes _regular_dtypes = _regular_float_dtypes + _int_bool_dtypes _dtypes = _float_dtypes + _int_bool_dtypes def _make_all_dtypes(no_float16, no_bool, no_complex): - if no_float16: - dtypes = _regular_float_dtypes - else: - dtypes = _float_dtypes - - if no_bool: - dtypes += _int_dtypes - else: - dtypes += _int_bool_dtypes - - if config.complex_types and not no_complex: - dtypes += _complex_dtypes - - return dtypes + return (numpy.int64, numpy.int32) + _get_supported_float_dtypes() def for_all_dtypes(