Skip to content

Commit

Permalink
Binary wheels on pip, build with github actions; v1.5.5
Browse files Browse the repository at this point in the history
  • Loading branch information
cmbant committed Jun 10, 2024
1 parent 5c3bdd7 commit 6c73391
Show file tree
Hide file tree
Showing 12 changed files with 206 additions and 33 deletions.
155 changes: 155 additions & 0 deletions .github/workflows/build_wheels.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
name: Wheels

on: [ push, pull_request ]

jobs:
build_wheels:
name: Build wheels on ${{ matrix.os }}
if: ${{ startsWith(github.ref, 'refs/tags/') || contains(github.event.head_commit.message, '[pypi]') }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ macos-11, macos-12, macos-13, flyci-macos-large-latest-m2, macos-14, ubuntu-latest, windows-latest ]

steps:
- uses: awvwgk/setup-fortran@main
if: matrix.os == 'windows-latest'
id: setup-fortran
with:
compiler: gcc
version: 11

- run: ln -s $(which gfortran-11) /usr/local/bin/gfortran
if: matrix.os != 'windows-latest'

- run: gfortran --version

- uses: actions/checkout@v4
with:
submodules: recursive

- uses: actions/setup-python@v5

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

- name: Build macos-13 wheels
if: matrix.os == 'macos-13' || matrix.os == 'macos-13-xlarge' || matrix.os == 'flyci-macos-large-latest-m2'
env:
MACOSX_DEPLOYMENT_TARGET: 13
CIBW_BUILD: cp311-*
CIBW_SKIP: pp*
CIBW_BUILD_VERBOSITY: 1
run: python -m cibuildwheel --output-dir wheelhouse

- name: Build macos-12 wheels
if: matrix.os == 'macos-12'
env:
MACOSX_DEPLOYMENT_TARGET: 12
CIBW_BUILD: cp311-*
CIBW_SKIP: pp*
CIBW_BUILD_VERBOSITY: 1
run: python -m cibuildwheel --output-dir wheelhouse

- name: Build macos-11 wheels
if: matrix.os == 'macos-11'
env:
# all cp3xx, since old macs seem to only use osx 11+ builds if this is set not "none"
# see consistency with get_tag() in setup.py
MACOSX_DEPLOYMENT_TARGET: 11
CIBW_SKIP: pp*
CIBW_BUILD_VERBOSITY: 1
run: python -m cibuildwheel --output-dir wheelhouse

- name: Build wheels
if: matrix.os == 'macos-14' || matrix.os == 'ubuntu-latest' || matrix.os == 'windows-latest'
env:
MACOSX_DEPLOYMENT_TARGET: 14
CIBW_BUILD: cp311-*
CIBW_SKIP: pp* *-win32 *-manylinux_i686 *musllinux*
CIBW_BUILD_VERBOSITY: 1
run: python -m cibuildwheel --output-dir wheelhouse

- uses: actions/upload-artifact@v4
with:
name: wheels-${{ matrix.os }}
path: |
wheelhouse/*.whl
build-sdist-and-upload:
runs-on: ubuntu-latest
needs: [ 'build_wheels' ]
environment: wheels
if: github.repository_owner == 'cmbant'
permissions:
id-token: write

steps:
- uses: actions/checkout@v4
with:
submodules: recursive

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.10"
cache: pip
cache-dependency-path: "setup.py"

- name: Install dependencies
run: |
python -m pip install -U pip
python -m pip install -U build twine
- name: Download wheels from build artifacts
uses: actions/download-artifact@v4
with:
pattern: wheels-*
merge-multiple: true
path: dist-wheels/

- name: Build package
run: |
python -m build --sdist
twine check --strict dist/*
twine check --strict dist-wheels/*
- name: Publish wheels to PyPI Test
if: ${{ !startsWith(github.ref, 'refs/tags/') }}
uses: pypa/gh-action-pypi-publish@release/v1
with:
repository-url: https://test.pypi.org/legacy/
packages-dir: dist-wheels/

- name: Publish sdist to PyPI Test
if: ${{ !startsWith(github.ref, 'refs/tags/') }}
uses: pypa/gh-action-pypi-publish@release/v1
with:
repository-url: https://test.pypi.org/legacy/

- name: Publish wheels to PyPI
if: ${{ startsWith(github.ref, 'refs/tags/') }}
uses: pypa/gh-action-pypi-publish@release/v1
with:
packages-dir: dist-wheels/

- name: Publish sdist to PyPI
if: ${{ startsWith(github.ref, 'refs/tags/') }}
uses: pypa/gh-action-pypi-publish@release/v1

test_wheels:
name: Test wheels on ${{ matrix.os }}
if: contains(github.event.head_commit.message, '[testpypi]')
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ macos-11, macos-12, macos-13, flyci-macos-large-latest-m2, macos-14, ubuntu-latest, windows-latest ]

steps:
- uses: actions/setup-python@v5

- name: install
run: python -m pip install -i https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple/ camb

- name: test
run: python -m unittest camb.tests.camb_test
13 changes: 0 additions & 13 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -88,16 +88,3 @@ script:
after_failure:
- test $TRAVIS_PULL_REQUEST == "false" && test $PYPI_DIST == "true" && test $TRAVIS_REPO_SLUG == "cmbant/CAMB" && [ -d fortran/testfiles ] && bash fortran/tests/upload_tests.sh

before_deploy:
- pushd fortran; make clean delete; popd

deploy:
- provider: pypi
distributions: sdist
username: "__token__"
password: $PYPI_PASSWORD
on:
branch: master
repo: cmbant/CAMB
tags: true
condition: $PYPI_DIST = true
6 changes: 3 additions & 3 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ Then install using::

pip install -e ./CAMB [--user]

You will need gfortran 6 or higher installed to compile. Binary files for Windows are also provided, so these are used instead if no
gfortran installation is found on Windows machines. If you have gfortran installed, "python setup.py make"
(and other standard setup commands) will build the Fortran library on all systems (including Windows without directly using a Makefile).
You will need gfortran 6 or higher installed to compile (usually included with gcc by default).
If you have gfortran installed, "python setup.py make" (and other standard setup commands) will build the Fortran
library on all systems (including Windows without directly using a Makefile).

The python wrapper provides a module called "camb" documented in the Python `CAMB documentation <https://camb.readthedocs.io/en/latest/>`_.

Expand Down
2 changes: 1 addition & 1 deletion camb/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
__author__ = "Antony Lewis"
__contact__ = "antony at cosmologist dot info"
__url__ = "https://camb.readthedocs.io"
__version__ = "1.5.4"
__version__ = "1.5.5"

from . import baseconfig

Expand Down
Binary file removed camb/cambdll.dll
Binary file not shown.
2 changes: 1 addition & 1 deletion camb/sources.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ def set_table(self, z, W, bias_z=None, k_bias=None, bias_kz=None):
:param z: array of redshift values (monotonically increasing)
:param W: array of window function values. It must be well enough sampled to smoothly cubic-spline interpolate
:param bias_z: optional array of bias values at each z for scale-independent bias
:param k_bias: optional array of k values for bias
:param k_bias: optional array of k values for bias (Mpc^-1)
:param bias_kz: optional 2D contiguous array for space-dependent bias(k, z).
Must ensure range of k is large enough to cover required values.
Expand Down
2 changes: 1 addition & 1 deletion camb/tests/camb_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from camb import model, correlations, bbn, dark_energy, initialpower
from camb.baseconfig import CAMBParamRangeError, CAMBValueError

fast = 'ci fast' in os.getenv("TRAVIS_COMMIT_MESSAGE", "")
fast = 'ci fast' in os.getenv("TRAVIS_COMMIT_MESSAGE", "") or os.getenv("GITHUB_ACTIONS")


class CambTest(unittest.TestCase):
Expand Down
2 changes: 1 addition & 1 deletion docs/source/fortran_compilers.rst
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ This includes in Jupyter notebooks; just re-start the kernel or use::
import IPython
IPython.Application.instance().kernel.do_shutdown(True)

If you want to automamatically rebuild the library from Jupyter you can do something like this::
If you want to automatically rebuild the library from Jupyter you can do something like this::

import subprocess
import sys
Expand Down
8 changes: 4 additions & 4 deletions docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,17 @@ If you want to work on the code from `GitHub <https://github.com/cmbant/camb>`_,
pip install -e ./CAMB [--user]

You will need ifort or gfortran 6 or higher installed (and on your path) to compile; see :ref:`fortran-compilers` for
compiler installation details if needed. A compiled library for Windows is also provided, and is used if no
gfortran installation is found on Windows machines. If you have gfortran installed, "python setup.py make" will build
compiler installation details if needed. If you have gfortran installed, "python setup.py make" will build
the Fortran library on all systems (including Windows without directly using a Makefile), and can be used to update
a source installation after changes or pulling an updated version.

The standard pip installation includes binary pre-compiled code, so no need for a Fortran compiler
(unless you want to use custom sources/symbolic compilation features).
Anaconda users can also install from conda-forge, best making a new clean environment using::

conda create -n camb -c conda-forge python=3.9 camb
conda create -n camb -c conda-forge python=3.11 camb
activate camb

with no need for a Fortran compiler (unless you want to use custom sources/symbolic compilation features).
Check that conda installs the latest version, if not try installing
in a new clean conda environment as above.

Expand Down
2 changes: 1 addition & 1 deletion fortran/config.f90
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module config
use constants, only: const_twopi
implicit none

character(LEN=*), parameter :: version = '1.5.4'
character(LEN=*), parameter :: version = '1.5.5'

integer :: FeedbackLevel = 0 !if >0 print out useful information about the model

Expand Down
7 changes: 3 additions & 4 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,18 @@ authors = [
{ name = "Antony Lewis" },
]
description = "Code for Anisotropies in the Microwave Background"
keywords= ['cosmology', 'CAMB', 'CMB']
keywords = ['cosmology', 'CAMB', 'CMB']
readme = "docs/README_pypi.rst"
license = { file = "LICENCE.txt" }
dynamic = ["version"]
requires-python = ">=3.6.0"
requires-python = ">=3.7.0"
classifiers = [
"Development Status :: 5 - Production/Stable",
"Operating System :: OS Independent",
"Environment :: Console",
"Intended Audience :: Science/Research",
"Topic :: Scientific/Engineering :: Astronomy",
"License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)",
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
Expand All @@ -46,4 +45,4 @@ Tracker = "https://github.com/cmbant/camb/issues"
Licensing = "https://github.com/cmbant/camb/blob/master/LICENCE.txt"

[tool.setuptools.dynamic]
version = {attr = "camb.__version__"}
version = { attr = "camb.__version__" }
40 changes: 36 additions & 4 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@
import os
import shutil
from typing import Any
from setuptools import setup
from setuptools import setup, Command, Extension
from setuptools.command.build_ext import build_ext
from setuptools.command.build_py import build_py
from setuptools.command.develop import develop
from setuptools import Command
from setuptools.command.install import install
from wheel.bdist_wheel import bdist_wheel as _bdist_wheel

file_dir = os.path.abspath(os.path.dirname(__file__))
os.chdir(file_dir)
Expand All @@ -19,6 +21,7 @@
else:
DLLNAME = 'camblib.so'


def get_forutils():
fpath = os.getenv('FORUTILSPATH')

Expand Down Expand Up @@ -177,7 +180,7 @@ def make_library(cluster=False):
get_forutils()
print("Compiling source...")
subprocess.call("make python PYCAMB_OUTPUT_DIR=%s/camb/ CLUSTER_SAFE=%d" %
(pycamb_path, int(cluster)), shell=True)
(pycamb_path, int(cluster if not os.getenv("GITHUB_ACTIONS") else 1)), shell=True)
subprocess.call("chmod 755 %s" % lib_file, shell=True)

if not os.path.isfile(os.path.join(pycamb_path, 'camb', DLLNAME)):
Expand Down Expand Up @@ -246,12 +249,41 @@ def run(self):
subprocess.call("make clean", shell=True, cwd=os.path.join(file_dir, 'fortran'))


class BDistWheelNonPure(_bdist_wheel):
def finalize_options(self):
super().finalize_options()
self.root_is_pure = False

def get_tag(self):
_, _, plat = super().get_tag()
if "osx_11" in plat:
return _, _, plat
return "py3", "none", plat


class InstallPlatlib(install):
def finalize_options(self):
super().finalize_options()
if self.distribution.has_ext_modules():
self.install_lib = self.install_platlib


class BuildExtCommand(build_ext):
"""Ensure built extensions are added to the correct path in the wheel."""

def run(self):
pass


if __name__ == "__main__":
setup(name=os.getenv('CAMB_PACKAGE_NAME', 'camb'),
zip_safe=False,
cmdclass={'build_py': SharedLibrary, 'build_cluster': SharedLibraryCluster,
'make': MakeLibrary, 'make_cluster': MakeLibraryCluster, 'clean': CleanLibrary,
'develop': DevelopLibrary, 'develop_cluster': DevelopLibraryCluster},
'develop': DevelopLibrary, 'develop_cluster': DevelopLibraryCluster,
'bdist_wheel': BDistWheelNonPure, 'install': InstallPlatlib,
"build_ext": BuildExtCommand},
ext_modules=[Extension("camb.camblib", [])],
packages=['camb', 'camb.tests'],
platforms="any",
package_data={'camb': [DLLNAME, 'HighLExtrapTemplate_lenspotentialCls.dat',
Expand Down

0 comments on commit 6c73391

Please sign in to comment.