From 2bd0227af46b8d3119953d26b996893285deda61 Mon Sep 17 00:00:00 2001 From: Vahid Tavanashad Date: Wed, 5 Mar 2025 13:27:13 -0600 Subject: [PATCH 1/6] 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 2/6] 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 3/6] 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 4/6] 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 5/6] 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 6/6] 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)