From d3e51364e634c98a8e080cb468ed3e755dc1b150 Mon Sep 17 00:00:00 2001 From: Vladislav Perevezentsev Date: Fri, 1 Dec 2023 15:23:28 +0100 Subject: [PATCH 01/10] Add dtype checking for inexact dtype in assert_dtype_allclose --- tests/helper.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/helper.py b/tests/helper.py index b3d816e769ac..7fca2d828e21 100644 --- a/tests/helper.py +++ b/tests/helper.py @@ -12,6 +12,9 @@ def assert_dtype_allclose(dpnp_arr, numpy_arr, check_type=True): Assert DPNP and NumPy array based on maximum dtype resolution of input arrays for floating and complex types. For other dtypes the assertion is based on exact matching of the arrays. + When 'check_type' True (default), it asserts equal dtypes for exact types + and either equal dtypes or kinds for inexact types, depending on the 64-bit precision + support of the device on which `dpnp_arr` is created. """ @@ -22,6 +25,11 @@ def assert_dtype_allclose(dpnp_arr, numpy_arr, check_type=True): numpy.finfo(numpy_arr.dtype).resolution, ) assert_allclose(dpnp_arr.asnumpy(), numpy_arr, atol=tol, rtol=tol) + if check_type: + if has_support_aspect64(dpnp_arr.sycl_device): + assert dpnp_arr.dtype == numpy_arr.dtype + else: + assert dpnp_arr.dtype.kind == numpy_arr.dtype.kind else: assert_array_equal(dpnp_arr.asnumpy(), numpy_arr) if check_type: From 579fcc2ec9992ccb2f17682dc2edd598a3551c80 Mon Sep 17 00:00:00 2001 From: Vladislav Perevezentsev Date: Fri, 1 Dec 2023 15:24:05 +0100 Subject: [PATCH 02/10] Update test_out_dtypes in TestDivide --- tests/test_mathematical.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/test_mathematical.py b/tests/test_mathematical.py index 9c8850aad188..4f751b697fef 100644 --- a/tests/test_mathematical.py +++ b/tests/test_mathematical.py @@ -1105,6 +1105,7 @@ def test_out_dtypes(self, dtype): dp_array2 = dpnp.arange(size, dtype=dtype) dp_out = dpnp.empty(size, dtype=dpnp.complex64) + check_dtype = True if dtype != dpnp.complex64: # dtype of out mismatches types of input arrays with pytest.raises(TypeError): @@ -1112,9 +1113,11 @@ def test_out_dtypes(self, dtype): # allocate new out with expected type dp_out = dpnp.empty(size, dtype=dtype) + # Set check_dtype to False as dtype does not match + check_dtype = False result = dpnp.divide(dp_array1, dp_array2, out=dp_out) - assert_dtype_allclose(result, expected) + assert_dtype_allclose(result, expected, check_type=check_dtype) @pytest.mark.usefixtures("suppress_divide_invalid_numpy_warnings") @pytest.mark.parametrize("dtype", get_float_complex_dtypes()) From 8b300c2e436ac73ceec60c9865511b2d189715b1 Mon Sep 17 00:00:00 2001 From: Vladislav Perevezentsev Date: Fri, 1 Dec 2023 18:32:28 +0100 Subject: [PATCH 03/10] Add a check for support of 16 bit types --- tests/helper.py | 36 +++++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/tests/helper.py b/tests/helper.py index 7fca2d828e21..73c4a0a1579d 100644 --- a/tests/helper.py +++ b/tests/helper.py @@ -12,12 +12,20 @@ def assert_dtype_allclose(dpnp_arr, numpy_arr, check_type=True): Assert DPNP and NumPy array based on maximum dtype resolution of input arrays for floating and complex types. For other dtypes the assertion is based on exact matching of the arrays. - When 'check_type' True (default), it asserts equal dtypes for exact types - and either equal dtypes or kinds for inexact types, depending on the 64-bit precision - support of the device on which `dpnp_arr` is created. - - """ - + When 'check_type' is True (default), the function asserts: + - Equal dtypes for exact types. + For inexact types: + - If the numpy array's dtype is `numpy.float16`, checks if the device + of the `dpnp_arr` supports 64-bit precision floating point operations. + If supported, asserts equal dtypes. + Otherwise, asserts equal type kinds. + - For other inexact types, asserts equal dtypes if the device of the `dpnp_arr` + supports 64-bit precision floating point operations or if the numpy array's inexact + dtype is not a double precision type. + Otherwise, asserts equal type kinds. + """ + + list_64bit_types = [numpy.float64, numpy.complex128] is_inexact = lambda x: dpnp.issubdtype(x.dtype, dpnp.inexact) if is_inexact(dpnp_arr) or is_inexact(numpy_arr): tol = 8 * max( @@ -26,10 +34,20 @@ def assert_dtype_allclose(dpnp_arr, numpy_arr, check_type=True): ) assert_allclose(dpnp_arr.asnumpy(), numpy_arr, atol=tol, rtol=tol) if check_type: - if has_support_aspect64(dpnp_arr.sycl_device): - assert dpnp_arr.dtype == numpy_arr.dtype + numpy_arr_dtype = numpy_arr.dtype + dpnp_arr_dtype = dpnp_arr.dtype + dpnp_arr_dev = dpnp_arr.sycl_device + is_np_arr_f2 = numpy_arr_dtype == numpy.float16 + + if is_np_arr_f2 and has_support_aspect16(dpnp_arr_dev): + assert dpnp_arr_dtype == numpy_arr_dtype + elif is_np_arr_f2 and ( + has_support_aspect64(dpnp_arr_dev) + or numpy_arr_dtype not in list_64bit_types + ): + assert dpnp_arr_dtype == numpy_arr_dtype else: - assert dpnp_arr.dtype.kind == numpy_arr.dtype.kind + assert dpnp_arr_dtype.kind == numpy_arr_dtype.kind else: assert_array_equal(dpnp_arr.asnumpy(), numpy_arr) if check_type: From 6f4a4fc5777eae1e350d43106450c08ce915a515 Mon Sep 17 00:00:00 2001 From: Vladislav Perevezentsev Date: Fri, 1 Dec 2023 18:34:54 +0100 Subject: [PATCH 04/10] Add an empty line after the description --- tests/helper.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/helper.py b/tests/helper.py index 73c4a0a1579d..b3cff6e73661 100644 --- a/tests/helper.py +++ b/tests/helper.py @@ -23,6 +23,7 @@ def assert_dtype_allclose(dpnp_arr, numpy_arr, check_type=True): supports 64-bit precision floating point operations or if the numpy array's inexact dtype is not a double precision type. Otherwise, asserts equal type kinds. + """ list_64bit_types = [numpy.float64, numpy.complex128] From 3c446c018438d23ca0322b9cf32deacedee412d0 Mon Sep 17 00:00:00 2001 From: Vladislav Perevezentsev Date: Mon, 4 Dec 2023 11:07:04 +0100 Subject: [PATCH 05/10] fix condition when numpy`s array is not float16 --- tests/helper.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/helper.py b/tests/helper.py index b3cff6e73661..37d350eefbf9 100644 --- a/tests/helper.py +++ b/tests/helper.py @@ -42,7 +42,7 @@ def assert_dtype_allclose(dpnp_arr, numpy_arr, check_type=True): if is_np_arr_f2 and has_support_aspect16(dpnp_arr_dev): assert dpnp_arr_dtype == numpy_arr_dtype - elif is_np_arr_f2 and ( + elif not is_np_arr_f2 and ( has_support_aspect64(dpnp_arr_dev) or numpy_arr_dtype not in list_64bit_types ): From 42b199d50e337537802a7abe32af85725de628d8 Mon Sep 17 00:00:00 2001 From: Vladislav Perevezentsev Date: Mon, 4 Dec 2023 11:31:02 +0100 Subject: [PATCH 06/10] Address the remarks --- tests/helper.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/tests/helper.py b/tests/helper.py index 37d350eefbf9..2ca873ee7a44 100644 --- a/tests/helper.py +++ b/tests/helper.py @@ -40,11 +40,12 @@ def assert_dtype_allclose(dpnp_arr, numpy_arr, check_type=True): dpnp_arr_dev = dpnp_arr.sycl_device is_np_arr_f2 = numpy_arr_dtype == numpy.float16 - if is_np_arr_f2 and has_support_aspect16(dpnp_arr_dev): - assert dpnp_arr_dtype == numpy_arr_dtype - elif not is_np_arr_f2 and ( - has_support_aspect64(dpnp_arr_dev) - or numpy_arr_dtype not in list_64bit_types + if is_np_arr_f2: + if has_support_aspect16(dpnp_arr_dev): + assert dpnp_arr_dtype == numpy_arr_dtype + elif ( + numpy_arr_dtype not in list_64bit_types + or has_support_aspect64(dpnp_arr_dev) ): assert dpnp_arr_dtype == numpy_arr_dtype else: From e0b6f0ef32349cf7d9ed698c829cde10ce326135 Mon Sep 17 00:00:00 2001 From: Vladislav Perevezentsev Date: Mon, 4 Dec 2023 15:51:29 +0100 Subject: [PATCH 07/10] Update test_sum_float in test_sum.py --- tests/test_sum.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tests/test_sum.py b/tests/test_sum.py index 16b17847f270..f34d1cf6252d 100644 --- a/tests/test_sum.py +++ b/tests/test_sum.py @@ -27,10 +27,17 @@ def test_sum_float(dtype): ) ia = dpnp.array(a) + # Flag for type check in special cases + # Skip dtype checks when dpnp handles float32 arrays + # as `dpnp.sum()` and `numpy.sum()` return different dtypes + check_dtype = dtype != dpnp.float32 for axis in range(len(a)): result = dpnp.sum(ia, axis=axis) expected = numpy.sum(a, axis=axis) - assert_dtype_allclose(result, expected) + assert_dtype_allclose(result, expected, check_type=check_dtype) + if not check_dtype: + # Ensure dtype kind matches when check_dtype is False + assert result.dtype.kind == expected.dtype.kind def test_sum_int(): From f9212b0facaa0434f81d760666e8320fa34b1a87 Mon Sep 17 00:00:00 2001 From: Vladislav Perevezentsev Date: Tue, 5 Dec 2023 15:10:39 +0100 Subject: [PATCH 08/10] Add a new check_only_type_kind param to assert_dtype_allclose --- tests/helper.py | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/tests/helper.py b/tests/helper.py index 2ca873ee7a44..243c61504a50 100644 --- a/tests/helper.py +++ b/tests/helper.py @@ -7,7 +7,9 @@ import dpnp -def assert_dtype_allclose(dpnp_arr, numpy_arr, check_type=True): +def assert_dtype_allclose( + dpnp_arr, numpy_arr, check_type=True, check_only_type_kind=False +): """ Assert DPNP and NumPy array based on maximum dtype resolution of input arrays for floating and complex types. @@ -23,6 +25,9 @@ def assert_dtype_allclose(dpnp_arr, numpy_arr, check_type=True): supports 64-bit precision floating point operations or if the numpy array's inexact dtype is not a double precision type. Otherwise, asserts equal type kinds. + The 'check_only_type_kind' parameter (False by default) asserts only equal type kinds + for all data types supported by DPNP when set to True. + It is effective only when 'check_type' is also set to True. """ @@ -38,22 +43,29 @@ def assert_dtype_allclose(dpnp_arr, numpy_arr, check_type=True): numpy_arr_dtype = numpy_arr.dtype dpnp_arr_dtype = dpnp_arr.dtype dpnp_arr_dev = dpnp_arr.sycl_device - is_np_arr_f2 = numpy_arr_dtype == numpy.float16 - if is_np_arr_f2: - if has_support_aspect16(dpnp_arr_dev): - assert dpnp_arr_dtype == numpy_arr_dtype - elif ( - numpy_arr_dtype not in list_64bit_types - or has_support_aspect64(dpnp_arr_dev) - ): - assert dpnp_arr_dtype == numpy_arr_dtype - else: + if check_only_type_kind: assert dpnp_arr_dtype.kind == numpy_arr_dtype.kind + else: + is_np_arr_f2 = numpy_arr_dtype == numpy.float16 + + if is_np_arr_f2: + if has_support_aspect16(dpnp_arr_dev): + assert dpnp_arr_dtype == numpy_arr_dtype + elif ( + numpy_arr_dtype not in list_64bit_types + or has_support_aspect64(dpnp_arr_dev) + ): + assert dpnp_arr_dtype == numpy_arr_dtype + else: + assert dpnp_arr_dtype.kind == numpy_arr_dtype.kind else: assert_array_equal(dpnp_arr.asnumpy(), numpy_arr) if check_type: - assert dpnp_arr.dtype == numpy_arr.dtype + if check_only_type_kind: + assert dpnp_arr.dtype.kind == numpy_arr.dtype.kind + else: + assert dpnp_arr.dtype == numpy_arr.dtype def get_complex_dtypes(device=None): From 0290b424fc405d756e929e52b9dea9eec531d02f Mon Sep 17 00:00:00 2001 From: Vladislav Perevezentsev Date: Tue, 5 Dec 2023 15:12:14 +0100 Subject: [PATCH 09/10] Update test_sum and test_fft --- tests/test_fft.py | 8 ++++---- tests/test_sum.py | 11 +++++------ 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/tests/test_fft.py b/tests/test_fft.py index 0d2ea664b58d..b439ef38cce6 100644 --- a/tests/test_fft.py +++ b/tests/test_fft.py @@ -16,7 +16,7 @@ def test_fft(dtype, norm): np_res = numpy.fft.fft(data, norm=norm) dpnp_res = dpnp.fft.fft(dpnp_data, norm=norm) - assert_dtype_allclose(dpnp_res, np_res) + assert_dtype_allclose(dpnp_res, np_res, check_only_type_kind=True) @pytest.mark.parametrize("dtype", get_all_dtypes(no_bool=True)) @@ -29,7 +29,7 @@ def test_fft_ndim(dtype, shape, norm): np_res = numpy.fft.fft(np_data, norm=norm) dpnp_res = dpnp.fft.fft(dpnp_data, norm=norm) - assert_dtype_allclose(dpnp_res, np_res) + assert_dtype_allclose(dpnp_res, np_res, check_only_type_kind=True) @pytest.mark.parametrize("dtype", get_all_dtypes(no_bool=True)) @@ -44,7 +44,7 @@ def test_fft_ifft(dtype, shape, norm): np_res = numpy.fft.ifft(np_data, norm=norm) dpnp_res = dpnp.fft.ifft(dpnp_data, norm=norm) - assert_dtype_allclose(dpnp_res, np_res) + assert_dtype_allclose(dpnp_res, np_res, check_only_type_kind=True) @pytest.mark.parametrize("dtype", get_all_dtypes(no_bool=True, no_complex=True)) @@ -58,7 +58,7 @@ def test_fft_rfft(dtype, shape): np_res = numpy.fft.rfft(np_data) dpnp_res = dpnp.fft.rfft(dpnp_data) - assert_dtype_allclose(dpnp_res, np_res) + assert_dtype_allclose(dpnp_res, np_res, check_only_type_kind=True) @pytest.mark.parametrize( diff --git a/tests/test_sum.py b/tests/test_sum.py index f34d1cf6252d..4104b33a6248 100644 --- a/tests/test_sum.py +++ b/tests/test_sum.py @@ -28,16 +28,15 @@ def test_sum_float(dtype): ia = dpnp.array(a) # Flag for type check in special cases - # Skip dtype checks when dpnp handles float32 arrays + # Use only type kinds checks when dpnp handles float32 arrays # as `dpnp.sum()` and `numpy.sum()` return different dtypes - check_dtype = dtype != dpnp.float32 + check_type_kind = dtype == dpnp.float32 for axis in range(len(a)): result = dpnp.sum(ia, axis=axis) expected = numpy.sum(a, axis=axis) - assert_dtype_allclose(result, expected, check_type=check_dtype) - if not check_dtype: - # Ensure dtype kind matches when check_dtype is False - assert result.dtype.kind == expected.dtype.kind + assert_dtype_allclose( + result, expected, check_only_type_kind=check_type_kind + ) def test_sum_int(): From f82692feb214f5aa58f633e3137e65dcb83fcc51 Mon Sep 17 00:00:00 2001 From: Vladislav Perevezentsev Date: Tue, 5 Dec 2023 16:12:52 +0100 Subject: [PATCH 10/10] Use check_only_type_kind in test_fft_rfft --- tests/test_sycl_queue.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_sycl_queue.py b/tests/test_sycl_queue.py index 265d412b2ac1..3618a9bb4c54 100644 --- a/tests/test_sycl_queue.py +++ b/tests/test_sycl_queue.py @@ -875,7 +875,7 @@ def test_fft_rfft(type, shape, device): np_res = numpy.fft.rfft(np_data) dpnp_res = dpnp.fft.rfft(dpnp_data) - assert_dtype_allclose(dpnp_res, np_res) + assert_dtype_allclose(dpnp_res, np_res, check_only_type_kind=True) expected_queue = dpnp_data.get_array().sycl_queue result_queue = dpnp_res.get_array().sycl_queue