8000 CI: enable free-threaded wheel builds [wheel build] · numpy/numpy@81e089f · GitHub
[go: up one dir, main page]

Skip to content

Commit 81e089f

Browse files
committed
CI: enable free-threaded wheel builds [wheel build]
[skip cirrus] [skip azp] [skip circle]
1 parent 5ac5c15 commit 81e089f

File tree

3 files changed

+199
-0
lines changed

3 files changed

+199
-0
lines changed
Lines changed: 178 additions & 0 deletions
10000
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
# Workflow to build and test wheels for the free-threaded Python build.
2+
#
3+
# This should be merged back into wheels.yml when free-threaded wheel
4+
# builds can be uploaded to pypi along with the rest of numpy's release
5+
# artifacts.
6+
#
7+
# To work on the wheel building infrastructure on a fork, comment out:
8+
#
9+
# if: github.repository == 'numpy/numpy'
10+
#
11+
# in the get_commit_message job. Be sure to include [wheel build] in your commit
12+
# message to trigger the build. All files related to wheel building are located
13+
# at tools/wheels/
14+
name: Free-Threaded Wheel Builder
15+
16+
on:
17+
schedule:
18+
# ┌───────────── minute (0 - 59)
19+
# │ ┌───────────── hour (0 - 23)
20+
# │ │ ┌───────────── day of the month (1 - 31)
21+
# │ │ │ ┌───────────── month (1 - 12 or JAN-DEC)
22+
# │ │ │ │ ┌───────────── day of the week (0 - 6 or SUN-SAT)
23+
# │ │ │ │ │
24+
- cron: "42 2 * * SUN,WED"
25+
pull_request:
26+
branches:
27+
- main
28+
- maintenance/**
29+
# we don't want to upload free-threaded wheels to pypi yet
30+
# so we don't build on tags
31+
workflow_dispatch:
32+
33+
concurrency:
34+
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
35+
cancel-in-progress: true
36+
37+
permissions:
38+
contents: read # to fetch code (actions/checkout)
39+
40+
jobs:
41+
get_commit_message:
42+
name: Get commit message
43+
runs-on: ubuntu-latest
44+
# To enable this job and subsequent jobs on a fork, comment out:
45+
if: github.repository == 'numpy/numpy'
46+
outputs:
47+
message: ${{ steps.commit_message.outputs.message }}
48+
steps:
49+
- name: Checkout numpy
50+
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
51+
# Gets the correct commit message for pull request
52+
with:
53+
ref: ${{ github.event.pull_request.head.sha }}
54+
- name: Get commit message
55+
id: commit_message
56+
run: |
57+
set -xe
58+
COMMIT_MSG=$(git log --no-merges -1 --oneline)
59+
echo "message=$COMMIT_MSG" >> $GITHUB_OUTPUT
60+
echo github.ref ${{ github.ref }}
61+
62+
build_wheels:
63+
name: Build wheel ${{ matrix.python }}-${{ matrix.buildplat[1] }}-${{ matrix.buildplat[2] }}
64+
needs: get_commit_message
65+
if: >-
66+
contains(needs.get_commit_message.outputs.message, '[wheel build]') ||
67+
github.event_name == 'schedule' ||
68+
github.event_name == 'workflow_dispatch'
69+
runs-on: ${{ matrix.buildplat[0] }}
70+
strategy:
71+
# Ensure that a wheel builder finishes even if another fails
72+
fail-fast: false
73+
matrix:
74+
# Github Actions doesn't support pairing matrix values together, let's improvise
75+
# https://github.com/github/feedback/discussions/7835#discussioncomment-1769026
76+
buildplat:
77+
- [ubuntu-20.04, manylinux_x86_64, ""]
78+
- [ubuntu-20.04, musllinux_x86_64, ""]
79+
# TODO: build numpy and set up Windows and MacOS
80+
# cibuildwheel does not yet support Mac for free-threaded python
81+
# windows is supported but numpy doesn't build on the image yet
82+
python: ["cp313t"]
83+
env:
84+
IS_32_BIT: ${{ matrix.buildplat[1] == 'win32' }}
85+
IS_SCHEDULE_DISPATCH: ${{ github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' }}
86+
steps:
87+
- name: Checkout numpy
88+
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
89+
with:
90+
submodules: true
91+
92+
- name: Setup MSVC (32-bit)
93+
if: ${{ matrix.buildplat[1] == 'win32' }}
94+
uses: bus1/cabuild/action/msdevshell@e22aba57d6e74891d059d66501b6b5aed8123c4d # v1
95+
with:
96+
architecture: 'x86'
97+
98+
- name: pkg-config-for-win
99+
run: |
100+
choco install -y --no-progress --stoponfirstfailure --checksum 6004DF17818F5A6DBF19CB335CC92702 pkgconfiglite
101+
$CIBW = "${{ github.workspace }}/.openblas"
102+
# pkgconfig needs a complete path, and not just "./openblas since the
103+
# build is run in a tmp dir (?)
104+
# It seems somewhere in the env passing, `\` is not
105+
# passed through, so convert it to '/'
106+
$CIBW = $CIBW.replace("\","/")
107+
echo "CIBW_ENVIRONMENT_WINDOWS=PKG_CONFIG_PATH=$CIBW" >> $env:GITHUB_ENV
108+
if: runner.os == 'windows'
109+
110+
# Used to push the built wheels
111+
- uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v5.1.0
112+
with:
113+
python-version: "3.x"
114+
115+
- name: Setup macOS
116+
if: matrix.buildplat[0] == 'macos-13' || matrix.buildplat[0] == 'macos-14'
117+
run: |
118+
if [[ ${{ matrix.buildplat[2] }} == 'accelerate' ]]; then
119+
# macosx_arm64 and macosx_x86_64 with accelerate
120+
# only target Sonoma onwards
121+
CIBW="MACOSX_DEPLOYMENT_TARGET=14.0 INSTALL_OPENBLAS=false RUNNER_OS=macOS"
122+
echo "CIBW_ENVIRONMENT_MACOS=$CIBW" >> "$GITHUB_ENV"
123+
124+
# the macos-13 image that's used for building the x86_64 wheel can't test
125+
# a wheel with deployment target >= 14 without further work
126+
echo "CIBW_TEST_SKIP=*-macosx_x86_64" >> "$GITHUB_ENV"
127+
else
128+
# macosx_x86_64 with OpenBLAS
129+
# if INSTALL_OPENBLAS isn't specified then scipy-openblas is automatically installed
130+
CIBW="RUNNER_OS=macOS"
131+
PKG_CONFIG_PATH="$PWD/.openblas"
132+
DYLD="$DYLD_LIBRARY_PATH:/$PWD/.openblas/lib"
133+
echo "CIBW_ENVIRONMENT_MACOS=$CIBW PKG_CONFIG_PATH=$PKG_CONFIG_PATH DYLD_LIBRARY_PATH=$DYLD" >> "$GITHUB_ENV"
134+
fi
135+
136+
- name: Build wheels
137+
uses: pypa/cibuildwheel@ba8be0d98853f5744f24e7f902c8adef7ae2e7f3 # v2.18.1
138+
env:
139+
CIBW_PRERELEASE_PYTHONS: True
140+
CIBW_FREE_THREADED_SUPPORT: True
141+
CIBW_BUILD: ${{ matrix.python }}-${{ matrix.buildplat[1] }}
142+
# TODO: remove along with installing build deps in
143+
# cibw_before_build.sh when a released cython can build numpy
144+
CIBW_BUILD_FRONTEND: "pip; args: --no-build-isolation"
145+
146+
- uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3
147+
with:
148+
name: ${{ matrix.python }}-${{ matrix.buildplat[1] }}-${{ matrix.buildplat[2] }}
149+
path: ./wheelhouse/*.whl
150+
151+
- uses: mamba-org/setup-micromamba@422500192359a097648154e8db4e39bdb6c6eed7
152+
with:
153+
# for installation of anaconda-client, required for upload to
154+
# anaconda.org
155+
# Note that this step is *after* specific pythons have been used to
156+
# build and test the wheel
157+
# for installation of anaconda-client, for upload to anaconda.org
158+
# environment will be activated after creation, and in future bash steps
159+
init-shell: bash
160+
environment-name: upload-env
161+
create-args: >-
162+
anaconda-client
163+
164+
- name: Upload wheels
165+
if: success()
166+
shell: bash -el {0}
167+
# see https://github.com/marketplace/actions/setup-miniconda for why
168+
# `-el {0}` is required.
169+
env:
170+
NUMPY_NIGHTLY_UPLOAD_TOKEN: ${{ secrets.NUMPY_NIGHTLY_UPLOAD_TOKEN }}
171+
run: |
172+
source tools/wheels/upload_wheels.sh
173+
set_upload_vars
174+
# trigger an upload to
175+
# https://anaconda.org/scientific-python-nightly-wheels/numpy
176+
# for cron jobs or "Run workflow" (restricted to main branch).
177+
# The tokens were originally generated at anaconda.org
178+
upload_wheels

tools/wheels/cibw_before_build.sh

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,11 @@ if [[ $RUNNER_OS == "Windows" ]]; then
5252
# delvewheel is the equivalent of delocate/auditwheel for windows.
5353
python -m pip install delvewheel wheel
5454
fi
55+
56+
# TODO: delete along with enabling building isolation by unsetting
57+
# CIBW_BUILD_FRONTEND when numpy is buildable under free-threaded
58+
# python with a released version of cython
59+
FREE_THREADED_BUILD="$(python -c"import sysconfig; print(bool(sysconfig.get_config_var('Py_GIL_DISABLED')))") == "True""
60+
if [[ $FREE_THREADED_BUILD ]]; then
61+
python -m pip install git+https://github.com/cython/cython meson-python ninja
62+
fi

tools/wheels/cibw_test_command.sh

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ PROJECT_DIR="$1"
66

77
python -m pip install threadpoolctl
88
python -c "import numpy; numpy.show_config()"
9+
910
if [[ $RUNNER_OS == "Windows" ]]; then
1011
# GH 20391
1112
PY_DIR=$(python -c "import sys; print(sys.prefix)")
@@ -26,6 +27,18 @@ fi
2627
# Set available memory value to avoid OOM problems on aarch64.
2728
# See gh-22418.
2829
export NPY_AVAILABLE_MEM="4 GB"
30+
31+
FREE_THREADED_BUILD="$(python -c"import sysconfig; print(bool(sysconfig.get_config_var('Py_GIL_DISABLED')))") == "True""
32+
if [[ $FREE_THREADED_BUILD ]]; then
33+
# TODO: delete when numpy is buildable under free-threaded python
34+
# with a released version of cython
35+
python -m pip install git+https://github.com/cython/cython
36+
# TODO: delete when importing numpy no longer enables the GIL
37+
# setting to zero ensures the GIL is disabled while running the
38+
# tests under free-threaded python
39+
export PYTHON_GIL=0
40+
fi
41+
2942
# Run full tests with -n=auto. This makes pytest-xdist distribute tests across
3043
# the available N CPU cores: 2 by default for Linux instances and 4 for macOS arm64
3144
python -c "import sys; import numpy; sys.exit(not numpy.test(label='full', extra_argv=['-n=auto']))"

0 commit comments

Comments
 (0)
0