diff --git a/.github/workflows/windows_clangcl.yml b/.github/workflows/windows_clangcl.yml new file mode 100644 index 000000000000..e3ee856fd001 --- /dev/null +++ b/.github/workflows/windows_clangcl.yml @@ -0,0 +1,91 @@ +name: Test Clang-CL Build (Windows) + +on: + pull_request: + branches: + - main + - maintenance/** + +env: + PYTHON_VERSION: 3.11 + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +permissions: + contents: read # to fetch code (actions/checkout) + +jobs: + meson: + name: Meson windows build/test + runs-on: windows-2019 + # if: "github.repository == 'numpy/numpy'" + steps: + - name: Checkout + uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + with: + submodules: recursive + fetch-depth: 0 + - name: Setup Python + uses: actions/setup-python@bd6b4b6205c4dbad673328db7b31b7fab9e241c0 # v4.6.1 + with: + python-version: ${{ env.PYTHON_VERSION }} + + - name: Install dependencies + run: | + pip install -r build_requirements.txt + - name: openblas-libs + run: | + # Download and install pre-built OpenBLAS library + # with 32-bit interfaces + # Unpack it in the pkg-config hardcoded path + choco install unzip -y + choco install wget -y + # Install llvm, which contains clang-cl + choco install llvm -y --version=16.0.6 + choco install -y --checksum 6004DF17818F5A6DBF19CB335CC92702 pkgconfiglite + wget https://anaconda.org/multibuild-wheels-staging/openblas-libs/v0.3.21/download/openblas-v0.3.21-win_amd64-gcc_10_3_0.zip + unzip -d c:\opt openblas-v0.3.21-win_amd64-gcc_10_3_0.zip + echo "PKG_CONFIG_PATH=c:\opt\64\lib\pkgconfig;" >> $env:GITHUB_ENV + - name: meson-configure + run: | + "[binaries]","c = 'clang-cl'","cpp = 'clang-cl'","ar = 'llvm-lib'","c_ld = 'lld-link'","cpp_ld = 'lld-link'" | Out-File $PWD/clang-cl-build.ini -Encoding ascii + meson setup build --prefix=$PWD\build-install --native-file=$PWD/clang-cl-build.ini -Ddebug=false --optimization 2 --vsenv + - name: meson-build + run: | + meson compile -C build -v + + - name: meson-install + run: | + cd build + meson install --no-rebuild + - name: build-path + run: | + echo "installed_path=$PWD\build-install\Lib\site-packages" >> $env:GITHUB_ENV + - name: post-install + run: | + $numpy_path = "${env:installed_path}\numpy" + $libs_path = "${numpy_path}\.libs" + mkdir ${libs_path} + $ob_path = "C:/opt/64/bin/" + cp $ob_path/*.dll $libs_path + # Write _distributor_init.py to load .libs DLLs. + python -c "from tools import openblas_support; openblas_support.make_init(r'${numpy_path}')" + + - name: prep-test + run: | + echo "PYTHONPATH=${env:installed_path}" >> $env:GITHUB_ENV + python -m pip install -r test_requirements.txt + python -m pip install threadpoolctl + + - name: test + run: | + mkdir tmp + cd tmp + echo "============================================" + python -c "import numpy; print(numpy.show_runtime())" + echo "============================================" + echo "LASTEXITCODE is '$LASTEXITCODE'" + python -c "import numpy, sys; sys.exit(numpy.test(verbose=3) is False)" + echo "LASTEXITCODE is '$LASTEXITCODE'" diff --git a/numpy/core/src/multiarray/_multiarray_tests.c.src b/numpy/core/src/multiarray/_multiarray_tests.c.src index c2d53ef4eae2..6bd58dd53593 100644 --- a/numpy/core/src/multiarray/_multiarray_tests.c.src +++ b/numpy/core/src/multiarray/_multiarray_tests.c.src @@ -1966,13 +1966,13 @@ get_fpu_mode(PyObject *NPY_UNUSED(self), PyObject *args) return NULL; } -#if defined(_MSC_VER) +#if defined(_MSC_VER) && !defined(__clang__) { unsigned int result = 0; result = _controlfp(0, 0); return PyLong_FromLongLong(result); } -#elif defined(__GNUC__) && (defined(__x86_64__) || defined(__i386__)) +#elif (defined(__GNUC__) && (defined(__x86_64__) || defined(__i386__))) || (defined(_MSC_VER) && defined(__clang__)) { unsigned short cw = 0; __asm__("fstcw %w0" : "=m" (cw)); diff --git a/numpy/core/tests/test_einsum.py b/numpy/core/tests/test_einsum.py index e77c270c7b26..702be2486515 100644 --- a/numpy/core/tests/test_einsum.py +++ b/numpy/core/tests/test_einsum.py @@ -10,6 +10,12 @@ assert_raises, suppress_warnings, assert_raises_regex, assert_allclose ) +try: + COMPILERS = np.show_config(mode="dicts")["Compilers"] + USING_CLANG_CL = COMPILERS["c"]["name"] == "clang-cl" +except TypeError: + USING_CLANG_CL = False + # Setup for optimize einsum chars = 'abcdefghij' sizes = np.array([2, 3, 4, 5, 4, 3, 2, 6, 5, 4, 3]) @@ -611,13 +617,23 @@ def check_einsum_sums(self, dtype, do_opt=False): [2.]) # contig_stride0_outstride0_two def test_einsum_sums_int8(self): - if sys.platform == 'darwin' and platform.machine() == 'x86_64': - pytest.xfail('Fails on macOS x86-64 with Meson, see gh-23838') + if ( + (sys.platform == 'darwin' and platform.machine() == 'x86_64') + or + USING_CLANG_CL + ): + pytest.xfail('Fails on macOS x86-64 and when using clang-cl ' + 'with Meson, see gh-23838') self.check_einsum_sums('i1') def test_einsum_sums_uint8(self): - if sys.platform == 'darwin' and platform.machine() == 'x86_64': - pytest.xfail('Fails on macOS x86-64 with Meson, see gh-23838') + if ( + (sys.platform == 'darwin' and platform.machine() == 'x86_64') + or + USING_CLANG_CL + ): + pytest.xfail('Fails on macOS x86-64 and when using clang-cl ' + 'with Meson, see gh-23838') self.check_einsum_sums('u1') def test_einsum_sums_int16(self): diff --git a/numpy/core/tests/test_scalarmath.py b/numpy/core/tests/test_scalarmath.py index c737099c1b55..9977c8b1163b 100644 --- a/numpy/core/tests/test_scalarmath.py +++ b/numpy/core/tests/test_scalarmath.py @@ -17,6 +17,12 @@ assert_warns, _SUPPORTS_SVE, ) +try: + COMPILERS = np.show_config(mode="dicts")["Compilers"] + USING_CLANG_CL = COMPILERS["c"]["name"] == "clang-cl" +except TypeError: + USING_CLANG_CL = False + types = [np.bool_, np.byte, np.ubyte, np.short, np.ushort, np.intc, np.uintc, np.int_, np.uint, np.longlong, np.ulonglong, np.single, np.double, np.longdouble, np.csingle, @@ -798,7 +804,13 @@ class TestBitShifts: @pytest.mark.parametrize('op', [operator.rshift, operator.lshift], ids=['>>', '<<']) def test_shift_all_bits(self, type_code, op): - """ Shifts where the shift amount is the width of the type or wider """ + """Shifts where the shift amount is the width of the type or wider """ + if ( + USING_CLANG_CL and + type_code in ("l", "L") and + op is operator.lshift + ): + pytest.xfail("Failing on clang-cl builds") # gh-2449 dt = np.dtype(type_code) nbits = dt.itemsize * 8