From 2bd0227af46b8d3119953d26b996893285deda61 Mon Sep 17 00:00:00 2001 From: Vahid Tavanashad Date: Wed, 5 Mar 2025 13:27:13 -0600 Subject: [PATCH 01/11] update test_umath.py --- dpnp/tests/test_binary_ufuncs.py | 84 ++++---- dpnp/tests/test_mathematical.py | 57 ++---- dpnp/tests/test_umath.py | 322 +++++++++++++------------------ 3 files changed, 179 insertions(+), 284 deletions(-) diff --git a/dpnp/tests/test_binary_ufuncs.py b/dpnp/tests/test_binary_ufuncs.py index 4823b5a1cd9a..54dd33957dde 100644 --- a/dpnp/tests/test_binary_ufuncs.py +++ b/dpnp/tests/test_binary_ufuncs.py @@ -13,6 +13,7 @@ from .helper import ( assert_dtype_allclose, + generate_random_numpy_array, get_abs_array, get_all_dtypes, get_complex_dtypes, @@ -22,10 +23,7 @@ has_support_aspect16, numpy_version, ) -from .test_umath import ( - _get_numpy_arrays_2in_1out, - _get_output_data_type, -) +from .test_umath import _get_output_data_type """ The scope includes tests with only functions which are instances of @@ -39,7 +37,9 @@ class TestAdd: @pytest.mark.parametrize("dtype", ALL_DTYPES) def test_add(self, dtype): - a, b, expected = _get_numpy_arrays_2in_1out("add", dtype, [-5, 5, 10]) + a = generate_random_numpy_array(10, dtype) + b = generate_random_numpy_array(10, dtype) + expected = numpy.add(a, b) ia, ib = dpnp.array(a), dpnp.array(b) iout = dpnp.empty(expected.shape, dtype=dtype) @@ -139,37 +139,19 @@ def test_invalid_out(self, xp, out): assert_raises(TypeError, xp.add, a, 2, out) +@pytest.mark.parametrize("func", ["fmax", "fmin", "maximum", "minimum"]) class TestBoundFuncs: - @pytest.fixture( - params=[ - {"func_name": "fmax", "input_values": [-5, 5, 10]}, - {"func_name": "fmin", "input_values": [-5, 5, 10]}, - {"func_name": "maximum", "input_values": [-5, 5, 10]}, - {"func_name": "minimum", "input_values": [-5, 5, 10]}, - ], - ids=[ - "fmax", - "fmin", - "maximum", - "minimum", - ], - ) - def func_params(self, request): - return request.param - @pytest.mark.parametrize( "dtype", get_all_dtypes(no_bool=True, no_complex=True) ) - def test_out(self, func_params, dtype): - func_name = func_params["func_name"] - input_values = func_params["input_values"] - a, b, expected = _get_numpy_arrays_2in_1out( - func_name, dtype, input_values - ) + def test_out(self, func, dtype): + a = generate_random_numpy_array(10, dtype) + b = generate_random_numpy_array(10, dtype) + expected = getattr(numpy, func)(a, b) ia, ib = dpnp.array(a), dpnp.array(b) iout = dpnp.empty(expected.shape, dtype=dtype) - result = getattr(dpnp, func_name)(ia, ib, out=iout) + result = getattr(dpnp, func)(ia, ib, out=iout) assert result is iout assert_dtype_allclose(result, expected) @@ -177,25 +159,23 @@ def test_out(self, func_params, dtype): @pytest.mark.parametrize( "dtype", get_all_dtypes(no_bool=True, no_complex=True) ) - def test_out_overlap(self, func_params, dtype): - func_name = func_params["func_name"] + def test_out_overlap(self, func, dtype): size = 15 a = numpy.arange(2 * size, dtype=dtype) ia = dpnp.array(a) - getattr(dpnp, func_name)(ia[size::], ia[::2], out=ia[:size:]) - getattr(numpy, func_name)(a[size::], a[::2], out=a[:size:]) + getattr(dpnp, func)(ia[size::], ia[::2], out=ia[:size:]) + getattr(numpy, func)(a[size::], a[::2], out=a[:size:]) assert_dtype_allclose(ia, a) @pytest.mark.parametrize("shape", [(0,), (15,), (2, 2)]) - def test_invalid_shape(self, func_params, shape): - func_name = func_params["func_name"] + def test_invalid_shape(self, func, shape): a, b = dpnp.arange(10), dpnp.arange(10) out = dpnp.empty(shape) with pytest.raises(ValueError): - getattr(dpnp, func_name)(a, b, out=out) + getattr(dpnp, func)(a, b, out=out) @pytest.mark.parametrize("xp", [dpnp, numpy]) @pytest.mark.parametrize( @@ -203,10 +183,9 @@ def test_invalid_shape(self, func_params, shape): [4, (), [], (3, 7), [2, 4]], ids=["scalar", "empty_tuple", "empty_list", "tuple", "list"], ) - def test_invalid_out(self, func_params, xp, out): - func_name = func_params["func_name"] + def test_invalid_out(self, func, xp, out): a = xp.arange(10) - assert_raises(TypeError, getattr(xp, func_name), a, 2, out) + assert_raises(TypeError, getattr(xp, func), a, 2, out) class TestDivide: @@ -215,9 +194,9 @@ class TestDivide: "dtype", get_all_dtypes(no_none=True, no_bool=True) ) def test_divide(self, dtype): - a, b, expected = _get_numpy_arrays_2in_1out( - "divide", dtype, [-5, 5, 10] - ) + a = generate_random_numpy_array(10, dtype) + b = generate_random_numpy_array(10, dtype) + expected = numpy.divide(a, b) ia, ib = dpnp.array(a), dpnp.array(b) if numpy.issubdtype(dtype, numpy.integer): @@ -318,7 +297,9 @@ def do_inplace_op(self, base, other, func): @pytest.mark.usefixtures("suppress_divide_numpy_warnings") @pytest.mark.parametrize("dtype", ALL_DTYPES) def test_basic(self, func, dtype): - a, b, expected = _get_numpy_arrays_2in_1out(func, dtype, [-5, 5, 10]) + a = generate_random_numpy_array(10, dtype) + b = generate_random_numpy_array(10, dtype) + expected = getattr(numpy, func)(a, b) ia, ib = dpnp.array(a), dpnp.array(b) iout = dpnp.empty(expected.shape, dtype=dtype) @@ -602,9 +583,9 @@ class TestMultiply: @pytest.mark.parametrize("dtype", ALL_DTYPES) def test_multiply(self, dtype): - a, b, expected = _get_numpy_arrays_2in_1out( - "multiply", dtype, [0, 10, 10] - ) + a = generate_random_numpy_array(10, dtype) + b = generate_random_numpy_array(10, dtype) + expected = numpy.multiply(a, b) ia, ib = dpnp.array(a), dpnp.array(b) iout = dpnp.empty(expected.shape, dtype=dtype) @@ -853,8 +834,9 @@ def test_basic(self, array, val, data_type, val_type): @pytest.mark.parametrize("dtype", ALL_DTYPES) def test_power(self, dtype): - numpy.random.seed(42) - a, b, expected = _get_numpy_arrays_2in_1out("power", dtype, [0, 10, 10]) + a = generate_random_numpy_array(10, dtype, low=0) + b = generate_random_numpy_array(10, dtype, low=0) + expected = numpy.power(a, b) ia, ib = dpnp.array(a), dpnp.array(b) out_dtype = numpy.int8 if dtype == numpy.bool_ else dtype @@ -1075,9 +1057,9 @@ class TestSubtract: @pytest.mark.parametrize("dtype", ALL_DTYPES) def test_add(self, dtype): - a, b, expected = _get_numpy_arrays_2in_1out( - "subtract", dtype, [-5, 5, 10] - ) + a = generate_random_numpy_array(10, dtype) + b = generate_random_numpy_array(10, dtype) + expected = numpy.subtract(a, b) ia, ib = dpnp.array(a), dpnp.array(b) iout = dpnp.empty(expected.shape, dtype=dtype) diff --git a/dpnp/tests/test_mathematical.py b/dpnp/tests/test_mathematical.py index d53be2fb4665..b79d07e456d6 100644 --- a/dpnp/tests/test_mathematical.py +++ b/dpnp/tests/test_mathematical.py @@ -33,11 +33,7 @@ has_support_aspect64, numpy_version, ) -from .test_umath import ( - _get_numpy_arrays_1in_1out, - _get_numpy_arrays_2in_1out, - _get_output_data_type, -) +from .test_umath import _get_output_data_type from .third_party.cupy import testing @@ -2414,34 +2410,17 @@ def test_projection(self, dtype): assert_allclose(result, expected) +@pytest.mark.parametrize("func", ["ceil", "floor", "trunc"]) class TestRoundingFuncs: - @pytest.fixture( - params=[ - {"func_name": "ceil", "input_values": [-5, 5, 10]}, - {"func_name": "floor", "input_values": [-5, 5, 10]}, - {"func_name": "trunc", "input_values": [-5, 5, 10]}, - ], - ids=[ - "ceil", - "floor", - "trunc", - ], - ) - def func_params(self, request): - return request.param - @pytest.mark.parametrize("dtype", get_all_dtypes(no_complex=True)) - def test_out(self, func_params, dtype): - func_name = func_params["func_name"] - input_values = func_params["input_values"] - np_array, expected = _get_numpy_arrays_1in_1out( - func_name, dtype, input_values - ) + def test_out(self, func, dtype): + a = generate_random_numpy_array(10, dtype) + expected = getattr(numpy, func)(a) - dp_array = dpnp.array(np_array) + dp_array = dpnp.array(a) out_dtype = numpy.int8 if dtype == numpy.bool_ else dtype dp_out = dpnp.empty(expected.shape, dtype=out_dtype) - result = getattr(dpnp, func_name)(dp_array, out=dp_out) + result = getattr(dpnp, func)(dp_array, out=dp_out) assert result is dp_out # numpy.ceil, numpy.floor, numpy.trunc always return float dtype for @@ -2457,25 +2436,23 @@ def test_out(self, func_params, dtype): @pytest.mark.parametrize( "dtype", get_all_dtypes(no_complex=True, no_none=True)[:-1] ) - def test_invalid_dtype(self, func_params, dtype): - func_name = func_params["func_name"] + def test_invalid_dtype(self, func, dtype): dpnp_dtype = get_all_dtypes(no_complex=True, no_none=True)[-1] dp_array = dpnp.arange(10, dtype=dpnp_dtype) dp_out = dpnp.empty(10, dtype=dtype) with pytest.raises(ValueError): - getattr(dpnp, func_name)(dp_array, out=dp_out) + getattr(dpnp, func)(dp_array, out=dp_out) @pytest.mark.parametrize( - "shape", [(0,), (15,), (2, 2)], ids=["(0,)", "(15, )", "(2,2)"] + "shape", [(0,), (15,), (2, 2)], ids=["(0,)", "(15,)", "(2, 2)"] ) - def test_invalid_shape(self, func_params, shape): - func_name = func_params["func_name"] + def test_invalid_shape(self, func, shape): dp_array = dpnp.arange(10, dtype=dpnp.float32) dp_out = dpnp.empty(shape, dtype=dpnp.float32) with pytest.raises(ValueError): - getattr(dpnp, func_name)(dp_array, out=dp_out) + getattr(dpnp, func)(dp_array, out=dp_out) class TestHypot: @@ -2483,12 +2460,12 @@ class TestHypot: "dtype", get_all_dtypes(no_bool=True, no_complex=True) ) def test_hypot(self, dtype): - np_array1, np_array2, expected = _get_numpy_arrays_2in_1out( - "hypot", dtype, [0, 10, 10] - ) + a = generate_random_numpy_array(10, dtype, low=0) + b = generate_random_numpy_array(10, dtype, low=0) + expected = numpy.hypot(a, b) - dp_array1 = dpnp.array(np_array1) - dp_array2 = dpnp.array(np_array2) + dp_array1 = dpnp.array(a) + dp_array2 = dpnp.array(b) out_dtype = _get_output_data_type(dtype) dp_out = dpnp.empty(expected.shape, dtype=out_dtype) result = dpnp.hypot(dp_array1, dp_array2, out=dp_out) diff --git a/dpnp/tests/test_umath.py b/dpnp/tests/test_umath.py index 526586564da6..7e3b719d5946 100644 --- a/dpnp/tests/test_umath.py +++ b/dpnp/tests/test_umath.py @@ -12,6 +12,7 @@ from .helper import ( assert_dtype_allclose, + generate_random_numpy_array, get_abs_array, get_all_dtypes, get_float_complex_dtypes, @@ -108,64 +109,6 @@ def test_umaths(test_cases): assert_allclose(result, expected, rtol=1e-6) -def _get_numpy_arrays_1in_1out(func_name, dtype, range): - """ - Return a sample array and an output array. - - Create an appropriate array specified by `dtype` and `range` which is used as - an input for a function specified by `func_name` to obtain the output. - """ - low = range[0] - high = range[1] - size = range[2] - if dtype == dpnp.bool: - np_array = numpy.arange(2, dtype=dtype) - result = getattr(numpy, func_name)(np_array) - elif dpnp.issubdtype(dtype, dpnp.complexfloating): - a = numpy.random.uniform(low=low, high=high, size=size) - b = numpy.random.uniform(low=low, high=high, size=size) - np_array = numpy.array(a + 1j * b, dtype=dtype) - result = getattr(numpy, func_name)(np_array) - else: - a = numpy.random.uniform(low=low, high=high, size=size) - np_array = numpy.array(a, dtype=dtype) - result = getattr(numpy, func_name)(np_array) - - return np_array, result - - -def _get_numpy_arrays_2in_1out(func_name, dtype, range): - """ - Return two sample arrays and an output array. - - Create two appropriate arrays specified by `dtype` and `range` which are - used as inputs for a function specified by `func_name` to obtain the output. - """ - low = range[0] - high = range[1] - size = range[2] - if dtype == dpnp.bool: - np_array1 = numpy.arange(2, dtype=dtype) - np_array2 = numpy.arange(2, dtype=dtype) - result = getattr(numpy, func_name)(np_array1, np_array2) - elif dpnp.issubdtype(dtype, dpnp.complexfloating): - a = numpy.random.uniform(low=low, high=high, size=size) - b = numpy.random.uniform(low=low, high=high, size=size) - np_array1 = numpy.array(a + 1j * b, dtype=dtype) - a = numpy.random.uniform(low=low, high=high, size=size) - b = numpy.random.uniform(low=low, high=high, size=size) - np_array2 = numpy.array(a + 1j * b, dtype=dtype) - result = getattr(numpy, func_name)(np_array1, np_array2) - else: - a = numpy.random.uniform(low=low, high=high, size=size) - np_array1 = numpy.array(a, dtype=dtype) - a = numpy.random.uniform(low=low, high=high, size=size) - np_array2 = numpy.array(a, dtype=dtype) - result = getattr(numpy, func_name)(np_array1, np_array2) - - return np_array1, np_array2, result - - def _get_output_data_type(dtype): """Return a data type specified by input `dtype` and device capabilities.""" dtype_float16 = any( @@ -193,17 +136,16 @@ def _get_output_data_type(dtype): class TestArctan2: @pytest.mark.parametrize("dtype", get_all_dtypes(no_complex=True)) def test_arctan2(self, dtype): - np_array1, np_array2, expected = _get_numpy_arrays_2in_1out( - "arctan2", dtype, [0, 10, 10] - ) + a = generate_random_numpy_array(10, dtype, low=0) + b = generate_random_numpy_array(10, dtype, low=0) + expected = numpy.arctan2(a, b) - dp_array1 = dpnp.array(np_array1) - dp_array2 = dpnp.array(np_array2) + ia, ib = dpnp.array(a), dpnp.array(b) out_dtype = _get_output_data_type(dtype) - dp_out = dpnp.empty(expected.shape, dtype=out_dtype) - result = dpnp.arctan2(dp_array1, dp_array2, out=dp_out) + iout = dpnp.empty(expected.shape, dtype=out_dtype) + result = dpnp.arctan2(ia, ib, out=iout) - assert result is dp_out + assert result is iout assert_dtype_allclose(result, expected) @pytest.mark.parametrize( @@ -211,20 +153,20 @@ def test_arctan2(self, dtype): ) def test_invalid_dtype(self, dtype): dpnp_dtype = get_all_dtypes(no_complex=True, no_none=True)[-1] - dp_array = dpnp.arange(10, dtype=dpnp_dtype) - dp_out = dpnp.empty(10, dtype=dtype) + a = dpnp.arange(10, dtype=dpnp_dtype) + iout = dpnp.empty(10, dtype=dtype) with pytest.raises(ValueError): - dpnp.arctan2(dp_array, dp_array, out=dp_out) + dpnp.arctan2(a, a, out=iout) @pytest.mark.parametrize( "shape", [(0,), (15,), (2, 2)], ids=["(0,)", "(15, )", "(2,2)"] ) def test_invalid_shape(self, shape): - dp_array = dpnp.arange(10) - dp_out = dpnp.empty(shape) + a = dpnp.arange(10) + iout = dpnp.empty(shape) with pytest.raises(ValueError): - dpnp.arctan2(dp_array, dp_array, out=dp_out) + dpnp.arctan2(a, a, out=iout) def test_alias(self): x = dpnp.array([-1, +1, +1, -1]) @@ -238,16 +180,15 @@ def test_alias(self): class TestCbrt: @pytest.mark.parametrize("dtype", get_all_dtypes(no_complex=True)) def test_cbrt(self, dtype): - np_array, expected = _get_numpy_arrays_1in_1out( - "cbrt", dtype, [-5, 5, 10] - ) + a = generate_random_numpy_array(10, dtype) + expected = numpy.cbrt(a) - dp_array = dpnp.array(np_array) + ia = dpnp.array(a) out_dtype = _get_output_data_type(dtype) - dp_out = dpnp.empty(expected.shape, dtype=out_dtype) - result = dpnp.cbrt(dp_array, out=dp_out) + iout = dpnp.empty(expected.shape, dtype=out_dtype) + result = dpnp.cbrt(ia, out=iout) - assert result is dp_out + assert result is iout assert_dtype_allclose(result, expected) @pytest.mark.parametrize( @@ -255,37 +196,36 @@ def test_cbrt(self, dtype): ) def test_invalid_dtype(self, dtype): dpnp_dtype = get_all_dtypes(no_complex=True, no_none=True)[-1] - dp_array = dpnp.arange(10, dtype=dpnp_dtype) - dp_out = dpnp.empty(10, dtype=dtype) + a = dpnp.arange(10, dtype=dpnp_dtype) + iout = dpnp.empty(10, dtype=dtype) with pytest.raises(ValueError): - dpnp.cbrt(dp_array, out=dp_out) + dpnp.cbrt(a, out=iout) @pytest.mark.parametrize( "shape", [(0,), (15,), (2, 2)], ids=["(0,)", "(15, )", "(2,2)"] ) def test_invalid_shape(self, shape): - dp_array = dpnp.arange(10) - dp_out = dpnp.empty(shape) + a = dpnp.arange(10) + iout = dpnp.empty(shape) with pytest.raises(ValueError): - dpnp.cbrt(dp_array, out=dp_out) + dpnp.cbrt(a, out=iout) class TestCopySign: @pytest.mark.parametrize("dtype", get_all_dtypes(no_complex=True)) def test_copysign(self, dtype): - np_array1, np_array2, expected = _get_numpy_arrays_2in_1out( - "copysign", dtype, [0, 10, 10] - ) + a = generate_random_numpy_array(10, dtype, low=0) + b = generate_random_numpy_array(10, dtype, low=0) + expected = numpy.copysign(a, b) - dp_array1 = dpnp.array(np_array1) - dp_array2 = dpnp.array(np_array2) + ia, ib = dpnp.array(a), dpnp.array(b) out_dtype = _get_output_data_type(dtype) - dp_out = dpnp.empty(expected.shape, dtype=out_dtype) - result = dpnp.copysign(dp_array1, dp_array2, out=dp_out) + iout = dpnp.empty(expected.shape, dtype=out_dtype) + result = dpnp.copysign(ia, ib, out=iout) - assert result is dp_out + assert result is iout assert_dtype_allclose(result, expected) @pytest.mark.parametrize( @@ -293,19 +233,19 @@ def test_copysign(self, dtype): ) def test_invalid_dtype(self, dtype): dpnp_dtype = get_all_dtypes(no_complex=True, no_none=True)[-1] - dp_array = dpnp.arange(10, dtype=dpnp_dtype) - dp_out = dpnp.empty(10, dtype=dtype) + a = dpnp.arange(10, dtype=dpnp_dtype) + iout = dpnp.empty(10, dtype=dtype) with pytest.raises(ValueError): - dpnp.copysign(dp_array, dp_array, out=dp_out) + dpnp.copysign(a, a, out=iout) @pytest.mark.parametrize( - "shape", [(0,), (15,), (2, 2)], ids=["(0,)", "(15, )", "(2,2)"] + "shape", [(0,), (15,), (2, 2)], ids=["(0,)", "(15,)", "(2, 2)"] ) def test_invalid_shape(self, shape): - dp_array = dpnp.arange(10) - dp_out = dpnp.empty(shape) + a = dpnp.arange(10) + iout = dpnp.empty(shape) with pytest.raises(ValueError): - dpnp.copysign(dp_array, dp_array, out=dp_out) + dpnp.copysign(a, a, out=iout) class TestDegrees: @@ -393,17 +333,16 @@ def test_nan_infs_base(self, exp_val, dtype): class TestLogAddExp: @pytest.mark.parametrize("dtype", get_all_dtypes(no_complex=True)) def test_logaddexp(self, dtype): - np_array1, np_array2, expected = _get_numpy_arrays_2in_1out( - "logaddexp", dtype, [0, 10, 10] - ) + a = generate_random_numpy_array(10, dtype, low=0) + b = generate_random_numpy_array(10, dtype, low=0) + expected = numpy.logaddexp(a, b) - dp_array1 = dpnp.array(np_array1) - dp_array2 = dpnp.array(np_array2) + ia, ib = dpnp.array(a), dpnp.array(b) out_dtype = _get_output_data_type(dtype) - dp_out = dpnp.empty(expected.shape, dtype=out_dtype) - result = dpnp.logaddexp(dp_array1, dp_array2, out=dp_out) + iout = dpnp.empty(expected.shape, dtype=out_dtype) + result = dpnp.logaddexp(ia, ib, out=iout) - assert result is dp_out + assert result is iout assert_dtype_allclose(result, expected) @pytest.mark.parametrize( @@ -411,19 +350,19 @@ def test_logaddexp(self, dtype): ) def test_invalid_dtype(self, dtype): dpnp_dtype = get_all_dtypes(no_complex=True, no_none=True)[-1] - dp_array = dpnp.arange(10, dtype=dpnp_dtype) - dp_out = dpnp.empty(10, dtype=dtype) + a = dpnp.arange(10, dtype=dpnp_dtype) + iout = dpnp.empty(10, dtype=dtype) with pytest.raises(ValueError): - dpnp.logaddexp(dp_array, dp_array, out=dp_out) + dpnp.logaddexp(a, a, out=iout) @pytest.mark.parametrize( - "shape", [(0,), (15,), (2, 2)], ids=["(0,)", "(15, )", "(2,2)"] + "shape", [(0,), (15,), (2, 2)], ids=["(0,)", "(15,)", "(2, 2)"] ) def test_invalid_shape(self, shape): - dp_array = dpnp.arange(10) - dp_out = dpnp.empty(shape) + a = dpnp.arange(10) + iout = dpnp.empty(shape) with pytest.raises(ValueError): - dpnp.logaddexp(dp_array, dp_array, out=dp_out) + dpnp.logaddexp(a, a, out=iout) @pytest.mark.usefixtures("suppress_invalid_numpy_warnings") @pytest.mark.parametrize( @@ -538,53 +477,50 @@ class TestReciprocal: @pytest.mark.usefixtures("suppress_divide_numpy_warnings") @pytest.mark.parametrize("dtype", get_float_complex_dtypes()) def test_reciprocal(self, dtype): - np_array, expected = _get_numpy_arrays_1in_1out( - "reciprocal", dtype, [-5, 5, 10] - ) + a = generate_random_numpy_array(10, dtype) + expected = numpy.reciprocal(a) - dp_array = dpnp.array(np_array) + ia = dpnp.array(a) out_dtype = _get_output_data_type(dtype) - dp_out = dpnp.empty(expected.shape, dtype=out_dtype) - result = dpnp.reciprocal(dp_array, out=dp_out) + iout = dpnp.empty(expected.shape, dtype=out_dtype) + result = dpnp.reciprocal(ia, out=iout) - assert result is dp_out + assert result is iout assert_dtype_allclose(result, expected) @pytest.mark.parametrize("dtype", get_float_complex_dtypes()[:-1]) def test_invalid_dtype(self, dtype): dpnp_dtype = get_float_complex_dtypes()[-1] - dp_array = dpnp.arange(10, dtype=dpnp_dtype) - dp_out = dpnp.empty(10, dtype=dtype) + a = dpnp.arange(10, dtype=dpnp_dtype) + iout = dpnp.empty(10, dtype=dtype) with pytest.raises(ValueError): - dpnp.reciprocal(dp_array, out=dp_out) + dpnp.reciprocal(a, out=iout) @pytest.mark.parametrize( "shape", [(0,), (15,), (2, 2)], ids=["(0,)", "(15, )", "(2,2)"] ) def test_invalid_shape(self, shape): - dp_array = dpnp.arange(10) - dp_out = dpnp.empty(shape) + a = dpnp.arange(10) + iout = dpnp.empty(shape) with pytest.raises(ValueError): - dpnp.reciprocal(dp_array, out=dp_out) + dpnp.reciprocal(a, out=iout) class TestRsqrt: @pytest.mark.usefixtures("suppress_divide_numpy_warnings") @pytest.mark.parametrize("dtype", get_all_dtypes(no_complex=True)) def test_rsqrt(self, dtype): - np_array, expected = _get_numpy_arrays_1in_1out( - "sqrt", dtype, [0, 10, 10] - ) - expected = numpy.reciprocal(expected) + a = generate_random_numpy_array(10, dtype, low=0) + expected = numpy.reciprocal(numpy.sqrt(a)) - dp_array = dpnp.array(np_array) + ia = dpnp.array(a) out_dtype = _get_output_data_type(dtype) - dp_out = dpnp.empty(expected.shape, dtype=out_dtype) - result = dpnp.rsqrt(dp_array, out=dp_out) + iout = dpnp.empty(expected.shape, dtype=out_dtype) + result = dpnp.rsqrt(ia, out=iout) - assert result is dp_out + assert result is iout assert_dtype_allclose(result, expected) @pytest.mark.parametrize( @@ -592,20 +528,20 @@ def test_rsqrt(self, dtype): ) def test_invalid_dtype(self, dtype): dpnp_dtype = get_all_dtypes(no_complex=True, no_none=True)[-1] - dp_array = dpnp.arange(10, dtype=dpnp_dtype) - dp_out = dpnp.empty(10, dtype=dtype) + a = dpnp.arange(10, dtype=dpnp_dtype) + iout = dpnp.empty(10, dtype=dtype) with pytest.raises(ValueError): - dpnp.rsqrt(dp_array, out=dp_out) + dpnp.rsqrt(a, out=iout) @pytest.mark.parametrize( "shape", [(0,), (15,), (2, 2)], ids=["(0,)", "(15, )", "(2,2)"] ) def test_invalid_shape(self, shape): - dp_array = dpnp.arange(10) - dp_out = dpnp.empty(shape) + a = dpnp.arange(10) + iout = dpnp.empty(shape) with pytest.raises(ValueError): - dpnp.rsqrt(dp_array, out=dp_out) + dpnp.rsqrt(a, out=iout) @pytest.mark.parametrize( "out", @@ -620,35 +556,34 @@ def test_invalid_out(self, out): class TestSquare: @pytest.mark.parametrize("dtype", get_all_dtypes()) def test_square(self, dtype): - np_array, expected = _get_numpy_arrays_1in_1out( - "square", dtype, [-5, 5, 10] - ) + a = generate_random_numpy_array(10, dtype) + expected = numpy.square(a) - dp_array = dpnp.array(np_array) + ia = dpnp.array(a) out_dtype = numpy.int8 if dtype == dpnp.bool else dtype - dp_out = dpnp.empty(expected.shape, dtype=out_dtype) - result = dpnp.square(dp_array, out=dp_out) + iout = dpnp.empty(expected.shape, dtype=out_dtype) + result = dpnp.square(ia, out=iout) - assert result is dp_out + assert result is iout assert_dtype_allclose(result, expected) @pytest.mark.parametrize("dtype", get_all_dtypes(no_none=True)[:-1]) def test_invalid_dtype(self, dtype): dpnp_dtype = get_all_dtypes(no_none=True)[-1] - dp_array = dpnp.arange(10, dtype=dpnp_dtype) - dp_out = dpnp.empty(10, dtype=dtype) + a = dpnp.arange(10, dtype=dpnp_dtype) + iout = dpnp.empty(10, dtype=dtype) with pytest.raises(ValueError): - dpnp.square(dp_array, out=dp_out) + dpnp.square(a, out=iout) @pytest.mark.parametrize( "shape", [(0,), (15,), (2, 2)], ids=["(0,)", "(15, )", "(2,2)"] ) def test_invalid_shape(self, shape): - dp_array = dpnp.arange(10) - dp_out = dpnp.empty(shape) + a = dpnp.arange(10) + iout = dpnp.empty(shape) with pytest.raises(ValueError): - dpnp.square(dp_array, out=dp_out) + dpnp.square(a, out=iout) @pytest.mark.parametrize("xp", [dpnp, numpy]) @pytest.mark.parametrize( @@ -664,26 +599,26 @@ def test_invalid_out(self, xp, out): class TestUmath: @pytest.fixture( params=[ - {"func_name": "arccos", "input_values": [-1, 1, 10]}, - {"func_name": "arccosh", "input_values": [1, 10, 10]}, - {"func_name": "arcsin", "input_values": [-1, 1, 10]}, - {"func_name": "arcsinh", "input_values": [-5, 5, 10]}, - {"func_name": "arctan", "input_values": [-5, 5, 10]}, - {"func_name": "arctanh", "input_values": [-1, 1, 10]}, - {"func_name": "cos", "input_values": [-5, 5, 10]}, - {"func_name": "cosh", "input_values": [-5, 5, 10]}, - {"func_name": "exp", "input_values": [-3, 8, 10]}, - {"func_name": "exp2", "input_values": [-5, 5, 10]}, - {"func_name": "expm1", "input_values": [-5, 5, 10]}, - {"func_name": "log", "input_values": [0, 10, 10]}, - {"func_name": "log10", "input_values": [0, 10, 10]}, - {"func_name": "log2", "input_values": [0, 10, 10]}, - {"func_name": "log1p", "input_values": [0, 10, 10]}, - {"func_name": "sin", "input_values": [-5, 5, 10]}, - {"func_name": "sinh", "input_values": [-5, 5, 10]}, - {"func_name": "sqrt", "input_values": [0, 10, 10]}, - {"func_name": "tan", "input_values": [-1.5, 1.5, 10]}, - {"func_name": "tanh", "input_values": [-5, 5, 10]}, + {"func": "arccos", "values": [-1, 1]}, + {"func": "arccosh", "values": [1, 10]}, + {"func": "arcsin", "values": [-1, 1]}, + {"func": "arcsinh", "values": [-5, 5]}, + {"func": "arctan", "values": [-5, 5]}, + {"func": "arctanh", "values": [-1, 1]}, + {"func": "cos", "values": [-5, 5]}, + {"func": "cosh", "values": [-5, 5]}, + {"func": "exp", "values": [-3, 8]}, + {"func": "exp2", "values": [-5, 5]}, + {"func": "expm1", "values": [-5, 5]}, + {"func": "log", "values": [0, 10]}, + {"func": "log10", "values": [0, 10]}, + {"func": "log2", "values": [0, 10]}, + {"func": "log1p", "values": [0, 10]}, + {"func": "sin", "values": [-5, 5]}, + {"func": "sinh", "values": [-5, 5]}, + {"func": "sqrt", "values": [0, 10]}, + {"func": "tan", "values": [-1.5, 1.5]}, + {"func": "tanh", "values": [-5, 5]}, ], ids=[ "arccos", @@ -715,39 +650,40 @@ def func_params(self, request): @pytest.mark.usefixtures("suppress_divide_invalid_numpy_warnings") @pytest.mark.parametrize("dtype", get_all_dtypes()) def test_out(self, func_params, dtype): - func_name = func_params["func_name"] - input_values = func_params["input_values"] - np_array, expected = _get_numpy_arrays_1in_1out( - func_name, dtype, input_values + func = func_params["func"] + values = func_params["values"] + a = generate_random_numpy_array( + 10, dtype, low=values[0], high=values[1] ) + expected = getattr(numpy, func)(a) - dp_array = dpnp.array(np_array) + ia = dpnp.array(a) out_dtype = _get_output_data_type(dtype) - dp_out = dpnp.empty(expected.shape, dtype=out_dtype) - result = getattr(dpnp, func_name)(dp_array, out=dp_out) + iout = dpnp.empty(expected.shape, dtype=out_dtype) + result = getattr(dpnp, func)(ia, out=iout) - assert result is dp_out + assert result is iout assert_dtype_allclose(result, expected) @pytest.mark.parametrize("dtype", get_all_dtypes(no_none=True)[:-1]) def test_invalid_dtype(self, func_params, dtype): - func_name = func_params["func_name"] + func = func_params["func"] dpnp_dtype = get_all_dtypes(no_none=True)[-1] - dp_array = dpnp.arange(10, dtype=dpnp_dtype) - dp_out = dpnp.empty(10, dtype=dtype) + a = dpnp.arange(10, dtype=dpnp_dtype) + iout = dpnp.empty(10, dtype=dtype) with pytest.raises(ValueError): - getattr(dpnp, func_name)(dp_array, out=dp_out) + getattr(dpnp, func)(a, out=iout) @pytest.mark.parametrize( "shape", [(0,), (15,), (2, 2)], ids=["(0,)", "(15, )", "(2,2)"] ) def test_invalid_shape(self, func_params, shape): - func_name = func_params["func_name"] - dp_array = dpnp.arange(10) - dp_out = dpnp.empty(shape) + func = func_params["func"] + a = dpnp.arange(10) + iout = dpnp.empty(shape) with pytest.raises(ValueError): - getattr(dpnp, func_name)(dp_array, out=dp_out) + getattr(dpnp, func)(a, out=iout) @pytest.mark.parametrize("xp", [dpnp, numpy]) @pytest.mark.parametrize( @@ -756,9 +692,9 @@ def test_invalid_shape(self, func_params, shape): ids=["scalar", "empty_tuple", "empty_list", "tuple", "list"], ) def test_invalid_out(self, func_params, xp, out): - func_name = func_params["func_name"] + func = func_params["func"] a = xp.arange(10) - assert_raises(TypeError, getattr(xp, func_name), a, out) + assert_raises(TypeError, getattr(xp, func), a, out) def test_trigonometric_hyperbolic_aliases(): From a65bb9aee522d10771d557eb752eefe47dd3820a Mon Sep 17 00:00:00 2001 From: Vahid Tavanashad Date: Thu, 20 Mar 2025 09:42:01 -0700 Subject: [PATCH 02/11] use dpnp.bool --- dpnp/tests/test_mathematical.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dpnp/tests/test_mathematical.py b/dpnp/tests/test_mathematical.py index cb7f8d9816d3..f0fc5e2ea86f 100644 --- a/dpnp/tests/test_mathematical.py +++ b/dpnp/tests/test_mathematical.py @@ -2277,7 +2277,7 @@ def test_out(self, func, dtype): expected = getattr(numpy, func)(a) ia = dpnp.array(a) - out_dt = numpy.int8 if dtype == numpy.bool_ else dtype + out_dt = numpy.int8 if dtype == dpnp.bool else dtype iout = dpnp.empty(expected.shape, dtype=out_dt) result = getattr(dpnp, func)(ia, out=iout) From 14e1044cc4d6a16fab4fc23cc202db00cae52ad8 Mon Sep 17 00:00:00 2001 From: Vahid Tavanashad Date: Fri, 21 Mar 2025 07:23:27 -0700 Subject: [PATCH 03/11] address comments --- dpnp/tests/test_binary_ufuncs.py | 19 +++++--------- dpnp/tests/test_umath.py | 43 +++++++++++++++++++------------- 2 files changed, 32 insertions(+), 30 deletions(-) diff --git a/dpnp/tests/test_binary_ufuncs.py b/dpnp/tests/test_binary_ufuncs.py index 54dd33957dde..75de6438fc19 100644 --- a/dpnp/tests/test_binary_ufuncs.py +++ b/dpnp/tests/test_binary_ufuncs.py @@ -141,9 +141,7 @@ def test_invalid_out(self, xp, out): @pytest.mark.parametrize("func", ["fmax", "fmin", "maximum", "minimum"]) class TestBoundFuncs: - @pytest.mark.parametrize( - "dtype", get_all_dtypes(no_bool=True, no_complex=True) - ) + @pytest.mark.parametrize("dtype", get_all_dtypes(no_none=True)) def test_out(self, func, dtype): a = generate_random_numpy_array(10, dtype) b = generate_random_numpy_array(10, dtype) @@ -157,7 +155,7 @@ def test_out(self, func, dtype): assert_dtype_allclose(result, expected) @pytest.mark.parametrize( - "dtype", get_all_dtypes(no_bool=True, no_complex=True) + "dtype", get_all_dtypes(no_none=True, no_bool=True) ) def test_out_overlap(self, func, dtype): size = 15 @@ -190,17 +188,15 @@ def test_invalid_out(self, func, xp, out): class TestDivide: @pytest.mark.usefixtures("suppress_divide_invalid_numpy_warnings") - @pytest.mark.parametrize( - "dtype", get_all_dtypes(no_none=True, no_bool=True) - ) + @pytest.mark.parametrize("dtype", get_all_dtypes(no_none=True)) def test_divide(self, dtype): a = generate_random_numpy_array(10, dtype) b = generate_random_numpy_array(10, dtype) expected = numpy.divide(a, b) ia, ib = dpnp.array(a), dpnp.array(b) - if numpy.issubdtype(dtype, numpy.integer): - out_dtype = map_dtype_to_device(dpnp.float64, ia.sycl_device) + if numpy.issubdtype(dtype, numpy.bool): + out_dtype = dpnp.float64 else: out_dtype = _get_output_data_type(dtype) iout = dpnp.empty(expected.shape, dtype=out_dtype) @@ -379,9 +375,9 @@ def test_invalid_out(self, func, xp, out): assert_raises(TypeError, getattr(xp, func), a, 2, out) +@pytest.mark.parametrize("func", ["fmax", "fmin"]) class TestFmaxFmin: @pytest.mark.skipif(not has_support_aspect16(), reason="no fp16 support") - @pytest.mark.parametrize("func", ["fmax", "fmin"]) def test_half(self, func): a = numpy.array([0, 1, 2, 4, 2], dtype=numpy.float16) b = numpy.array([-2, 5, 1, 4, 3], dtype=numpy.float16) @@ -396,7 +392,6 @@ def test_half(self, func): expected = getattr(numpy, func)(b, c) assert_equal(result, expected) - @pytest.mark.parametrize("func", ["fmax", "fmin"]) @pytest.mark.parametrize("dtype", get_float_dtypes()) def test_float_nans(self, func, dtype): a = numpy.array([0, numpy.nan, numpy.nan], dtype=dtype) @@ -407,7 +402,6 @@ def test_float_nans(self, func, dtype): expected = getattr(numpy, func)(a, b) assert_equal(result, expected) - @pytest.mark.parametrize("func", ["fmax", "fmin"]) @pytest.mark.parametrize("dtype", get_complex_dtypes()) @pytest.mark.parametrize( "nan_val", @@ -427,7 +421,6 @@ def test_complex_nans(self, func, dtype, nan_val): expected = getattr(numpy, func)(a, b) assert_equal(result, expected) - @pytest.mark.parametrize("func", ["fmax", "fmin"]) @pytest.mark.parametrize("dtype", get_float_dtypes(no_float16=False)) def test_precision(self, func, dtype): dtmin = numpy.finfo(dtype).min diff --git a/dpnp/tests/test_umath.py b/dpnp/tests/test_umath.py index 7e3b719d5946..ad131e660297 100644 --- a/dpnp/tests/test_umath.py +++ b/dpnp/tests/test_umath.py @@ -74,7 +74,6 @@ def get_id(val): return val.__str__() -@pytest.mark.usefixtures("allow_fall_back_on_numpy") @pytest.mark.usefixtures("suppress_divide_invalid_numpy_warnings") @pytest.mark.parametrize("test_cases", test_cases, ids=get_id) def test_umaths(test_cases): @@ -134,7 +133,9 @@ def _get_output_data_type(dtype): class TestArctan2: - @pytest.mark.parametrize("dtype", get_all_dtypes(no_complex=True)) + @pytest.mark.parametrize( + "dtype", get_all_dtypes(no_none=True, no_complex=True) + ) def test_arctan2(self, dtype): a = generate_random_numpy_array(10, dtype, low=0) b = generate_random_numpy_array(10, dtype, low=0) @@ -149,10 +150,10 @@ def test_arctan2(self, dtype): assert_dtype_allclose(result, expected) @pytest.mark.parametrize( - "dtype", get_all_dtypes(no_complex=True, no_none=True)[:-1] + "dtype", get_all_dtypes(no_none=True, no_complex=True)[:-1] ) def test_invalid_dtype(self, dtype): - dpnp_dtype = get_all_dtypes(no_complex=True, no_none=True)[-1] + dpnp_dtype = get_all_dtypes(no_none=True, no_complex=True)[-1] a = dpnp.arange(10, dtype=dpnp_dtype) iout = dpnp.empty(10, dtype=dtype) @@ -178,7 +179,9 @@ def test_alias(self): class TestCbrt: - @pytest.mark.parametrize("dtype", get_all_dtypes(no_complex=True)) + @pytest.mark.parametrize( + "dtype", get_all_dtypes(no_none=True, no_complex=True) + ) def test_cbrt(self, dtype): a = generate_random_numpy_array(10, dtype) expected = numpy.cbrt(a) @@ -192,10 +195,10 @@ def test_cbrt(self, dtype): assert_dtype_allclose(result, expected) @pytest.mark.parametrize( - "dtype", get_all_dtypes(no_complex=True, no_none=True)[:-1] + "dtype", get_all_dtypes(no_none=True, no_complex=True)[:-1] ) def test_invalid_dtype(self, dtype): - dpnp_dtype = get_all_dtypes(no_complex=True, no_none=True)[-1] + dpnp_dtype = get_all_dtypes(no_none=True, no_complex=True)[-1] a = dpnp.arange(10, dtype=dpnp_dtype) iout = dpnp.empty(10, dtype=dtype) @@ -214,7 +217,9 @@ def test_invalid_shape(self, shape): class TestCopySign: - @pytest.mark.parametrize("dtype", get_all_dtypes(no_complex=True)) + @pytest.mark.parametrize( + "dtype", get_all_dtypes(no_none=True, no_complex=True) + ) def test_copysign(self, dtype): a = generate_random_numpy_array(10, dtype, low=0) b = generate_random_numpy_array(10, dtype, low=0) @@ -229,10 +234,10 @@ def test_copysign(self, dtype): assert_dtype_allclose(result, expected) @pytest.mark.parametrize( - "dtype", get_all_dtypes(no_complex=True, no_none=True)[:-1] + "dtype", get_all_dtypes(no_none=True, no_complex=True)[:-1] ) def test_invalid_dtype(self, dtype): - dpnp_dtype = get_all_dtypes(no_complex=True, no_none=True)[-1] + dpnp_dtype = get_all_dtypes(no_none=True, no_complex=True)[-1] a = dpnp.arange(10, dtype=dpnp_dtype) iout = dpnp.empty(10, dtype=dtype) with pytest.raises(ValueError): @@ -331,7 +336,9 @@ def test_nan_infs_base(self, exp_val, dtype): class TestLogAddExp: - @pytest.mark.parametrize("dtype", get_all_dtypes(no_complex=True)) + @pytest.mark.parametrize( + "dtype", get_all_dtypes(no_none=True, no_complex=True) + ) def test_logaddexp(self, dtype): a = generate_random_numpy_array(10, dtype, low=0) b = generate_random_numpy_array(10, dtype, low=0) @@ -346,10 +353,10 @@ def test_logaddexp(self, dtype): assert_dtype_allclose(result, expected) @pytest.mark.parametrize( - "dtype", get_all_dtypes(no_complex=True, no_none=True)[:-1] + "dtype", get_all_dtypes(no_none=True, no_complex=True)[:-1] ) def test_invalid_dtype(self, dtype): - dpnp_dtype = get_all_dtypes(no_complex=True, no_none=True)[-1] + dpnp_dtype = get_all_dtypes(no_none=True, no_complex=True)[-1] a = dpnp.arange(10, dtype=dpnp_dtype) iout = dpnp.empty(10, dtype=dtype) with pytest.raises(ValueError): @@ -510,7 +517,9 @@ def test_invalid_shape(self, shape): class TestRsqrt: @pytest.mark.usefixtures("suppress_divide_numpy_warnings") - @pytest.mark.parametrize("dtype", get_all_dtypes(no_complex=True)) + @pytest.mark.parametrize( + "dtype", get_all_dtypes(no_none=True, no_complex=True) + ) def test_rsqrt(self, dtype): a = generate_random_numpy_array(10, dtype, low=0) expected = numpy.reciprocal(numpy.sqrt(a)) @@ -524,10 +533,10 @@ def test_rsqrt(self, dtype): assert_dtype_allclose(result, expected) @pytest.mark.parametrize( - "dtype", get_all_dtypes(no_complex=True, no_none=True)[:-1] + "dtype", get_all_dtypes(no_none=True, no_complex=True)[:-1] ) def test_invalid_dtype(self, dtype): - dpnp_dtype = get_all_dtypes(no_complex=True, no_none=True)[-1] + dpnp_dtype = get_all_dtypes(no_none=True, no_complex=True)[-1] a = dpnp.arange(10, dtype=dpnp_dtype) iout = dpnp.empty(10, dtype=dtype) @@ -554,7 +563,7 @@ def test_invalid_out(self, out): class TestSquare: - @pytest.mark.parametrize("dtype", get_all_dtypes()) + @pytest.mark.parametrize("dtype", get_all_dtypes(no_none=True)) def test_square(self, dtype): a = generate_random_numpy_array(10, dtype) expected = numpy.square(a) From 563108e5ae496fbccee9c6fe386db365d8432357 Mon Sep 17 00:00:00 2001 From: Vahid Tavanashad Date: Fri, 21 Mar 2025 08:54:00 -0700 Subject: [PATCH 04/11] fix failing tests --- dpnp/tests/test_binary_ufuncs.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dpnp/tests/test_binary_ufuncs.py b/dpnp/tests/test_binary_ufuncs.py index 75de6438fc19..a9631018b2ea 100644 --- a/dpnp/tests/test_binary_ufuncs.py +++ b/dpnp/tests/test_binary_ufuncs.py @@ -195,8 +195,8 @@ def test_divide(self, dtype): expected = numpy.divide(a, b) ia, ib = dpnp.array(a), dpnp.array(b) - if numpy.issubdtype(dtype, numpy.bool): - out_dtype = dpnp.float64 + if numpy.issubdtype(dtype, numpy.integer) or dtype == dpnp.bool: + out_dtype = map_dtype_to_device(dpnp.float64, ia.sycl_device) else: out_dtype = _get_output_data_type(dtype) iout = dpnp.empty(expected.shape, dtype=out_dtype) From 1f519b904478b272d0cfb387be3c94e216cae590 Mon Sep 17 00:00:00 2001 From: Vahid Tavanashad Date: Wed, 26 Mar 2025 05:53:29 -0700 Subject: [PATCH 05/11] reduce duplication --- dpnp/tests/test_umath.py | 258 +++++++++++++++------------------------ 1 file changed, 96 insertions(+), 162 deletions(-) diff --git a/dpnp/tests/test_umath.py b/dpnp/tests/test_umath.py index ad131e660297..b14bc668f0ed 100644 --- a/dpnp/tests/test_umath.py +++ b/dpnp/tests/test_umath.py @@ -117,19 +117,19 @@ def _get_output_data_type(dtype): 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 + dt_out = dpnp.float16 if has_support_aspect16() else dpnp.float32 elif dtype_float32: - out_dtype = dpnp.float32 + dt_out = dpnp.float32 elif dpnp.issubdtype(dtype, dpnp.complexfloating): - out_dtype = dpnp.complex64 + dt_out = dpnp.complex64 if has_support_aspect64() and dtype != dpnp.complex64: - out_dtype = dpnp.complex128 + dt_out = dpnp.complex128 else: - out_dtype = dpnp.float32 + dt_out = dpnp.float32 if has_support_aspect64() and dtype != dpnp.float32: - out_dtype = dpnp.float64 + dt_out = dpnp.float64 - return out_dtype + return dt_out class TestArctan2: @@ -142,26 +142,26 @@ def test_arctan2(self, dtype): expected = numpy.arctan2(a, b) ia, ib = dpnp.array(a), dpnp.array(b) - out_dtype = _get_output_data_type(dtype) - iout = dpnp.empty(expected.shape, dtype=out_dtype) + dt_out = _get_output_data_type(dtype) + iout = dpnp.empty(expected.shape, dtype=dt_out) result = dpnp.arctan2(ia, ib, out=iout) assert result is iout assert_dtype_allclose(result, expected) @pytest.mark.parametrize( - "dtype", get_all_dtypes(no_none=True, no_complex=True)[:-1] + "dt_out", get_all_dtypes(no_none=True, no_complex=True)[:-1] ) - def test_invalid_dtype(self, dtype): - dpnp_dtype = get_all_dtypes(no_none=True, no_complex=True)[-1] - a = dpnp.arange(10, dtype=dpnp_dtype) - iout = dpnp.empty(10, dtype=dtype) + def test_invalid_dtype(self, dt_out): + dt_in = get_all_dtypes(no_none=True, no_complex=True)[-1] + a = dpnp.arange(10, dtype=dt_in) + iout = dpnp.empty(10, dtype=dt_out) with pytest.raises(ValueError): dpnp.arctan2(a, a, out=iout) @pytest.mark.parametrize( - "shape", [(0,), (15,), (2, 2)], ids=["(0,)", "(15, )", "(2,2)"] + "shape", [(0,), (15,), (2, 2)], ids=["(0,)", "(15,)", "(2, 2)"] ) def test_invalid_shape(self, shape): a = dpnp.arange(10) @@ -178,44 +178,6 @@ def test_alias(self): assert_array_equal(res1, res2) -class TestCbrt: - @pytest.mark.parametrize( - "dtype", get_all_dtypes(no_none=True, no_complex=True) - ) - def test_cbrt(self, dtype): - a = generate_random_numpy_array(10, dtype) - expected = numpy.cbrt(a) - - ia = dpnp.array(a) - out_dtype = _get_output_data_type(dtype) - iout = dpnp.empty(expected.shape, dtype=out_dtype) - result = dpnp.cbrt(ia, out=iout) - - assert result is iout - assert_dtype_allclose(result, expected) - - @pytest.mark.parametrize( - "dtype", get_all_dtypes(no_none=True, no_complex=True)[:-1] - ) - def test_invalid_dtype(self, dtype): - dpnp_dtype = get_all_dtypes(no_none=True, no_complex=True)[-1] - a = dpnp.arange(10, dtype=dpnp_dtype) - iout = dpnp.empty(10, dtype=dtype) - - with pytest.raises(ValueError): - dpnp.cbrt(a, out=iout) - - @pytest.mark.parametrize( - "shape", [(0,), (15,), (2, 2)], ids=["(0,)", "(15, )", "(2,2)"] - ) - def test_invalid_shape(self, shape): - a = dpnp.arange(10) - iout = dpnp.empty(shape) - - with pytest.raises(ValueError): - dpnp.cbrt(a, out=iout) - - class TestCopySign: @pytest.mark.parametrize( "dtype", get_all_dtypes(no_none=True, no_complex=True) @@ -226,20 +188,20 @@ def test_copysign(self, dtype): expected = numpy.copysign(a, b) ia, ib = dpnp.array(a), dpnp.array(b) - out_dtype = _get_output_data_type(dtype) - iout = dpnp.empty(expected.shape, dtype=out_dtype) + dt_out = _get_output_data_type(dtype) + iout = dpnp.empty(expected.shape, dtype=dt_out) result = dpnp.copysign(ia, ib, out=iout) assert result is iout assert_dtype_allclose(result, expected) @pytest.mark.parametrize( - "dtype", get_all_dtypes(no_none=True, no_complex=True)[:-1] + "dt_out", get_all_dtypes(no_none=True, no_complex=True)[:-1] ) - def test_invalid_dtype(self, dtype): - dpnp_dtype = get_all_dtypes(no_none=True, no_complex=True)[-1] - a = dpnp.arange(10, dtype=dpnp_dtype) - iout = dpnp.empty(10, dtype=dtype) + def test_invalid_dtype(self, dt_out): + dt_in = get_all_dtypes(no_none=True, no_complex=True)[-1] + a = dpnp.arange(10, dtype=dt_in) + iout = dpnp.empty(10, dtype=dt_out) with pytest.raises(ValueError): dpnp.copysign(a, a, out=iout) @@ -345,20 +307,20 @@ def test_logaddexp(self, dtype): expected = numpy.logaddexp(a, b) ia, ib = dpnp.array(a), dpnp.array(b) - out_dtype = _get_output_data_type(dtype) - iout = dpnp.empty(expected.shape, dtype=out_dtype) + dt_out = _get_output_data_type(dtype) + iout = dpnp.empty(expected.shape, dtype=dt_out) result = dpnp.logaddexp(ia, ib, out=iout) assert result is iout assert_dtype_allclose(result, expected) @pytest.mark.parametrize( - "dtype", get_all_dtypes(no_none=True, no_complex=True)[:-1] + "dt_out", get_all_dtypes(no_none=True, no_complex=True)[:-1] ) - def test_invalid_dtype(self, dtype): - dpnp_dtype = get_all_dtypes(no_none=True, no_complex=True)[-1] - a = dpnp.arange(10, dtype=dpnp_dtype) - iout = dpnp.empty(10, dtype=dtype) + def test_invalid_dtype(self, dt_out): + dt_in = get_all_dtypes(no_none=True, no_complex=True)[-1] + a = dpnp.arange(10, dtype=dt_in) + iout = dpnp.empty(10, dtype=dt_out) with pytest.raises(ValueError): dpnp.logaddexp(a, a, out=iout) @@ -488,121 +450,90 @@ def test_reciprocal(self, dtype): expected = numpy.reciprocal(a) ia = dpnp.array(a) - out_dtype = _get_output_data_type(dtype) - iout = dpnp.empty(expected.shape, dtype=out_dtype) + dt_out = _get_output_data_type(dtype) + iout = dpnp.empty(expected.shape, dtype=dt_out) result = dpnp.reciprocal(ia, out=iout) assert result is iout assert_dtype_allclose(result, expected) - @pytest.mark.parametrize("dtype", get_float_complex_dtypes()[:-1]) - def test_invalid_dtype(self, dtype): - dpnp_dtype = get_float_complex_dtypes()[-1] - a = dpnp.arange(10, dtype=dpnp_dtype) - iout = dpnp.empty(10, dtype=dtype) - - with pytest.raises(ValueError): - dpnp.reciprocal(a, out=iout) + @pytest.mark.parametrize("dt_out", get_float_complex_dtypes()[:-1]) + def test_invalid_dtype(self, dt_out): + dt_in = get_float_complex_dtypes()[-1] + a = dpnp.arange(10, dtype=dt_in) + iout = dpnp.empty(10, dtype=dt_out) + assert_raises(ValueError, dpnp.reciprocal, a, out=iout) @pytest.mark.parametrize( - "shape", [(0,), (15,), (2, 2)], ids=["(0,)", "(15, )", "(2,2)"] + "shape", [(0,), (15,), (2, 2)], ids=["(0,)", "(15,)", "(2, 2)"] ) def test_invalid_shape(self, shape): a = dpnp.arange(10) iout = dpnp.empty(shape) + assert_raises(ValueError, dpnp.reciprocal, a, out=iout) - with pytest.raises(ValueError): - dpnp.reciprocal(a, out=iout) +class TestRsqrtCbrt: + @pytest.fixture( + params=[ + {"func": "cbrt", "values": [-10, 10]}, + {"func": "rsqrt", "values": [0, 10]}, + ], + ids=["cbrt", "rsqrt"], + ) + def func_params(self, request): + return request.param -class TestRsqrt: @pytest.mark.usefixtures("suppress_divide_numpy_warnings") @pytest.mark.parametrize( "dtype", get_all_dtypes(no_none=True, no_complex=True) ) - def test_rsqrt(self, dtype): - a = generate_random_numpy_array(10, dtype, low=0) - expected = numpy.reciprocal(numpy.sqrt(a)) + def test_basic(self, func_params, dtype): + func = func_params["func"] + values = func_params["values"] + a = generate_random_numpy_array( + 10, dtype, low=values[0], high=values[1] + ) + if func == "rsqrt": + expected = numpy.reciprocal(numpy.sqrt(a)) + else: + expected = getattr(numpy, func)(a) ia = dpnp.array(a) - out_dtype = _get_output_data_type(dtype) - iout = dpnp.empty(expected.shape, dtype=out_dtype) - result = dpnp.rsqrt(ia, out=iout) - + dt_out = _get_output_data_type(dtype) + iout = dpnp.empty(expected.shape, dtype=dt_out) + result = getattr(dpnp, func)(ia, out=iout) assert result is iout assert_dtype_allclose(result, expected) @pytest.mark.parametrize( - "dtype", get_all_dtypes(no_none=True, no_complex=True)[:-1] + "dt_out", get_all_dtypes(no_none=True, no_complex=True)[:-1] ) - def test_invalid_dtype(self, dtype): - dpnp_dtype = get_all_dtypes(no_none=True, no_complex=True)[-1] - a = dpnp.arange(10, dtype=dpnp_dtype) - iout = dpnp.empty(10, dtype=dtype) - - with pytest.raises(ValueError): - dpnp.rsqrt(a, out=iout) + def test_invalid_dtype(self, func_params, dt_out): + func = func_params["func"] + dt_in = get_all_dtypes(no_none=True, no_complex=True)[-1] + a = dpnp.arange(10, dtype=dt_in) + iout = dpnp.empty(10, dtype=dt_out) + assert_raises(ValueError, getattr(dpnp, func), a, out=iout) @pytest.mark.parametrize( - "shape", [(0,), (15,), (2, 2)], ids=["(0,)", "(15, )", "(2,2)"] + "shape", [(0,), (15,), (2, 2)], ids=["(0,)", "(15,)", "(2, 2)"] ) - def test_invalid_shape(self, shape): + def test_invalid_shape(self, func_params, shape): + func = func_params["func"] a = dpnp.arange(10) iout = dpnp.empty(shape) - with pytest.raises(ValueError): - dpnp.rsqrt(a, out=iout) + assert_raises(ValueError, getattr(dpnp, func), a, out=iout) @pytest.mark.parametrize( "out", [4, (), [], (3, 7), [2, 4]], ids=["4", "()", "[]", "(3, 7)", "[2, 4]"], ) - def test_invalid_out(self, out): - a = dpnp.arange(10) - assert_raises(TypeError, dpnp.rsqrt, a, out) - - -class TestSquare: - @pytest.mark.parametrize("dtype", get_all_dtypes(no_none=True)) - def test_square(self, dtype): - a = generate_random_numpy_array(10, dtype) - expected = numpy.square(a) - - ia = dpnp.array(a) - out_dtype = numpy.int8 if dtype == dpnp.bool else dtype - iout = dpnp.empty(expected.shape, dtype=out_dtype) - result = dpnp.square(ia, out=iout) - - assert result is iout - assert_dtype_allclose(result, expected) - - @pytest.mark.parametrize("dtype", get_all_dtypes(no_none=True)[:-1]) - def test_invalid_dtype(self, dtype): - dpnp_dtype = get_all_dtypes(no_none=True)[-1] - a = dpnp.arange(10, dtype=dpnp_dtype) - iout = dpnp.empty(10, dtype=dtype) - - with pytest.raises(ValueError): - dpnp.square(a, out=iout) - - @pytest.mark.parametrize( - "shape", [(0,), (15,), (2, 2)], ids=["(0,)", "(15, )", "(2,2)"] - ) - def test_invalid_shape(self, shape): + def test_invalid_out(self, func_params, out): + func = func_params["func"] a = dpnp.arange(10) - iout = dpnp.empty(shape) - with pytest.raises(ValueError): - dpnp.square(a, out=iout) - - @pytest.mark.parametrize("xp", [dpnp, numpy]) - @pytest.mark.parametrize( - "out", - [4, (), [], (3, 7), [2, 4]], - ids=["scalar", "empty_tuple", "empty_list", "tuple", "list"], - ) - def test_invalid_out(self, xp, out): - a = xp.arange(10) - assert_raises(TypeError, xp.square, a, out) + assert_raises(TypeError, getattr(dpnp, func), a, out) class TestUmath: @@ -626,6 +557,7 @@ class TestUmath: {"func": "sin", "values": [-5, 5]}, {"func": "sinh", "values": [-5, 5]}, {"func": "sqrt", "values": [0, 10]}, + {"func": "square", "values": [-10, 10]}, {"func": "tan", "values": [-1.5, 1.5]}, {"func": "tanh", "values": [-5, 5]}, ], @@ -648,6 +580,7 @@ class TestUmath: "sin", "sinh", "sqrt", + "square", "tan", "tanh", ], @@ -657,7 +590,7 @@ def func_params(self, request): @pytest.mark.filterwarnings("ignore:overflow encountered:RuntimeWarning") @pytest.mark.usefixtures("suppress_divide_invalid_numpy_warnings") - @pytest.mark.parametrize("dtype", get_all_dtypes()) + @pytest.mark.parametrize("dtype", get_all_dtypes(no_none=True)) def test_out(self, func_params, dtype): func = func_params["func"] values = func_params["values"] @@ -667,32 +600,33 @@ def test_out(self, func_params, dtype): expected = getattr(numpy, func)(a) ia = dpnp.array(a) - out_dtype = _get_output_data_type(dtype) - iout = dpnp.empty(expected.shape, dtype=out_dtype) + if func == "square": + dt_out = numpy.int8 if dtype == dpnp.bool else dtype + else: + dt_out = _get_output_data_type(dtype) + iout = dpnp.empty(expected.shape, dtype=dt_out) result = getattr(dpnp, func)(ia, out=iout) assert result is iout assert_dtype_allclose(result, expected) - @pytest.mark.parametrize("dtype", get_all_dtypes(no_none=True)[:-1]) - def test_invalid_dtype(self, func_params, dtype): + @pytest.mark.parametrize("dt_out", get_all_dtypes(no_none=True)[:-1]) + def test_invalid_dtype(self, func_params, dt_out): func = func_params["func"] - dpnp_dtype = get_all_dtypes(no_none=True)[-1] - a = dpnp.arange(10, dtype=dpnp_dtype) - iout = dpnp.empty(10, dtype=dtype) - - with pytest.raises(ValueError): - getattr(dpnp, func)(a, out=iout) + dt_in = get_all_dtypes(no_none=True)[-1] + a = dpnp.arange(10, dtype=dt_in) + iout = dpnp.empty(10, dtype=dt_out) + assert_raises(ValueError, getattr(dpnp, func), a, out=iout) + @pytest.mark.parametrize("xp", [dpnp, numpy]) @pytest.mark.parametrize( - "shape", [(0,), (15,), (2, 2)], ids=["(0,)", "(15, )", "(2,2)"] + "shape", [(0,), (15,), (2, 2)], ids=["(0,)", "(15,)", "(2, 2)"] ) - def test_invalid_shape(self, func_params, shape): + def test_invalid_shape(self, xp, func_params, shape): func = func_params["func"] - a = dpnp.arange(10) - iout = dpnp.empty(shape) - with pytest.raises(ValueError): - getattr(dpnp, func)(a, out=iout) + a = xp.arange(10) + iout = xp.empty(shape) + assert_raises(ValueError, getattr(xp, func), a, out=iout) @pytest.mark.parametrize("xp", [dpnp, numpy]) @pytest.mark.parametrize( From 5b8cdd7233c285c6aa879a142565e7716fa8553d Mon Sep 17 00:00:00 2001 From: Vahid Tavanashad Date: Wed, 26 Mar 2025 08:47:50 -0700 Subject: [PATCH 06/11] updates for obtaining out dtype --- dpnp/tests/test_binary_ufuncs.py | 6 +---- dpnp/tests/test_mathematical.py | 28 ++++++++++++++++++-- dpnp/tests/test_umath.py | 44 +++++++------------------------- 3 files changed, 36 insertions(+), 42 deletions(-) diff --git a/dpnp/tests/test_binary_ufuncs.py b/dpnp/tests/test_binary_ufuncs.py index a9631018b2ea..1bc1ddd5b967 100644 --- a/dpnp/tests/test_binary_ufuncs.py +++ b/dpnp/tests/test_binary_ufuncs.py @@ -23,7 +23,6 @@ has_support_aspect16, numpy_version, ) -from .test_umath import _get_output_data_type """ The scope includes tests with only functions which are instances of @@ -195,10 +194,7 @@ def test_divide(self, dtype): expected = numpy.divide(a, b) ia, ib = dpnp.array(a), dpnp.array(b) - if numpy.issubdtype(dtype, numpy.integer) or dtype == dpnp.bool: - out_dtype = map_dtype_to_device(dpnp.float64, ia.sycl_device) - else: - out_dtype = _get_output_data_type(dtype) + out_dtype = map_dtype_to_device(expected.dtype, ia.sycl_device) iout = dpnp.empty(expected.shape, dtype=out_dtype) result = dpnp.divide(ia, ib, out=iout) diff --git a/dpnp/tests/test_mathematical.py b/dpnp/tests/test_mathematical.py index f0fc5e2ea86f..ecb146b3f213 100644 --- a/dpnp/tests/test_mathematical.py +++ b/dpnp/tests/test_mathematical.py @@ -17,6 +17,7 @@ import dpnp from dpnp.dpnp_array import dpnp_array +from dpnp.dpnp_utils import map_dtype_to_device from .helper import ( assert_dtype_allclose, @@ -32,10 +33,33 @@ has_support_aspect64, numpy_version, ) -from .test_umath import _get_output_data_type from .third_party.cupy import testing +def _get_output_data_type(dtype): + """Return a data type specified by input `dtype` and device capabilities.""" + 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: + out_dtype = dpnp.complex128 + else: + out_dtype = dpnp.float32 + if has_support_aspect64() and dtype != dpnp.float32: + out_dtype = dpnp.float64 + + return out_dtype + + @pytest.mark.parametrize("deg", [True, False]) class TestAngle: def test_angle_bool(self, deg): @@ -2323,7 +2347,7 @@ def test_hypot(self, dtype): expected = numpy.hypot(a, b) ia, ib = dpnp.array(a), dpnp.array(b) - out_dt = _get_output_data_type(dtype) + out_dt = map_dtype_to_device(expected.dtype, ia.sycl_device) iout = dpnp.empty(expected.shape, dtype=out_dt) result = dpnp.hypot(ia, ib, out=iout) diff --git a/dpnp/tests/test_umath.py b/dpnp/tests/test_umath.py index b14bc668f0ed..2d3b18c20bc7 100644 --- a/dpnp/tests/test_umath.py +++ b/dpnp/tests/test_umath.py @@ -9,6 +9,7 @@ ) import dpnp +from dpnp.dpnp_utils import map_dtype_to_device from .helper import ( assert_dtype_allclose, @@ -108,30 +109,6 @@ def test_umaths(test_cases): assert_allclose(result, expected, rtol=1e-6) -def _get_output_data_type(dtype): - """Return a data type specified by input `dtype` and device capabilities.""" - 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: - dt_out = dpnp.float16 if has_support_aspect16() else dpnp.float32 - elif dtype_float32: - dt_out = dpnp.float32 - elif dpnp.issubdtype(dtype, dpnp.complexfloating): - dt_out = dpnp.complex64 - if has_support_aspect64() and dtype != dpnp.complex64: - dt_out = dpnp.complex128 - else: - dt_out = dpnp.float32 - if has_support_aspect64() and dtype != dpnp.float32: - dt_out = dpnp.float64 - - return dt_out - - class TestArctan2: @pytest.mark.parametrize( "dtype", get_all_dtypes(no_none=True, no_complex=True) @@ -142,10 +119,10 @@ def test_arctan2(self, dtype): expected = numpy.arctan2(a, b) ia, ib = dpnp.array(a), dpnp.array(b) - dt_out = _get_output_data_type(dtype) + dt_out = map_dtype_to_device(expected.dtype, ia.sycl_device) iout = dpnp.empty(expected.shape, dtype=dt_out) - result = dpnp.arctan2(ia, ib, out=iout) + result = dpnp.arctan2(ia, ib, out=iout) assert result is iout assert_dtype_allclose(result, expected) @@ -188,7 +165,7 @@ def test_copysign(self, dtype): expected = numpy.copysign(a, b) ia, ib = dpnp.array(a), dpnp.array(b) - dt_out = _get_output_data_type(dtype) + dt_out = map_dtype_to_device(expected.dtype, ia.sycl_device) iout = dpnp.empty(expected.shape, dtype=dt_out) result = dpnp.copysign(ia, ib, out=iout) @@ -307,7 +284,7 @@ def test_logaddexp(self, dtype): expected = numpy.logaddexp(a, b) ia, ib = dpnp.array(a), dpnp.array(b) - dt_out = _get_output_data_type(dtype) + dt_out = map_dtype_to_device(expected.dtype, ia.sycl_device) iout = dpnp.empty(expected.shape, dtype=dt_out) result = dpnp.logaddexp(ia, ib, out=iout) @@ -450,7 +427,7 @@ def test_reciprocal(self, dtype): expected = numpy.reciprocal(a) ia = dpnp.array(a) - dt_out = _get_output_data_type(dtype) + dt_out = map_dtype_to_device(expected.dtype, ia.sycl_device) iout = dpnp.empty(expected.shape, dtype=dt_out) result = dpnp.reciprocal(ia, out=iout) @@ -500,7 +477,7 @@ def test_basic(self, func_params, dtype): expected = getattr(numpy, func)(a) ia = dpnp.array(a) - dt_out = _get_output_data_type(dtype) + dt_out = map_dtype_to_device(expected.dtype, ia.sycl_device) iout = dpnp.empty(expected.shape, dtype=dt_out) result = getattr(dpnp, func)(ia, out=iout) assert result is iout @@ -591,7 +568,7 @@ def func_params(self, request): @pytest.mark.filterwarnings("ignore:overflow encountered:RuntimeWarning") @pytest.mark.usefixtures("suppress_divide_invalid_numpy_warnings") @pytest.mark.parametrize("dtype", get_all_dtypes(no_none=True)) - def test_out(self, func_params, dtype): + def test_basic(self, func_params, dtype): func = func_params["func"] values = func_params["values"] a = generate_random_numpy_array( @@ -600,10 +577,7 @@ def test_out(self, func_params, dtype): expected = getattr(numpy, func)(a) ia = dpnp.array(a) - if func == "square": - dt_out = numpy.int8 if dtype == dpnp.bool else dtype - else: - dt_out = _get_output_data_type(dtype) + dt_out = map_dtype_to_device(expected.dtype, ia.sycl_device) iout = dpnp.empty(expected.shape, dtype=dt_out) result = getattr(dpnp, func)(ia, out=iout) From a5c72f721afe29aef4e5566a527b2c3024b448b7 Mon Sep 17 00:00:00 2001 From: Anton Volkov Date: Wed, 26 Mar 2025 11:00:42 +0100 Subject: [PATCH 07/11] Extend a number of supported types to all numeric dtypes in umath tests --- dpnp/tests/helper.py | 8 ++++++ dpnp/tests/skipped_tests.tbl | 7 ----- dpnp/tests/skipped_tests_gpu.tbl | 8 ------ dpnp/tests/skipped_tests_gpu_no_fp64.tbl | 1 - dpnp/tests/test_umath.py | 34 +++++++++++++++--------- 5 files changed, 29 insertions(+), 29 deletions(-) delete mode 100644 dpnp/tests/skipped_tests_gpu_no_fp64.tbl diff --git a/dpnp/tests/helper.py b/dpnp/tests/helper.py index eb42d76b4d87..54d66b815add 100644 --- a/dpnp/tests/helper.py +++ b/dpnp/tests/helper.py @@ -346,6 +346,14 @@ def is_cuda_device(device=None): return dev.backend == dpctl.backend_type.cuda +def is_gpu_device(device=None): + """ + Return True if a test is running on GPU device, False otherwise. + """ + dev = dpctl.select_default_device() if device is None else device + return dev.has_aspect_gpu + + def is_win_platform(): """ Return True if a test is running on Windows OS, False otherwise. diff --git a/dpnp/tests/skipped_tests.tbl b/dpnp/tests/skipped_tests.tbl index 7a7e140972dd..f685019009db 100644 --- a/dpnp/tests/skipped_tests.tbl +++ b/dpnp/tests/skipped_tests.tbl @@ -10,10 +10,3 @@ tests/test_random.py::TestPermutationsTestShuffle::test_shuffle1[lambda x: dpnp. tests/test_random.py::TestPermutationsTestShuffle::test_shuffle1[lambda x: dpnp.asarray(x).astype(dpnp.int8)] tests/third_party/intel/test_zero_copy_test1.py::test_dpnp_interaction_with_dpctl_memory - -tests/test_umath.py::test_umaths[('divmod', 'ii')] -tests/test_umath.py::test_umaths[('divmod', 'll')] -tests/test_umath.py::test_umaths[('divmod', 'ff')] -tests/test_umath.py::test_umaths[('divmod', 'dd')] -tests/test_umath.py::test_umaths[('frexp', 'f')] -tests/test_umath.py::test_umaths[('frexp', 'd')] diff --git a/dpnp/tests/skipped_tests_gpu.tbl b/dpnp/tests/skipped_tests_gpu.tbl index 7eddf6a27297..ff62106ad3bd 100644 --- a/dpnp/tests/skipped_tests_gpu.tbl +++ b/dpnp/tests/skipped_tests_gpu.tbl @@ -17,12 +17,4 @@ tests/test_random.py::TestPermutationsTestShuffle::test_shuffle1[lambda x: (dpnp tests/test_random.py::TestPermutationsTestShuffle::test_shuffle1[lambda x: dpnp.asarray([(i, i) for i in x], [("a", object), ("b", dpnp.int32)])]] tests/test_random.py::TestPermutationsTestShuffle::test_shuffle1[lambda x: dpnp.asarray(x).astype(dpnp.int8)] -tests/test_umath.py::test_umaths[('divmod', 'ii')] -tests/test_umath.py::test_umaths[('divmod', 'll')] -tests/test_umath.py::test_umaths[('divmod', 'ff')] -tests/test_umath.py::test_umaths[('divmod', 'dd')] -tests/test_umath.py::test_umaths[('floor_divide', 'ff')] -tests/test_umath.py::test_umaths[('frexp', 'f')] -tests/test_umath.py::test_umaths[('frexp', 'd')] - tests/third_party/intel/test_zero_copy_test1.py::test_dpnp_interaction_with_dpctl_memory diff --git a/dpnp/tests/skipped_tests_gpu_no_fp64.tbl b/dpnp/tests/skipped_tests_gpu_no_fp64.tbl deleted file mode 100644 index 2b751bbf3a8d..000000000000 --- a/dpnp/tests/skipped_tests_gpu_no_fp64.tbl +++ /dev/null @@ -1 +0,0 @@ -tests/test_umath.py::test_umaths[('floor_divide', 'ff')] diff --git a/dpnp/tests/test_umath.py b/dpnp/tests/test_umath.py index 2d3b18c20bc7..0e9c3eaf5177 100644 --- a/dpnp/tests/test_umath.py +++ b/dpnp/tests/test_umath.py @@ -20,21 +20,18 @@ get_float_dtypes, has_support_aspect16, has_support_aspect64, + is_gpu_device, ) # full list of umaths umaths = [i for i in dir(numpy) if isinstance(getattr(numpy, i), numpy.ufunc)] -types = { - "d": numpy.float64, - "f": numpy.float32, - "l": numpy.int64, - "i": numpy.int32, -} - -supported_types = "fli" +supported_types = "?bBhHiIlLkK" +if has_support_aspect16(): + supported_types += "e" +supported_types += "fF" if has_support_aspect64(): - supported_types += "d" + supported_types += "dD" def check_types(args_str): @@ -55,7 +52,7 @@ def shaped_arange(shape, xp=numpy, dtype=numpy.float32): def get_args(args_str, sh, xp=numpy): args = [] for s in args_str: - args.append(shaped_arange(shape=sh, xp=xp, dtype=types[s])) + args.append(shaped_arange(shape=sh, xp=xp, dtype=numpy.dtype(s))) return tuple(args) @@ -75,6 +72,7 @@ def get_id(val): return val.__str__() +@pytest.mark.filterwarnings("ignore:overflow encountered:RuntimeWarning") @pytest.mark.usefixtures("suppress_divide_invalid_numpy_warnings") @pytest.mark.parametrize("test_cases", test_cases, ids=get_id) def test_umaths(test_cases): @@ -91,7 +89,7 @@ def test_umaths(test_cases): iargs = get_args(args_str, sh, xp=dpnp) if umath == "reciprocal": - if args[0].dtype in [numpy.int32, numpy.int64]: + if numpy.issubdtype(args[0].dtype, numpy.integer): pytest.skip( "For integer input array, numpy.reciprocal returns zero." ) @@ -102,11 +100,21 @@ def test_umaths(test_cases): and numpy.dtype("l") != numpy.int64 ): pytest.skip("numpy.ldexp doesn't have a loop for the input types") + elif ( + umath == "floor_divide" + and args[0].dtype in [dpnp.float16, dpnp.float32] + and is_gpu_device() + ): + pytest.skip("dpctl-1652") + elif umath in ["divmod", "frexp"]: + pytest.skip("Not implemented umath") + elif umath == "modf" and args[0].dtype == dpnp.float16: + pytest.skip("dpnp.modf is not supported with dpnp.float16") expected = getattr(numpy, umath)(*args) result = getattr(dpnp, umath)(*iargs) - - assert_allclose(result, expected, rtol=1e-6) + for x, y in zip(result, expected): + assert_dtype_allclose(x, y) class TestArctan2: From c7b4b3f8b28ab1fcf3694d1e5eec0a25367b4e98 Mon Sep 17 00:00:00 2001 From: Anton Volkov Date: Wed, 26 Mar 2025 11:02:46 +0100 Subject: [PATCH 08/11] Use is_gpu_device() where required --- dpnp/tests/test_random_state.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/dpnp/tests/test_random_state.py b/dpnp/tests/test_random_state.py index 9f3aee8526c5..fb483692a49a 100644 --- a/dpnp/tests/test_random_state.py +++ b/dpnp/tests/test_random_state.py @@ -15,7 +15,12 @@ from dpnp.dpnp_array import dpnp_array from dpnp.random import RandomState -from .helper import assert_dtype_allclose, get_array, is_cpu_device +from .helper import ( + assert_dtype_allclose, + get_array, + is_cpu_device, + is_gpu_device, +) # aspects of default device: _def_device = dpctl.SyclQueue().sycl_device @@ -688,7 +693,7 @@ def test_scalar(self, func): ], ) def test_array_range(self, seed): - if not is_cpu_device(): + if is_gpu_device(): pytest.skip("seed as a scalar is only supported on GPU") size = 15 From 33d684d6d6c27ce91ebabcf8e12ca751f93ce425 Mon Sep 17 00:00:00 2001 From: Anton Volkov Date: Wed, 26 Mar 2025 14:00:11 +0100 Subject: [PATCH 09/11] Mute modf umath on CUDA explicitly in the test --- dpnp/tests/skipped_tests_cuda.tbl | 2 -- dpnp/tests/test_umath.py | 8 ++++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/dpnp/tests/skipped_tests_cuda.tbl b/dpnp/tests/skipped_tests_cuda.tbl index dfca5d08f04e..86c73b0e6a62 100644 --- a/dpnp/tests/skipped_tests_cuda.tbl +++ b/dpnp/tests/skipped_tests_cuda.tbl @@ -4,8 +4,6 @@ tests/test_arithmetic.py::TestArithmetic::test_modf_part1 tests/test_arithmetic.py::TestArithmetic::test_modf_part2 tests/test_sycl_queue.py::test_modf[cuda:gpu:0] -tests/test_umath.py::test_umaths[('modf', 'f')] -tests/test_umath.py::test_umaths[('modf', 'd')] tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticModf::test_modf # random diff --git a/dpnp/tests/test_umath.py b/dpnp/tests/test_umath.py index 0e9c3eaf5177..668590bb012e 100644 --- a/dpnp/tests/test_umath.py +++ b/dpnp/tests/test_umath.py @@ -20,6 +20,7 @@ get_float_dtypes, has_support_aspect16, has_support_aspect64, + is_cuda_device, is_gpu_device, ) @@ -108,8 +109,11 @@ def test_umaths(test_cases): pytest.skip("dpctl-1652") elif umath in ["divmod", "frexp"]: pytest.skip("Not implemented umath") - elif umath == "modf" and args[0].dtype == dpnp.float16: - pytest.skip("dpnp.modf is not supported with dpnp.float16") + elif umath == "modf": + if args[0].dtype == dpnp.float16: + pytest.skip("dpnp.modf is not supported with dpnp.float16") + elif is_cuda_device(): + pytest.skip("dpnp.modf is not supported on CUDA device") expected = getattr(numpy, umath)(*args) result = getattr(dpnp, umath)(*iargs) From 002d2da774959e8758af27abf7d68ad7f6d5dff6 Mon Sep 17 00:00:00 2001 From: Anton Volkov Date: Wed, 26 Mar 2025 14:07:02 +0100 Subject: [PATCH 10/11] Mute ceil, trunc, floor tests due to dpctl-2030 --- dpnp/tests/test_umath.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dpnp/tests/test_umath.py b/dpnp/tests/test_umath.py index 668590bb012e..cd8b60914c4a 100644 --- a/dpnp/tests/test_umath.py +++ b/dpnp/tests/test_umath.py @@ -107,6 +107,8 @@ def test_umaths(test_cases): and is_gpu_device() ): pytest.skip("dpctl-1652") + elif umath in ["ceil", "floor", "trunc"] and args[0].dtype == dpnp.bool: + pytest.skip("dpctl-2030") elif umath in ["divmod", "frexp"]: pytest.skip("Not implemented umath") elif umath == "modf": From cdb8e9601a79b748257b69940a6de0f57d714f7d Mon Sep 17 00:00:00 2001 From: Anton Volkov Date: Wed, 26 Mar 2025 15:09:02 +0100 Subject: [PATCH 11/11] Mute tan test due to dpctl-2031 --- dpnp/tests/test_umath.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/dpnp/tests/test_umath.py b/dpnp/tests/test_umath.py index cd8b60914c4a..5cc7d5f839bc 100644 --- a/dpnp/tests/test_umath.py +++ b/dpnp/tests/test_umath.py @@ -9,6 +9,7 @@ ) import dpnp +import dpnp.backend.extensions.vm._vm_impl as vmi from dpnp.dpnp_utils import map_dtype_to_device from .helper import ( @@ -109,6 +110,12 @@ def test_umaths(test_cases): pytest.skip("dpctl-1652") elif umath in ["ceil", "floor", "trunc"] and args[0].dtype == dpnp.bool: pytest.skip("dpctl-2030") + elif ( + umath == "tan" + and dpnp.issubdtype(args[0].dtype, dpnp.complexfloating) + and not (vmi._is_available() and has_support_aspect64()) + ): + pytest.skip("dpctl-2031") elif umath in ["divmod", "frexp"]: pytest.skip("Not implemented umath") elif umath == "modf":