Skip to content

CI: Build and test wheels on Windows on ARM - #31

Merged
bashtage merged 1 commit into
mainfrom
a90-whl2-win-arm64
Nov 4, 2026
Merged

bashtage merged 1 commit into
mainfrom
a90-whl2-win-arm64

Conversation

@bashtage

@bashtage bashtage commented Nov 4, 2026

Copy link
Copy Markdown
Owner

Builds and tests arch wheels on Windows on ARM (ARM64), on GitHub's windows-11-arm runner. bashtage/arch#1003 found that arch builds and passes its whole test suite there, with no BLAS thread limit.

Changes

  • Matrix: adds windows-11-arm for cp313, cp314 and cp315. statsmodels has win_arm64 wheels only from Python 3.13, so wheels for 3.10 to 3.12 couldn't be tested. numpy, SciPy and pandas have wheels for all three Pythons.
  • CIBW_ARCHS_WINDOWS: native: builds AMD64 on windows-latest, as before, and ARM64 on windows-11-arm.
  • Thread limits: these moved from the job's env to a step that sets them on every runner except windows-11-arm. On windows-11-arm, a step instead fails if any limit is set.

Why Windows on ARM can't have a thread limit

In the OpenBLAS of every numpy win_arm64 wheel, from 2.3.0 to the nightly, numpy.linalg.inv and solve crash with an access violation for 23×23 to 31×31 matrices when OpenBLAS starts with one thread (numpy/numpy#29442). arch's unit root tests use matrices of those sizes. OpenBLAS also reads OMP_NUM_THREADS when OPENBLAS_NUM_THREADS isn't set, so OMP_NUM_THREADS=1 alone is enough to cause the crash. With no limit, OpenBLAS uses the runner's 4 cores and every test passes.

The limit for OpenBLAS was misspelled OPENLAS_NUM_THREADS. Fixing it changes nothing in practice: OpenBLAS was already limited to one thread through OMP_NUM_THREADS. On Linux, cibuildwheel runs the tests in a container that doesn't get these variables, so Linux is unaffected either way.

Checked locally

  • actionlint and check-jsonschema (GitHub workflow schema) report no problems.
  • I ran both new steps with Git Bash. The limit step writes the three variables to GITHUB_ENV. The check passes with no limit, and fails when OMP_NUM_THREADS or GOTO_NUM_THREADS is set.
  • The build itself is untested. CI: Test on Windows on ARM arch#1003 built arch with pip wheel . on these runners for Python 3.13, 3.14 and 3.15, and cibuildwheel's build is the first real test of this setup.

🤖 Generated with Claude Code

Add windows-11-arm to the build matrix for Python 3.13 to 3.15, the
versions for which statsmodels has win_arm64 wheels, so that the wheels
can be tested. CIBW_ARCHS_WINDOWS is native, which builds AMD64 on
windows-latest and ARM64 on windows-11-arm.

numpy's OpenBLAS on Windows on ARM crashes in numpy.linalg.inv and solve
of 23x23 to 31x31 matrices when it starts with one thread
(numpy/numpy#29442, bashtage/arch#1003), and it reads OMP_NUM_THREADS
when OPENBLAS_NUM_THREADS is not set. The thread limits are now set in a
step that skips Windows on ARM, where a step checks that none is set.
The limit for OpenBLAS was misspelled OPENLAS_NUM_THREADS; OpenBLAS was
still limited through OMP_NUM_THREADS.
@bashtage
bashtage marked this pull request as ready for review November 4, 2026 23:03
@bashtage
bashtage merged commit dd1a73d into main Nov 4, 2026
27 checks passed
@bashtage
bashtage deleted the a90-whl2-win-arm64 branch November 4, 2026 23:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant