diff --git a/.cibw/test-linux-debian.sh b/.cibw/test-linux-debian.sh new file mode 100755 index 0000000..dc80f32 --- /dev/null +++ b/.cibw/test-linux-debian.sh @@ -0,0 +1,16 @@ +#!/bin/bash +set -euo pipefail + +packages=( + python3.11-venv + pypy3 + libmpich12 + libopenmpi3 +) +sudo=$(command -v sudo || true) +$sudo apt update -y +$sudo apt install -y ${packages[@]} +$sudo ln -sr /usr/lib/$(arch)-linux-gnu/libmpi{ch,}.so.12 + +sdir=$(cd "$(dirname -- "$0")" && pwd -P) +$sdir/test-wheel.sh diff --git a/.cibw/test-linux-fedora.sh b/.cibw/test-linux-fedora.sh new file mode 100755 index 0000000..e2f398e --- /dev/null +++ b/.cibw/test-linux-fedora.sh @@ -0,0 +1,25 @@ +#!/bin/bash +set -euo pipefail + +packages=( + python3.6 + python3.7 + python3.8 + python3.9 + python3.10 + python3.11 + python3.12 + pypy3.9 + pypy3.10 + mpich + openmpi +) +sudo=$(command -v sudo || true) +opts=--setopt=install_weak_deps=False +$sudo dnf install -y $opts ${packages[@]} +set +u +source /etc/profile.d/modules.sh +set -u + +sdir=$(cd "$(dirname -- "$0")" && pwd -P) +$sdir/test-wheel.sh diff --git a/.cibw/test-linux-ubuntu.sh b/.cibw/test-linux-ubuntu.sh new file mode 100755 index 0000000..c71a757 --- /dev/null +++ b/.cibw/test-linux-ubuntu.sh @@ -0,0 +1,17 @@ +#!/bin/bash +set -euo pipefail + +packages=( + python3.10-venv + python3.11-venv + pypy3 + libmpich12 + libopenmpi3 +) +sudo=$(command -v sudo || true) +$sudo apt update -y +$sudo apt install -y ${packages[@]} +$sudo ln -sr /usr/lib/$(arch)-linux-gnu/libmpi{ch,}.so.12 + +sdir=$(cd "$(dirname -- "$0")" && pwd -P) +$sdir/test-wheel.sh diff --git a/.cibw/test-macos.sh b/.cibw/test-macos.sh new file mode 100755 index 0000000..a163d14 --- /dev/null +++ b/.cibw/test-macos.sh @@ -0,0 +1,24 @@ +#!/bin/bash +set -euo pipefail + +packages_py=( + python@3.8 + python@3.9 + python@3.10 + python@3.11 + python@3.12 + pypy3.9 + pypy3.10 +) +packages_mpi=( + mpich + openmpi +) +brew install ${packages_py[@]} +for mpi in ${packages_mpi[@]}; do + brew install $mpi + brew unlink $mpi +done + +sdir=$(cd "$(dirname -- "$0")" && pwd -P) +$sdir/test-wheel.sh diff --git a/.cibw/test-wheel.sh b/.cibw/test-wheel.sh new file mode 100755 index 0000000..c00f4ab --- /dev/null +++ b/.cibw/test-wheel.sh @@ -0,0 +1,85 @@ +#!/bin/bash +set -euo pipefail + +PYTHON=( + python3.6 + python3.7 + python3.8 + python3.9 + python3.10 + python3.11 + python3.12 + pypy3.7 + pypy3.8 + pypy3.9 +) + +wheelhouse=${1:-dist} +venvroot=$(mktemp -d) +trap "rm -rf $venvroot" EXIT +export PIP_QUIET=1 + +if [[ $(uname) =~ NT ]]; then + MPI=(impi msmpi) + OSTYPE=nt +else + MPI=(mpich openmpi) + OSTYPE=posix +fi + +function setup-python { + local python=$1 + venvdir=$venvroot/$python + $python -m venv $venvdir + if [[ $OSTYPE == posix ]]; then + source $venvdir/bin/activate + else + export PATH="$venvdir\\Scripts;$PATH" + hash -r 2> /dev/null + fi + command -v python + python -m pip install pip --upgrade +} + +function setup-mpi4py { + local dist=$1 + python -m pip install mpi4py --no-index --find-links=$dist +} + +function setup-mpi { + local mpi=$1 + if command -v brew > /dev/null; then + brew unlink mpich openmpi > /dev/null + brew link $mpi > /dev/null + elif command -v module > /dev/null; then + module unload mpi + module load mpi/$mpi-$(arch) + else + export MPI4PY_MPIABI=$mpi + fi +} + +function mpi4py-test-basic { + python --version + python -m mpi4py --version + python -m mpi4py --mpi-std-version + python -m mpi4py --mpi-lib-version | head -n 1 + printf "\n" +} + +for python in ${PYTHON[@]}; do + test -z "$(command -v $python)" && continue + setup-python $python + setup-mpi4py $wheelhouse + for mpi in ${MPI[@]}; do + setup-mpi $mpi + mpi4py-test-basic + export MPI4PY_MPIABI=$mpi + mpi4py-test-basic + if [ $mpi == mpich -o $mpi == openmpi ]; then + export MPI4PY_MPIABI=mpi31-$mpi + mpi4py-test-basic + fi + unset MPI4PY_MPIABI + done +done diff --git a/.github/workflows/cd-wheel.yml b/.github/workflows/cd-wheel.yml index 8bfbe0f..af2b986 100644 --- a/.github/workflows/cd-wheel.yml +++ b/.github/workflows/cd-wheel.yml @@ -252,149 +252,285 @@ jobs: name: wheel-${{ runner.os }} path: dist/*.whl - test-setup: + test-Linux: + if: ${{ contains(needs.setup.outputs.os-arch-list, '"Linux-x86_64"') }} needs: [setup, merge] - runs-on: 'ubuntu-latest' - outputs: - matrix-test-cf: ${{ steps.setup.outputs.matrix-test-cf }} - matrix-test-gh: ${{ steps.setup.outputs.matrix-test-gh }} + runs-on: ${{ matrix.runner }} + strategy: + fail-fast: false + matrix: + runner: + - ubuntu-latest + steps: - uses: actions/checkout@v4 - - if: ${{ contains(needs.setup.outputs.os-arch-list, '"Linux-x86_64"') }} - uses: actions/download-artifact@v3 + - uses: actions/download-artifact@v3 with: - name: build-Linux-x86_64 - path: wheelhouse - - if: ${{ contains(needs.setup.outputs.os-arch-list, '"macOS-x86_64"') }} - uses: actions/download-artifact@v3 + name: wheel-${{ runner.os }} + path: dist + + - uses: docker://debian:latest with: - name: build-macOS-x86_64 - path: wheelhouse - - if: ${{ contains(needs.setup.outputs.os-arch-list, '"Windows-AMD64"') }} - uses: actions/download-artifact@v3 + entrypoint: /bin/bash + args: .cibw/test-linux-debian.sh + + - uses: docker://ubuntu:latest with: - name: build-Windows-AMD64 - path: wheelhouse - - id: setup - run: python -u .cibw/setup-test.py wheelhouse >> "$GITHUB_OUTPUT" - - test-cf: - if: ${{ needs.test-setup.outputs.matrix-test-cf != '[]' }} - needs: test-setup - runs-on: ${{ (matrix.os == 'Linux' && 'ubuntu-latest' ) || - (matrix.os == 'macOS' && 'macos-latest' ) || - (matrix.os == 'Windows' && 'windows-latest') }} + entrypoint: /bin/bash + args: .cibw/test-linux-ubuntu.sh + + - uses: docker://fedora:latest + with: + entrypoint: /bin/bash + args: .cibw/test-linux-fedora.sh + + test-macOS: + if: ${{ contains(needs.setup.outputs.os-arch-list, '"macOS-x86_64"') }} + needs: [setup, merge] + runs-on: ${{ matrix.runner }} strategy: fail-fast: false matrix: - include: ${{ fromJSON(needs.test-setup.outputs.matrix-test-cf) }} - + runner: + - macos-11 + - macos-12 + - macos-13 defaults: run: - shell: bash -el {0} + shell: bash steps: - - uses: actions/checkout@v4 - - - uses: mamba-org/setup-micromamba@v1 - with: - init-shell: bash - post-cleanup: none - environment-name: test - create-args: >- - ${{ matrix.mpi }}=${{ matrix.mpi-version }} - python=${{ matrix.py }} - pip - condarc: | - show_channel_urls: true - channel_priority: >- - ${{ matrix.mpi == 'impi_rt' && 'flexible' || 'strict' }} - channels: - - conda-forge - - ${{ matrix.mpi == 'impi_rt' && 'intel' || 'nodefaults' }} - - nodefaults - - - run: | - # Tweak MPI runtime - case $(uname)-${{ matrix.mpi }} in - Linux-*) - ;; - Darwin-*) - ;; - *NT*-impi_rt) - I_MPI_ROOT=$(cygpath -w "$CONDA_PREFIX/Library") - echo "I_MPI_ROOT=$I_MPI_ROOT" >> $GITHUB_ENV - echo "$I_MPI_ROOT\\bin" >> $GITHUB_PATH - echo "$I_MPI_ROOT\\bin\\libfabric" >> $GITHUB_PATH - ;; - *NT*-msmpi) - MSMPI_ROOT=$(cygpath -w "$CONDA_PREFIX/Library") - echo "MSMPI_BIN=$MSMPI_ROOT\\bin" >> $GITHUB_ENV - echo "MSMPI_INC=$MSMPI_ROOT\\include" >> $GITHUB_ENV - echo "MSMPI_LIB64=$MSMPI_ROOT\\lib" >> $GITHUB_ENV - echo "$MSMPI_BIN" >> $GITHUB_PATH - ;; - esac - - uses: actions/download-artifact@v3 with: name: wheel-${{ runner.os }} path: dist - - run: python -m pip install mpi4py --no-index --find-links=dist - - - uses: ./.github/actions/mpi4py-test-basic - timeout-minutes: 2 - with: - shell: bash -el {0} + - run: .cibw/test-macos.sh - - if: ${{ matrix.mpi == 'mpich' || matrix.mpi == 'openmpi' }} - uses: ./.github/actions/mpi4py-test-basic - timeout-minutes: 2 - env: - MPI4PY_MPIABI: mpi31-${{ matrix.mpi }} - with: - shell: bash -el {0} - - test-gh: - if: ${{ needs.test-setup.outputs.matrix-test-gh != '[]' }} - needs: test-setup + test-Windows: + if: ${{ contains(needs.setup.outputs.os-arch-list, '"Windows-AMD64"') }} + needs: [setup, merge] runs-on: ${{ matrix.runner }} strategy: fail-fast: false matrix: - include: ${{ fromJSON(needs.test-setup.outputs.matrix-test-gh) }} + runner: + - windows-2019 + - windows-2022 + defaults: + run: + shell: bash steps: - - uses: actions/checkout@v4 + - uses: actions/download-artifact@v3 + with: + name: wheel-${{ runner.os }} + path: dist - - uses: mpi4py/setup-mpi@v1 + - uses: actions/setup-python@v4 with: - mpi: ${{ matrix.mpi }} + python-version: '3.8' + update-environment: false + id: cp38 + - run: dirname ${{ steps.cp38.outputs.python-path }} >> $GITHUB_PATH - - if: ${{ matrix.mpi == 'mpich' && runner.os == 'Linux' }} - run: cd /usr/lib/$(gcc -print-multiarch) && sudo ln -s libmpi{ch,}.so.12 + - uses: actions/setup-python@v4 + with: + python-version: '3.9' + update-environment: false + id: cp39 + - run: dirname ${{ steps.cp39.outputs.python-path }} >> $GITHUB_PATH - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v4 with: - python-version: ${{ matrix.py }} + python-version: '3.10' + update-environment: false + id: cp310 + - run: dirname ${{ steps.cp310.outputs.python-path }} >> $GITHUB_PATH - - run: python -m pip install --upgrade pip + - uses: actions/setup-python@v4 + with: + python-version: '3.11' + update-environment: false + id: cp311 + - run: dirname ${{ steps.cp311.outputs.python-path }} >> $GITHUB_PATH - - uses: actions/download-artifact@v3 + - uses: actions/setup-python@v4 with: - name: wheel-${{ runner.os }} - path: dist + python-version: '3.12' + update-environment: false + id: cp312 + - run: dirname ${{ steps.cp312.outputs.python-path }} >> $GITHUB_PATH + + - uses: actions/setup-python@v4 + with: + python-version: 'pypy-3.8' + update-environment: false + id: pp38 + - run: dirname ${{ steps.pp38.outputs.python-path }} >> $GITHUB_PATH - - run: python -m pip install mpi4py --no-index --find-links=dist + - uses: actions/setup-python@v4 + with: + python-version: 'pypy-3.9' + update-environment: false + id: pp39 + - run: dirname ${{ steps.pp39.outputs.python-path }} >> $GITHUB_PATH - - uses: ./.github/actions/mpi4py-test-basic - timeout-minutes: 2 + - uses: mpi4py/setup-mpi@v1 + with: + mpi: intelmpi - - if: ${{ matrix.mpi == 'mpich' || matrix.mpi == 'openmpi' }} - uses: ./.github/actions/mpi4py-test-basic - timeout-minutes: 2 - env: - MPI4PY_MPIABI: mpi31-${{ matrix.mpi }} + - uses: mpi4py/setup-mpi@v1 + with: + mpi: msmpi + + - run: .cibw/test-wheel.sh + +# test-setup: +# needs: [setup, merge] +# runs-on: 'ubuntu-latest' +# outputs: +# matrix-test-cf: ${{ steps.setup.outputs.matrix-test-cf }} +# matrix-test-gh: ${{ steps.setup.outputs.matrix-test-gh }} +# steps: +# - uses: actions/checkout@v4 +# - if: ${{ contains(needs.setup.outputs.os-arch-list, '"Linux-x86_64"') }} +# uses: actions/download-artifact@v3 +# with: +# name: build-Linux-x86_64 +# path: wheelhouse +# - if: ${{ contains(needs.setup.outputs.os-arch-list, '"macOS-x86_64"') }} +# uses: actions/download-artifact@v3 +# with: +# name: build-macOS-x86_64 +# path: wheelhouse +# - if: ${{ contains(needs.setup.outputs.os-arch-list, '"Windows-AMD64"') }} +# uses: actions/download-artifact@v3 +# with: +# name: build-Windows-AMD64 +# path: wheelhouse +# - id: setup +# run: python -u .cibw/setup-test.py wheelhouse >> "$GITHUB_OUTPUT" +# +# test-cf: +# if: ${{ needs.test-setup.outputs.matrix-test-cf != '[]' }} +# needs: test-setup +# runs-on: ${{ (matrix.os == 'Linux' && 'ubuntu-latest' ) || +# (matrix.os == 'macOS' && 'macos-latest' ) || +# (matrix.os == 'Windows' && 'windows-latest') }} +# strategy: +# fail-fast: false +# matrix: +# include: ${{ fromJSON(needs.test-setup.outputs.matrix-test-cf) }} +# +# defaults: +# run: +# shell: bash -el {0} +# +# steps: +# +# - uses: actions/checkout@v4 +# +# - uses: mamba-org/setup-micromamba@v1 +# with: +# init-shell: bash +# post-cleanup: none +# environment-name: test +# create-args: >- +# ${{ matrix.mpi }}=${{ matrix.mpi-version }} +# python=${{ matrix.py }} +# pip +# condarc: | +# show_channel_urls: true +# channel_priority: >- +# ${{ matrix.mpi == 'impi_rt' && 'flexible' || 'strict' }} +# channels: +# - conda-forge +# - ${{ matrix.mpi == 'impi_rt' && 'intel' || 'nodefaults' }} +# - nodefaults +# +# - run: | +# # Tweak MPI runtime +# case $(uname)-${{ matrix.mpi }} in +# Linux-*) +# ;; +# Darwin-*) +# ;; +# *NT*-impi_rt) +# I_MPI_ROOT=$(cygpath -w "$CONDA_PREFIX/Library") +# echo "I_MPI_ROOT=$I_MPI_ROOT" >> $GITHUB_ENV +# echo "$I_MPI_ROOT\\bin" >> $GITHUB_PATH +# echo "$I_MPI_ROOT\\bin\\libfabric" >> $GITHUB_PATH +# ;; +# *NT*-msmpi) +# MSMPI_ROOT=$(cygpath -w "$CONDA_PREFIX/Library") +# echo "MSMPI_BIN=$MSMPI_ROOT\\bin" >> $GITHUB_ENV +# echo "MSMPI_INC=$MSMPI_ROOT\\include" >> $GITHUB_ENV +# echo "MSMPI_LIB64=$MSMPI_ROOT\\lib" >> $GITHUB_ENV +# echo "$MSMPI_BIN" >> $GITHUB_PATH +# ;; +# esac +# +# - uses: actions/download-artifact@v3 +# with: +# name: wheel-${{ runner.os }} +# path: dist +# +# - run: python -m pip install mpi4py --no-index --find-links=dist +# +# - uses: ./.github/actions/mpi4py-test-basic +# timeout-minutes: 2 +# with: +# shell: bash -el {0} +# +# - if: ${{ matrix.mpi == 'mpich' || matrix.mpi == 'openmpi' }} +# uses: ./.github/actions/mpi4py-test-basic +# timeout-minutes: 2 +# env: +# MPI4PY_MPIABI: mpi31-${{ matrix.mpi }} +# with: +# shell: bash -el {0} +# +# test-gh: +# if: ${{ needs.test-setup.outputs.matrix-test-gh != '[]' }} +# needs: test-setup +# runs-on: ${{ matrix.runner }} +# strategy: +# fail-fast: false +# matrix: +# include: ${{ fromJSON(needs.test-setup.outputs.matrix-test-gh) }} +# +# steps: +# +# - uses: actions/checkout@v4 +# +# - uses: mpi4py/setup-mpi@v1 +# with: +# mpi: ${{ matrix.mpi }} +# +# - if: ${{ matrix.mpi == 'mpich' && runner.os == 'Linux' }} +# run: cd /usr/lib/$(gcc -print-multiarch) && sudo ln -s libmpi{ch,}.so.12 +# +# - uses: actions/setup-python@v4 +# with: +# python-version: ${{ matrix.py }} +# +# - run: python -m pip install --upgrade pip +# +# - uses: actions/download-artifact@v3 +# with: +# name: wheel-${{ runner.os }} +# path: dist +# +# - run: python -m pip install mpi4py --no-index --find-links=dist +# +# - uses: ./.github/actions/mpi4py-test-basic +# timeout-minutes: 2 +# +# - if: ${{ matrix.mpi == 'mpich' || matrix.mpi == 'openmpi' }} +# uses: ./.github/actions/mpi4py-test-basic +# timeout-minutes: 2 +# env: +# MPI4PY_MPIABI: mpi31-${{ matrix.mpi }}