Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

build python wheels for all platforms #4

Merged
merged 24 commits into from
Jun 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
46f01f5
wheels: on windows install pip, on macos set LLVM path
jcschaff Jun 4, 2024
6c90184
explitly invoke cibuildwheel with PATHs set
jcschaff Jun 4, 2024
9258566
upload generated wheels as artifacts
jcschaff Jun 10, 2024
244b583
install wheels in dist/ dir
jcschaff Jun 10, 2024
edc5119
use pip wheel to place wheel in dist, then pip install prior to pytest
jcschaff Jun 10, 2024
ce894f6
add multiple python versions to build matrix
jcschaff Jun 10, 2024
9441d86
upload each wheel independenty, turn on build of exes and docker images
jcschaff Jun 10, 2024
df26c00
upload each wheel file independently
jcschaff Jun 10, 2024
6ef910f
skip all but python 11 for windows
jcschaff Jun 10, 2024
9677241
separate .vcg and .fvinput files for solver input specification
jcschaff Jun 11, 2024
278fbc3
removed static vars, added unit test, some updated C++
jcschaff Jun 13, 2024
c0b670d
fix build error on windows
jcschaff Jun 13, 2024
15d0957
remove mac14 wheel, shouldn't be committed
jcschaff Jun 13, 2024
d7f5b69
filesystem::path need .string().c_str() on windows for const char *
jcschaff Jun 13, 2024
a79e1b4
prepare for PyPI
jcschaff Jun 14, 2024
d587b5d
version as 0.0.2 and add release job to push wheels to test PyPI
jcschaff Jun 14, 2024
62054f8
replace deprecated set-output in GitHub action with use of GITHUB_ENV
jcschaff Jun 14, 2024
c81de15
ignore directories ending in .whl, only move files ending in .whl
jcschaff Jun 14, 2024
f4d6eb3
manylinux docker for linux, repair with auditwheel, delocate, delvewheel
jcschaff Jun 14, 2024
1f7d672
build multiple python version in manylinux, debug macos-13 and windows
jcschaff Jun 14, 2024
16660e3
split build/tests for manylinux pythons, don't repair win wheels
jcschaff Jun 14, 2024
cb74451
add back python 3.10 and remove windows from wheels builds
jcschaff Jun 14, 2024
575d2cb
set version 0.0.3 to refresh test PyPI
jcschaff Jun 14, 2024
9195935
push 0.0.4 to production PyPI for python>=3.9, fix readme link
jcschaff Jun 14, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion .github/workflows/cd.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
name: CD

on: [push, workflow_dispatch]
on:
pull_request:
push:
branches:
- master
release:
types:
- published


env:
REGISTRY: ghcr.io
Expand Down
172 changes: 146 additions & 26 deletions .github/workflows/pip.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ on:
push:
branches:
- master
release:
types:
- published

jobs:
build:
Expand All @@ -14,9 +17,14 @@ jobs:
strategy:
fail-fast: false
matrix:
platform: [windows-latest, macos-13, macos-14, ubuntu-latest]
# python-version: ["3.7", "3.12", "pypy-3.9"]
python-version: ["3.12"]
#platform: [ windows-latest, macos-13, macos-14, ubuntu-latest ]
platform: [ macos-13, macos-14, ubuntu-latest ]
python-version: ["3.9","3.10","3.11","3.12"]
# exclude:
# - platform: windows-latest
# python-version: "3.9"
# - platform: windows-latest
# python-version: "3.12"

steps:
- uses: actions/checkout@v4
Expand Down Expand Up @@ -79,49 +87,94 @@ jobs:
mingw-w64-clang-x86_64-libaec
mingw-w64-clang-x86_64-python-pip-tools


- name: Install Linux Dependencies
if: matrix.platform == 'ubuntu-latest'
run: |
sudo apt-get update
sudo apt-get install -y libboost-all-dev
sudo apt-get install -y libhdf5-dev
sudo apt-get install -y ninja-build

gcc --version
gfortran --version
cmake --version
dpkg -s libboost-all-dev
dpkg -s libhdf5-dev


- uses: actions/setup-python@v5
with:
python-version: "${{ matrix.python-version }}"

- name: Build and install macos-13
run: |
export MACOSX_DEPLOYMENT_TARGET=13.0
PATH="/usr/local/opt/llvm/bin:$PATH"
pip install --verbose .
pip wheel . -w dist
ls -al dist
pip install delocate
delocate-listdeps dist/*.whl
delocate-wheel -v dist/*.whl
pip install dist/*.whl
if: matrix.platform == 'macos-13'

- name: Build and install macos-14
run: |
PATH="/opt/homebrew/opt/llvm/bin:$PATH"
pip install --verbose .
pip wheel . -w dist
ls -al dist
pip install delocate
delocate-listdeps dist/*.whl
delocate-wheel -v dist/*.whl
pip install dist/*.whl
if: matrix.platform == 'macos-14'

- name: Build and install windows-latest
shell: msys2 {0}
run: |
pip install --verbose -Ccmake.define.CMAKE_C_COMPILER="clang.exe" -Ccmake.define.CMAKE_CXX_COMPILER="clang++.exe" .
pip wheel --verbose -Ccmake.define.CMAKE_C_COMPILER="clang.exe" -Ccmake.define.CMAKE_CXX_COMPILER="clang++.exe" . -w dist
pip install delvewheel
for wheel_file in dist/*.whl; do
echo "not inspecting $wheel_file"
echo "delvewheel needed -v $wheel_file"
echo "not repairing $wheel_file"
echo "delvewheel repair -v $wheel_file"
done
pip install dist/*.whl
if: matrix.platform == 'windows-latest'

- name: Build and install ubuntu-latest
- name: Build and install manylinux for python 3.9
run: |
docker run --rm -v $(pwd):/io quay.io/pypa/manylinux2014_x86_64 \
/bin/bash -c \
"yum install -y boost-devel hdf5-devel ninja-build && \
/opt/python/cp39-cp39/bin/pip wheel /io/ -w /io/dist && \
auditwheel repair /io/dist/*.whl -w /io/dist/"
echo "keeping only the manylinux wheels, remove those with -linux_x86_64.whl in the name"
sudo rm -rf dist/*-linux_x86_64.whl
pip install dist/*.whl
if: matrix.platform == 'ubuntu-latest' && matrix.python-version == '3.9'

- name: Build and install manylinux for python 3.10
run: |
docker run --rm -v $(pwd):/io quay.io/pypa/manylinux2014_x86_64 \
/bin/bash -c \
"yum install -y boost-devel hdf5-devel ninja-build && \
/opt/python/cp310-cp310/bin/pip wheel /io/ -w /io/dist && \
auditwheel repair /io/dist/*.whl -w /io/dist/"
echo "keeping only the manylinux wheels, remove those with -linux_x86_64.whl in the name"
sudo rm -rf dist/*-linux_x86_64.whl
pip install dist/*.whl
if: matrix.platform == 'ubuntu-latest' && matrix.python-version == '3.10'

- name: Build and install manylinux for python 3.11
run: |
docker run --rm -v $(pwd):/io quay.io/pypa/manylinux2014_x86_64 \
/bin/bash -c \
"yum install -y boost-devel hdf5-devel ninja-build && \
/opt/python/cp311-cp311/bin/pip wheel /io/ -w /io/dist && \
auditwheel repair /io/dist/*.whl -w /io/dist/"
echo "keeping only the manylinux wheels, remove those with -linux_x86_64.whl in the name"
sudo rm -rf dist/*-linux_x86_64.whl
pip install dist/*.whl
if: matrix.platform == 'ubuntu-latest' && matrix.python-version == '3.11'

- name: Build and install manylinux for python 3.12
run: |
platform=linux
pip install --verbose .
if: matrix.platform == 'ubuntu-latest'
docker run --rm -v $(pwd):/io quay.io/pypa/manylinux2014_x86_64 \
/bin/bash -c \
"yum install -y boost-devel hdf5-devel ninja-build && \
/opt/python/cp312-cp312/bin/pip wheel /io/ -w /io/dist && \
auditwheel repair /io/dist/*.whl -w /io/dist/"
echo "keeping only the manylinux wheels, remove those with -linux_x86_64.whl in the name"
sudo rm -rf dist/*-linux_x86_64.whl
pip install dist/*.whl
if: matrix.platform == 'ubuntu-latest' && matrix.python-version == '3.12'

- name: Test not windows
run: |
Expand All @@ -136,8 +189,75 @@ jobs:
pytest
if: matrix.platform == 'windows-latest'

- name: set wheel_file and artifact_name environment vars (non-windows)
if: matrix.platform != 'windows-latest'
run: |
for wheel_file in dist/*.whl; do
echo "Uploading $wheel_file"
echo "wheel_file=$wheel_file" >> $GITHUB_ENV
echo "artifact_name=$(basename $wheel_file)" >> $GITHUB_ENV
done

- name: set wheel_file and artifact_name environment vars (windows)
if: matrix.platform == 'windows-latest'
shell: pwsh
run: |
foreach ($wheel_file in Get-ChildItem -Path dist -Filter *.whl) {
Write-Output "Uploading $wheel_file"
echo "wheel_file=$wheel_file" | Out-File -Append -FilePath $env:GITHUB_ENV -Encoding utf8
echo "artifact_name=$(Split-Path $wheel_file -Leaf)" | Out-File -Append -FilePath $env:GITHUB_ENV -Encoding utf8
}

- name: Upload wheel file
uses: actions/upload-artifact@v4
with:
name: ${{ env.artifact_name }}
path: ${{ env.wheel_file }}

- name: Setup tmate session
uses: mxschmitt/action-tmate@v3
if: ${{ failure() }}
with:
github-token: ${{ secrets.GITHUB_TOKEN }}

publish-to-pypi:
name: Publish to PyPI
needs: build
runs-on: ubuntu-latest
if: github.event_name == 'release' && github.event.action == 'published'
environment: pypi
permissions:
id-token: write

steps:
- name: download all artifacts (wheels and executables)
uses: actions/download-artifact@v4
with:
path: dist_temp/

- name: Install Python
uses: actions/setup-python@v2
with:
python-version: '3.12'

- name: Publish wheels to PyPI
env:
TWINE_USERNAME: __token__
TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }}
run: |
pip install twine
mkdir dist
echo "current directory is $(pwd)"
ls -al dist*
echo "absolute paths of wheels:"
find dist_temp -type f -name '*.whl' -exec sh -c 'echo "$(realpath {})"/' \;
echo "moving wheels to dist directory"
find dist_temp -type f -name '*.whl' -exec sh -c 'mv "$(realpath {})" dist/' \;
twine upload --repository pypi dist/*.whl

- name: Setup tmate session for PyPI upload failure
uses: mxschmitt/action-tmate@v3
if: ${{ failure() }}
with:
github-token: ${{ secrets.GITHUB_TOKEN }}

37 changes: 34 additions & 3 deletions .github/workflows/wheels.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Wheels
name: "Wheels"

on:
workflow_dispatch:
Expand Down Expand Up @@ -107,7 +107,7 @@ jobs:
mingw-w64-clang-x86_64-libzip
mingw-w64-clang-x86_64-zlib
mingw-w64-clang-x86_64-libaec

mingw-w64-clang-x86_64-python-pip-tools

- name: Install Linux Dependencies
if: matrix.os == 'ubuntu-latest'
Expand All @@ -123,9 +123,40 @@ jobs:
dpkg -s libboost-all-dev
dpkg -s libhdf5-dev

# Used to host cibuildwheel
- uses: actions/setup-python@v5

- name: Install cibuildwheel
run: python -m pip install cibuildwheel==2.18.1

- name: build wheel on macos-13
if: matrix.os == 'macos-13'
run: |
export PATH="/usr/local/opt/llvm/bin:$PATH"
python -m cibuildwheel --output-dir wheelhouse
env:
CIBW_ARCHS: native

- name: build wheel on macos-14
if: matrix.os == 'macos-14'
run: |
export PATH="/opt/homebrew/opt/llvm/bin:$PATH"
python -m cibuildwheel --output-dir wheelhouse
env:
CIBW_ARCHS: native

- name: build wheel on windows-latest
if: matrix.os == 'windows-latest'
shell: msys2 {0}
run: |
python -m cibuildwheel --output-dir wheelhouse
env:
CIBW_ARCHS: native

- name: build wheel
uses: pypa/[email protected]
if: matrix.os == 'ubuntu-latest'
run: |
python -m cibuildwheel --output-dir wheelhouse
env:
CIBW_ARCHS: native

Expand Down
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,12 @@
/.idea/
/nfsim/
/all_solvers/*
/.venv/
/venv/

.DS_Store
/dist/

tests/__pycache__/

*.whl
34 changes: 2 additions & 32 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ option(OPTION_TARGET_PYTHON_BINDING "build Python bindings" ON)
option(OPTION_TARGET_MESSAGING "Messaging (requires libcurl)" off)
option(OPTION_TARGET_DOCS "Generate Doxygen documentation" off)
option(OPTION_TARGET_FV_SOLVER on)
option(OPTION_TARGET_TESTS "Build tests" off)
option(OPTION_VCELL "Compile Smoldyn for VCell" ON)
option(OPTION_NSV "Compile Smoldyn with NextSubvolume functionality" OFF)
option(OPTION_USE_OPENGL "Build with OpenGL support" OFF)
Expand Down Expand Up @@ -217,7 +218,7 @@ if (OPTION_TARGET_PYTHON_BINDING)
find_package(pybind11 CONFIG REQUIRED)

# Add a library using FindPython's tooling (pybind11 also provides a helper like this)
python_add_library(_core MODULE src/main.cpp src/SolverMain.cpp src/SolverMain.h WITH_SOABI)
python_add_library(_core MODULE src/main.cpp WITH_SOABI)
target_link_libraries(_core PRIVATE vcell pybind11::headers)

# This is passing in the version as a define just as an example
Expand All @@ -226,35 +227,4 @@ if (OPTION_TARGET_PYTHON_BINDING)
# The install directory is the output (wheel) directory
install(TARGETS _core DESTINATION pyvcell_fvsolver)

else(OPTION_TARGET_PYTHON_BINDING)

include(FetchContent)
FetchContent_Declare(
googletest
URL https://github.com/google/googletest/archive/03597a01ee50ed33e9dfd640b249b4be3799d395.zip
)
if (WINDOWS)
# For Windows: Prevent overriding the parent project's compiler/linker settings
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
endif()

FetchContent_MakeAvailable(googletest)
enable_testing()

get_cmake_property(_variableNames VARIABLES)
list (SORT _variableNames)
foreach (_variableName ${_variableNames})
message(STATUS "${_variableName}=${${_variableName}}")
endforeach()

include(CMakePrintHelpers)
cmake_print_variables(OPTION_TARGET_MESSAGING
OPTION_TARGET_DOCS
OPTION_TARGET_FV_SOLVER
OPTION_TARGET_LIBSMOLDYN OPTION_TARGET_VCELL OPTION_TARGET_NSV )
cmake_print_variables(CMAKE_CXX_FLAGS CMAKE_C_FLAGS CMAKE_Fortran_FLAGS)
cmake_print_variables(CMAKE_SYSTEM_NAME WINDOWS WIN32 MINGW APPLE ARCH_64bit ARCH_32bit)
cmake_print_variables(CMAKE_CPP_COMPILER CMAKE_C_COMPILER CMAKE_CXX_COMPILER CMAKE_Fortran_COMPILER)
cmake_print_variables(HAVE_ZLIB)

endif (OPTION_TARGET_PYTHON_BINDING)
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@
![CI](https://github.com/virtualcell/vcell-solvers/actions/workflows/cd.yml/badge.svg)

# vcell-fvsolver
Virtual Cell solvers [virtualcell/vcell-solvers](https://github.com/virtualcell/vcell-solvers) is a collection of numerical simulation codes used in the Virtual Cell framework [virtualcell/vcell](https://github.com/virtualcell/vcell)).
Virtual Cell Finite Volume solver [virtualcell/vcell-fvsolver](https://github.com/virtualcell/vcell-fvsolver)
is a reaction-diffusion-advection PDE solver for computational cell biology.
This solver is used within the Virtual Cell modeling and simulation application [virtualcell/vcell](https://github.com/virtualcell/vcell)
and as a component in the Virtual Cell Python API [virtualcell/pyvcell](https://github.com/virtualcell/pyvcell) (coming soon).


## The Virtual Cell Project
The Virtual Cell is a modeling and simulation framework for computational biology. For details see http://vcell.org and http://github.com/virtualcell.

Expand All @@ -27,4 +29,4 @@ and generates the output files (.log, .zip, .mesh, .meshmetrics, .hdf5). The
.functions file is not used by the solver, but is helpful for interpreting the
results in the context of the original model.

This package is intented to be used by the Virtual Cell Python API, pyvcell (coming soon).
This package is intended to be used by the Virtual Cell Python API [virtualcell/pyvcell](https://github.com/virtualcell/pyvcell) (coming soon).
Loading
Loading