diff --git a/.github/workflows/conda-package.yml b/.github/workflows/conda-package.yml index 49420a511dd7..096f7a10bbf4 100644 --- a/.github/workflows/conda-package.yml +++ b/.github/workflows/conda-package.yml @@ -37,7 +37,7 @@ jobs: strategy: matrix: - python: ['3.8', '3.9', '3.10'] + python: ['3.8', '3.9', '3.10', '3.11'] os: [ubuntu-20.04, windows-latest] runs-on: ${{ matrix.os }} @@ -114,7 +114,7 @@ jobs: strategy: matrix: - python: ['3.8', '3.9', '3.10'] + python: ['3.8', '3.9', '3.10', '3.11'] os: [ubuntu-20.04, ubuntu-latest] experimental: [false] @@ -217,7 +217,7 @@ jobs: strategy: matrix: - python: ['3.8', '3.9', '3.10'] + python: ['3.8', '3.9', '3.10', '3.11'] experimental: [false] continue-on-error: ${{ matrix.experimental }} @@ -350,7 +350,7 @@ jobs: strategy: matrix: - python: ['3.8', '3.9', '3.10'] + python: ['3.8', '3.9', '3.10', '3.11'] os: [ubuntu-20.04, windows-latest] runs-on: ${{ matrix.os }} diff --git a/.github/workflows/generate_coverage.yaml b/.github/workflows/generate_coverage.yaml index 413835d336cf..d3a217a03f81 100644 --- a/.github/workflows/generate_coverage.yaml +++ b/.github/workflows/generate_coverage.yaml @@ -14,7 +14,7 @@ jobs: shell: bash -l {0} env: - python-ver: '3.10' + python-ver: '3.11' CHANNELS: '-c dppy/label/dev -c intel -c conda-forge --override-channels' steps: diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml index 673f6c172430..18668bf10c45 100644 --- a/.github/workflows/pre-commit.yml +++ b/.github/workflows/pre-commit.yml @@ -19,5 +19,5 @@ jobs: - uses: actions/checkout@v3.5.2 - uses: actions/setup-python@v4.6.1 with: - python-version: '3.10' + python-version: '3.11' - uses: pre-commit/action@v3.0.0 diff --git a/conda-recipe/build.sh b/conda-recipe/build.sh index b25baed8ecd1..015a25bbbbd2 100755 --- a/conda-recipe/build.sh +++ b/conda-recipe/build.sh @@ -1,5 +1,8 @@ #!/bin/bash +# This is necessary to help DPC++ find Intel libraries such as SVML, IRNG, etc in build prefix +export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${BUILD_PREFIX}/lib" + # Intel LLVM must cooperate with compiler and sysroot from conda echo "--gcc-toolchain=${BUILD_PREFIX} --sysroot=${BUILD_PREFIX}/${HOST}/sysroot -target ${HOST}" > icpx_for_conda.cfg export ICPXCFG="$(pwd)/icpx_for_conda.cfg" diff --git a/setup.py b/setup.py index f95260aeda2a..174851ab770f 100644 --- a/setup.py +++ b/setup.py @@ -37,6 +37,7 @@ def _get_cmdclass(): Programming Language :: Python :: 3.8 Programming Language :: Python :: 3.9 Programming Language :: Python :: 3.10 +Programming Language :: Python :: 3.11 Programming Language :: Python :: Implementation :: CPython Topic :: Software Development Topic :: Scientific/Engineering diff --git a/tests/helper.py b/tests/helper.py index 6971feecb534..42ada2949833 100644 --- a/tests/helper.py +++ b/tests/helper.py @@ -1,10 +1,32 @@ from sys import platform import dpctl +import numpy +from numpy.testing import assert_allclose, assert_array_equal import dpnp +def assert_dtype_allclose(dpnp_arr, numpy_arr): + """ + 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. + + """ + + is_inexact = lambda x: dpnp.issubdtype(x.dtype, dpnp.inexact) + if is_inexact(dpnp_arr) or is_inexact(numpy_arr): + tol = 8 * max( + numpy.finfo(dpnp_arr.dtype).resolution, + numpy.finfo(numpy_arr.dtype).resolution, + ) + assert_allclose(dpnp_arr.asnumpy(), numpy_arr, atol=tol, rtol=tol) + else: + assert_array_equal(dpnp_arr.asnumpy(), numpy_arr) + assert dpnp_arr.dtype == numpy_arr.dtype + + def get_complex_dtypes(device=None): """ Build a list of complex types supported by DPNP based on device capabilities. diff --git a/tests/test_dot.py b/tests/test_dot.py index 7b4cdd02c928..80da5090e1b7 100644 --- a/tests/test_dot.py +++ b/tests/test_dot.py @@ -20,11 +20,11 @@ def test_dot_ones(type): assert_array_equal(expected, result) -@pytest.mark.parametrize("type", get_all_dtypes(no_bool=True, no_complex=True)) -def test_dot_arange(type): +@pytest.mark.parametrize("dtype", get_all_dtypes(no_bool=True, no_complex=True)) +def test_dot_arange(dtype): n = 10**2 - m = 10**3 - a = numpy.hstack((numpy.arange(n, dtype=type),) * m) + m = 10**3 if dtype is not inp.float32 else 10**2 + a = numpy.hstack((numpy.arange(n, dtype=dtype),) * m) b = numpy.flipud(a) ia = inp.array(a) ib = inp.array(b) diff --git a/tests/test_fft.py b/tests/test_fft.py index 38185f3e5f09..ae6835b86eda 100644 --- a/tests/test_fft.py +++ b/tests/test_fft.py @@ -3,7 +3,7 @@ import dpnp -from .helper import has_support_aspect64 +from .helper import assert_dtype_allclose, has_support_aspect64 pytestmark = pytest.mark.skipif( not has_support_aspect64(), reason="Aborted on Iris Xe: SAT-6028" @@ -20,10 +20,9 @@ def test_fft(type, norm): dpnp_data = dpnp.array(data) np_res = numpy.fft.fft(data, norm=norm) - dpnp_res = dpnp.asnumpy(dpnp.fft.fft(dpnp_data, norm=norm)) + dpnp_res = dpnp.fft.fft(dpnp_data, norm=norm) - numpy.testing.assert_allclose(dpnp_res, np_res, rtol=1e-4, atol=1e-7) - assert dpnp_res.dtype == np_res.dtype + assert_dtype_allclose(dpnp_res, np_res) @pytest.mark.parametrize( @@ -38,8 +37,7 @@ def test_fft_ndim(type, shape, norm): np_res = numpy.fft.fft(np_data, norm=norm) dpnp_res = dpnp.fft.fft(dpnp_data, norm=norm) - numpy.testing.assert_allclose(dpnp_res, np_res, rtol=1e-4, atol=1e-7) - assert dpnp_res.dtype == np_res.dtype + assert_dtype_allclose(dpnp_res, np_res) @pytest.mark.parametrize( @@ -56,8 +54,7 @@ def test_fft_ifft(type, shape, norm): np_res = numpy.fft.ifft(np_data, norm=norm) dpnp_res = dpnp.fft.ifft(dpnp_data, norm=norm) - numpy.testing.assert_allclose(dpnp_res, np_res, rtol=1e-4, atol=1e-7) - assert dpnp_res.dtype == np_res.dtype + assert_dtype_allclose(dpnp_res, np_res) @pytest.mark.parametrize("type", ["float32", "float64", "int32", "int64"]) @@ -71,5 +68,4 @@ def test_fft_rfft(type, shape): np_res = numpy.fft.rfft(np_data) dpnp_res = dpnp.fft.rfft(dpnp_data) - numpy.testing.assert_allclose(dpnp_res, np_res, rtol=1e-4, atol=1e-7) - assert dpnp_res.dtype == np_res.dtype + assert_dtype_allclose(dpnp_res, np_res) diff --git a/tests/test_sycl_queue.py b/tests/test_sycl_queue.py index 0de3a1b0ba9a..7dc15a6bccfb 100644 --- a/tests/test_sycl_queue.py +++ b/tests/test_sycl_queue.py @@ -6,7 +6,7 @@ import dpnp -from .helper import get_all_dtypes, is_win_platform +from .helper import assert_dtype_allclose, get_all_dtypes, is_win_platform list_of_backend_str = [ "host", @@ -670,8 +670,7 @@ def test_fft_rfft(type, shape, device): np_res = numpy.fft.rfft(np_data) dpnp_res = dpnp.fft.rfft(dpnp_data) - numpy.testing.assert_allclose(dpnp_res, np_res, rtol=1e-4, atol=1e-7) - assert dpnp_res.dtype == np_res.dtype + assert_dtype_allclose(dpnp_res, np_res) expected_queue = dpnp_data.get_array().sycl_queue result_queue = dpnp_res.get_array().sycl_queue diff --git a/tests/test_umath.py b/tests/test_umath.py index 7d8bb4acfe55..96ff2a849c88 100644 --- a/tests/test_umath.py +++ b/tests/test_umath.py @@ -480,7 +480,7 @@ def test_tan(self): np_array = numpy.array(array_data, dtype=numpy.float64) expected = numpy.tan(np_array, out=out) - assert_array_equal(expected, result) + assert_allclose(expected, result) @pytest.mark.parametrize( "dtype", diff --git a/tests/third_party/cupy/fft_tests/test_fft.py b/tests/third_party/cupy/fft_tests/test_fft.py index 9214a8515e50..0ddd3cc56c17 100644 --- a/tests/third_party/cupy/fft_tests/test_fft.py +++ b/tests/third_party/cupy/fft_tests/test_fft.py @@ -23,7 +23,11 @@ class TestFft(unittest.TestCase): @testing.for_all_dtypes() @testing.numpy_cupy_allclose( - rtol=1e-4, atol=1e-7, accept_error=ValueError, contiguous_check=False + rtol=1e-4, + atol=1e-7, + accept_error=ValueError, + contiguous_check=False, + type_check=False, ) def test_fft(self, xp, dtype): a = testing.shaped_random(self.shape, xp, dtype) @@ -33,7 +37,11 @@ def test_fft(self, xp, dtype): @testing.for_all_dtypes() @testing.numpy_cupy_allclose( - rtol=1e-4, atol=1e-7, accept_error=ValueError, contiguous_check=False + rtol=1e-4, + atol=1e-7, + accept_error=ValueError, + contiguous_check=False, + type_check=False, ) def test_ifft(self, xp, dtype): a = testing.shaped_random(self.shape, xp, dtype) @@ -154,7 +162,9 @@ def test_ifftn(self, xp, dtype): @testing.gpu class TestRfft(unittest.TestCase): @testing.for_all_dtypes(no_complex=True) - @testing.numpy_cupy_allclose(rtol=1e-4, atol=1e-7, contiguous_check=False) + @testing.numpy_cupy_allclose( + rtol=1e-4, atol=1e-7, contiguous_check=False, type_check=False + ) def test_rfft(self, xp, dtype): a = testing.shaped_random(self.shape, xp, dtype) out = xp.fft.rfft(a, n=self.n, norm=self.norm) diff --git a/tests/third_party/cupy/sorting_tests/test_sort.py b/tests/third_party/cupy/sorting_tests/test_sort.py index d9fb94fc3e02..7ae7911f90ee 100644 --- a/tests/third_party/cupy/sorting_tests/test_sort.py +++ b/tests/third_party/cupy/sorting_tests/test_sort.py @@ -317,7 +317,8 @@ def test_argsort_zero_dim(self, xp, dtype): @testing.numpy_cupy_array_equal() def test_argsort_one_dim(self, xp, dtype): a = testing.shaped_random((10,), xp, dtype) - return self.argsort(a) + res = self.argsort(a) + return a[res] @testing.for_all_dtypes() @testing.numpy_cupy_array_equal()