diff --git a/.github/workflows/cygwin.yml b/.github/workflows/cygwin.yml new file mode 100644 index 000000000000..a8a294985fb6 --- /dev/null +++ b/.github/workflows/cygwin.yml @@ -0,0 +1,70 @@ +name: Cygwin Tests + +on: + push: + branches: + - main + - maintenance/** + pull_request: + branches: + - main + - maintenance/** + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +jobs: + cygwin: + name: Cygwin tests + runs-on: windows-latest + env: + SHELLOPTS: igncr + CHERE_INVOKING: 1 + CYGWIN_NOWINPATH: 1 + PYTHONPATH: /usr/local/lib/python3.8/site-packages + steps: + - run: git config --global core.autocrlf input + - uses: actions/checkout@v3 + with: + submodules: recursive + - uses: cygwin/cygwin-install-action@v2 + with: + packages: >- + gcc-g++ gcc-fortran liblapack-devel libopenblas libmpfr-devel ccache swig libmpc-devel + libumfpack-devel libsliplu-devel libldl-devel libklu-devel libcxsparse-devel libcholmod-devel libamd-devel + python38-devel python38-pip python38-setuptools python38-wheel python38-numpy python38-cython + python38-pytest + meson ninja cmake make git + - name: Fix git config + shell: bash.exe -eo pipefail -o igncr "{0}" + run: /usr/bin/git config --system --add safe.directory /cygdrive/d/a/*/scipy + - name: Install Python dependencies + shell: bash.exe -eo pipefail -o igncr "{0}" + run: | + mkdir builds + cd builds + python3.8 -m pip install --upgrade pip 'setuptools<60' wheel + python3.8 -m pip install --upgrade numpy cython pytest pytest-xdist pytest-timeout pybind11 + python3.8 -m pip install --upgrade mpmath gmpy2 pythran threadpoolctl pooch + python3.8 -m pip uninstall -y nose + cd .. + - name: Check NumPy import + shell: bash.exe -eo pipefail -o igncr "{0}" + run: /usr/bin/env PATH="/bin:/usr/bin:/usr/local/bin:/usr/lib/lapack" python3.8 -c "import numpy as np; print(np.__version__)" + - name: Building SciPy + shell: bash.exe -eo pipefail -o igncr "{0}" + env: + CPPFLAGS: -D_XOPEN_SOURCE=600 + run: /usr/bin/env PATH="/bin:/usr/bin:/usr/local/bin:/usr/lib/lapack" python3.8 -u runtests.py -g -j2 --build-only + - name: Check SciPy installs + shell: bash.exe -eo pipefail -o igncr "{0}" + if: false + env: + CPPFLAGS: -D_XOPEN_SOURCE=600 + run: /usr/bin/env PATH="/bin:/usr/bin:/usr/local/bin:/usr/lib/lapack" python3.8 -m pip install -e . + - name: Testing SciPy + shell: bash.exe -eo pipefail -o igncr "{0}" + run: | + /usr/bin/env PATH="/bin:/usr/bin:/usr/local/bin:/usr/lib/lapack" python3.8 -u runtests.py -n -g -j2 -m fast -- -rfEX --durations=10 --timeout=60 2>&1 | tee runtests.log + python3.8 tools/validate_runtests_log.py fast < runtests.log diff --git a/.github/workflows/cygwin_meson.yml b/.github/workflows/cygwin_meson.yml new file mode 100644 index 000000000000..a24db6c56941 --- /dev/null +++ b/.github/workflows/cygwin_meson.yml @@ -0,0 +1,131 @@ +name: Cygwin Meson tests + +# This is a single job: Python 3.9, building with Meson, using -Werror to +# ensure we remain at zero build warnings. Other Meson CI jobs are running +# on https://github.com/rgommers/scipy/tree/meson + +on: + push: + branches: + - main + - maintenance/** + pull_request: + branches: + - main + - maintenance/** + workflow_dispatch: + +permissions: + contents: read # to fetch code (actions/checkout) + +env: + CCACHE_DIR: "${{ github.workspace }}/.ccache" + INSTALLDIR: "build-install" + CPPFLAGS: "-D_XOPEN_SOURCE=700" + SHELLOPTS: igncr + CHERE_INVOKING: 1 + CYGWIN_NOWINPATH: 1 + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +jobs: + test_meson: + name: Cygwin Meson build + runs-on: windows-latest + strategy: + matrix: + python-minor-version: ['9'] + env: + PYTHONPATH: "/usr/local/lib/python3.${{ matrix.python-minor-version }}/site-packages" + + steps: + - run: git config --global core.autocrlf input + + - uses: actions/checkout@v3 + with: + submodules: recursive + + - uses: cygwin/cygwin-install-action@v3 + with: + packages: >- + gcc-g++ gcc-fortran liblapack-devel libopenblas libmpfr-devel ccache swig libmpc-devel + libumfpack-devel libsliplu-devel libldl-devel libklu-devel libcxsparse-devel libcholmod-devel libamd-devel + python3${{ matrix.python-minor-version }}-devel + python3${{ matrix.python-minor-version }}-pip + python3${{ matrix.python-minor-version }}-setuptools + python3${{ matrix.python-minor-version }}-wheel + python3${{ matrix.python-minor-version }}-numpy + python3${{ matrix.python-minor-version }}-cython + python3${{ matrix.python-minor-version }}-pytest + meson ninja cmake make git + + - name: Fix git config + shell: bash.exe -eo pipefail -o igncr "{0}" + run: /usr/bin/git config --system --add safe.directory /cygdrive/d/a/*/scipy + + - name: Install Python packages + shell: bash.exe -eo pipefail -o igncr "{0}" + run: | + python -m pip install numpy cython pytest pytest-xdist pytest-timeout pybind11 mpmath gmpy2 pythran click rich-click doit pydevtool pooch + python -m pip install meson'>=0.64.0' ninja tomli + + - name: Prepare compiler cache + id: prep-ccache + shell: bash.exe -eo pipefail -o igncr "{0}" + run: | + mkdir -p "${CCACHE_DIR}" + echo "dir=$(cygpath -wa $CCACHE_DIR)" >> $GITHUB_OUTPUT + NOW=$(date -u +"%F-%T") + echo "timestamp=${NOW}" >> $GITHUB_OUTPUT + - name: Setup compiler cache + uses: actions/cache@v3 + id: cache-ccache + # Reference: https://docs.github.com/en/actions/guides/caching-dependencies-to-speed-up-workflows#matching-a-cache-key + # NOTE: The caching strategy is modeled in a way that it will always have a unique cache key for each workflow run + # (even if the same workflow is run multiple times). The restore keys are not unique and for a partial match, they will + # return the most recently created cache entry, according to the GitHub Action Docs. + with: + path: ${{ steps.prep-ccache.outputs.dir }} + # Restores ccache from either a previous build on this branch or on main + key: ${{ github.workflow }}-${{ matrix.python-version }}-ccache-linux-${{ steps.prep-ccache.outputs.timestamp }} + # This evaluates to `Linux Tests-3.9-ccache-linux-` which is not unique. As the CI matrix is expanded, this will + # need to be updated to be unique so that the cache is not restored from a different job altogether. + restore-keys: | + ${{ github.workflow }}-${{ matrix.python-version }}-ccache-linux- + - name: Setup build and install scipy + shell: bash.exe -eo pipefail -o igncr "{0}" + run: | + export PATH="/usr/local/bin:/usr/bin:/bin:/usr/lib/lapack" + meson setup build -Dblas=blas -Dlapack=lapack --prefix=$(pwd)/${INSTALLDIR} + python dev.py build -j 2 --werror + - name: Ccache performance + shell: bash -l -eo pipefail -o igncr "{0}" + run: ccache -s + + - name: Check installation + shell: bash.exe -eo pipefail -o igncr "{0}" + run: | + export PATH="/usr/local/bin:/usr/bin:/bin:/usr/lib/lapack" + pushd tools + python check_installation.py ${{ env.INSTALLDIR }} + ./check_pyext_symbol_hiding.sh ../build + popd + - name: Check import + shell: bash.exe -eo pipefail -o igncr "{0}" + run: | + export PATH="/usr/local/bin:/usr/bin:/bin:/usr/lib/lapack" + pushd build-install + export PYTHONPATH="$(pwd)/lib/python3.${{ matrix.python-minor-version }}/site-packages/" + ls ${PYTHONPATH} ${PYTHONPATH}/scipy/* + python -vvv -d -c "import scipy.linalg" + popd + + - name: Test SciPy + shell: bash.exe -eo pipefail -o igncr "{0}" + run: | + export PATH="/usr/local/bin:/usr/bin:/bin:/usr/lib/lapack" + export OMP_NUM_THREADS=2 + export SCIPY_USE_PROPACK=1 + python dev.py --no-build test -j 2 -- --durations 10 --timeout=60 diff --git a/dev.py b/dev.py index 1594931996e0..26f46274ec4c 100644 --- a/dev.py +++ b/dev.py @@ -436,6 +436,13 @@ def setup_build(cls, dirs, args): raise RuntimeError("Can't build into non-empty directory " f"'{build_dir.absolute()}'") + if sys.platform == "cygwin": + # Cygwin only has netlib lapack, but can link against + # OpenBLAS rather than netlib blas at runtime. There is + # no libopenblas-devel to enable linking against + # openblas-specific functions or OpenBLAS Lapack + cmd.extend(["-Dlapack=lapack", "-Dblas=blas"]) + build_options_file = ( build_dir / "meson-info" / "intro-buildoptions.json") if build_options_file.exists(): @@ -547,6 +554,11 @@ def install_project(cls, dirs, args): with open(dirs.installed / ".gitignore", "w") as f: f.write("*") + if sys.platform == "cygwin": + rebase_cmd = ["/usr/bin/rebase", "--database", "--oblivious"] + rebase_cmd.extend(Path(dirs.installed).glob("**/*.dll")) + subprocess.check_call(rebase_cmd) + print("Installation OK") return diff --git a/scipy/integrate/meson.build b/scipy/integrate/meson.build index 97c85b99dcf4..1b38a9ed9f46 100644 --- a/scipy/integrate/meson.build +++ b/scipy/integrate/meson.build @@ -136,7 +136,7 @@ py3.extension_module('_vode', c_args: [numpy_nodepr_api, Wno_unused_variable], include_directories: [inc_np, inc_f2py], link_args: version_link_args, - dependencies: [lapack, fortranobject_dep], + dependencies: [lapack, blas, fortranobject_dep], install: true, link_language: 'fortran', subdir: 'scipy/integrate' diff --git a/scipy/linalg/meson.build b/scipy/linalg/meson.build index ce383e5d51cb..241a80272be2 100644 --- a/scipy/linalg/meson.build +++ b/scipy/linalg/meson.build @@ -55,7 +55,7 @@ py3.extension_module('_fblas', c_args: numpy_nodepr_api, include_directories: [inc_np, inc_f2py], link_args: version_link_args, - dependencies: [blas, lapack, fortranobject_dep], + dependencies: [lapack, blas, fortranobject_dep], install: true, link_language: 'fortran', subdir: 'scipy/linalg' @@ -76,7 +76,7 @@ py3.extension_module('_flapack', c_args: [numpy_nodepr_api, Wno_empty_body], include_directories: [inc_np, inc_f2py], link_args: version_link_args, - dependencies: [lapack, fortranobject_dep], + dependencies: [lapack, blas, fortranobject_dep], install: true, link_language: 'fortran', subdir: 'scipy/linalg' @@ -204,7 +204,7 @@ cython_blas = py3.extension_module('cython_blas', link_with: fwrappers, include_directories: inc_np, link_args: version_link_args, - dependencies: [blas, lapack], + dependencies: [lapack, blas], install: true, link_language: 'fortran', subdir: 'scipy/linalg' @@ -220,7 +220,7 @@ cython_lapack = py3.extension_module('cython_lapack', link_with: fwrappers, include_directories: inc_np, link_args: version_link_args, - dependencies: [blas, lapack], + dependencies: [lapack, blas], install: true, link_language: 'fortran', subdir: 'scipy/linalg' diff --git a/scipy/optimize/_trlib/meson.build b/scipy/optimize/_trlib/meson.build index 66fa0a39205c..c2cabb6c9796 100644 --- a/scipy/optimize/_trlib/meson.build +++ b/scipy/optimize/_trlib/meson.build @@ -8,7 +8,7 @@ _trlib = py3.extension_module('_trlib', 'trlib_tri_factor.c' ], c_args: cython_c_args, - dependencies: [lapack], + dependencies: [lapack, blas], include_directories: [ inc_np, '../../_lib', diff --git a/scipy/optimize/meson.build b/scipy/optimize/meson.build index 05db6a680404..595febb1d896 100644 --- a/scipy/optimize/meson.build +++ b/scipy/optimize/meson.build @@ -109,7 +109,7 @@ _lbfgsb = py3.extension_module('_lbfgsb', fortran_args: fortran_ignore_warnings, include_directories: [inc_np, inc_f2py], link_args: version_link_args, - dependencies: [lapack, fortranobject_dep], + dependencies: [lapack, blas, fortranobject_dep], install: true, link_language: 'fortran', subdir: 'scipy/optimize' diff --git a/scipy/sparse/linalg/_dsolve/meson.build b/scipy/sparse/linalg/_dsolve/meson.build index bf16643fe94c..4634cae247f8 100644 --- a/scipy/sparse/linalg/_dsolve/meson.build +++ b/scipy/sparse/linalg/_dsolve/meson.build @@ -199,7 +199,7 @@ _superlu = py3.extension_module('_superlu', link_with: [superlu_lib], include_directories: [incdir_numpy, 'SuperLU/SRC'], link_args: version_link_args, - dependencies: [blas, lapack], + dependencies: [lapack, blas], install: true, subdir: 'scipy/sparse/linalg/_dsolve' ) diff --git a/scipy/sparse/linalg/_eigen/arpack/meson.build b/scipy/sparse/linalg/_eigen/arpack/meson.build index bc77d411aabb..5b469a37914f 100644 --- a/scipy/sparse/linalg/_eigen/arpack/meson.build +++ b/scipy/sparse/linalg/_eigen/arpack/meson.build @@ -103,7 +103,7 @@ _arpack = py3.extension_module('_arpack', link_with: [arpack_lib], include_directories: [incdir_numpy, incdir_f2py], link_args: version_link_args, - dependencies: [lapack, fortranobject_dep], + dependencies: [lapack, blas, fortranobject_dep], install: true, link_language: 'fortran', subdir: 'scipy/sparse/linalg/_eigen/arpack' diff --git a/scipy/sparse/linalg/_isolve/meson.build b/scipy/sparse/linalg/_isolve/meson.build index 3009201862af..9af9fa146e6e 100644 --- a/scipy/sparse/linalg/_isolve/meson.build +++ b/scipy/sparse/linalg/_isolve/meson.build @@ -74,7 +74,7 @@ _iterative = py3.extension_module('_iterative', fortran_args: fortran_ignore_warnings, include_directories: [inc_np, inc_f2py], link_args: version_link_args, - dependencies: [lapack, fortranobject_dep], + dependencies: [lapack, blas, fortranobject_dep], install: true, link_language: 'fortran', subdir: 'scipy/sparse/linalg/_isolve' diff --git a/scipy/sparse/linalg/_propack/meson.build b/scipy/sparse/linalg/_propack/meson.build index 745d010ceb0a..898ecfb6b9be 100644 --- a/scipy/sparse/linalg/_propack/meson.build +++ b/scipy/sparse/linalg/_propack/meson.build @@ -109,7 +109,7 @@ foreach ele: elements link_with: propack_lib, c_args: ['-U_OPENMP', _cpp_Wno_cpp], fortran_args: _fflag_Wno_maybe_uninitialized, - dependencies: [lapack, fortranobject_dep], + dependencies: [lapack, blas, fortranobject_dep], include_directories: [inc_np, inc_f2py], link_args: version_link_args, install: true, diff --git a/scipy/special/_faddeeva.cxx b/scipy/special/_faddeeva.cxx index 6b619fb70bc5..7378b2770078 100644 --- a/scipy/special/_faddeeva.cxx +++ b/scipy/special/_faddeeva.cxx @@ -1,3 +1,4 @@ +#include #include #include diff --git a/scipy/special/_faddeeva.h b/scipy/special/_faddeeva.h index d4ec3a755e2c..4def793ec61d 100644 --- a/scipy/special/_faddeeva.h +++ b/scipy/special/_faddeeva.h @@ -9,6 +9,7 @@ #define EXTERN_C_END #endif +#include #include #include diff --git a/scipy/special/wright.hh b/scipy/special/wright.hh index ef168cba00ec..749f5f67af31 100644 --- a/scipy/special/wright.hh +++ b/scipy/special/wright.hh @@ -1,6 +1,7 @@ #ifndef WRIGHT_HH #define WRIGHT_HH +#include #include namespace wright {