Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
53 changes: 53 additions & 0 deletions .github/scripts/install_openblas_arm64.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Follow OpenBLAS's Windows ARM64 CI recipe, using its portable ARMV8 target:
# https://github.com/OpenMathLib/OpenBLAS/blob/v0.3.33/.github/workflows/windows_arm64.yml
$ErrorActionPreference = 'Stop'
$PSNativeCommandUseErrorActionPreference = $true

$version = '0.3.33'
$archive = Join-Path $env:RUNNER_TEMP 'openblas-source.tar.gz'
$source = Join-Path $env:RUNNER_TEMP "OpenBLAS-$version"
$build = Join-Path $env:RUNNER_TEMP 'openblas-build'
$prefix = Join-Path $env:RUNNER_TEMP 'openblas'
$llvm = Join-Path $env:RUNNER_TEMP 'openblas-llvm'
$installer = Join-Path $env:RUNNER_TEMP 'LLVM-20.1.8-woa64.exe'

Invoke-WebRequest -OutFile $archive -Uri "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/OpenMathLib/OpenBLAS/releases/download/v$version/OpenBLAS-$version.tar.gz"
if ((Get-FileHash $archive -Algorithm SHA256).Hash -ne '6761af1d9f5d353ab4f0b7497be2643313b36c8f31caec0144bfef198e71e6ab') {
throw 'OpenBLAS source checksum mismatch'
}
tar -xf $archive -C $env:RUNNER_TEMP

# Pin the C and Fortran toolchain used by the upstream recipe. Keep it separate
# from the runner's LLVM, which does not necessarily include flang-new.
Invoke-WebRequest -OutFile $installer -Uri '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/llvm/llvm-project/releases/download/llvmorg-20.1.8/LLVM-20.1.8-woa64.exe'
if ((Get-FileHash $installer -Algorithm SHA256).Hash -ne '7c4ac97eb2ae6b960ca5f9caf3ff6124c8d2a18cc07a7840a4d2ea15537bad8e') {
throw 'LLVM installer checksum mismatch'
}
$install = Start-Process -FilePath $installer -ArgumentList '/S', "/D=$llvm" -Wait -PassThru
if ($install.ExitCode -ne 0) { throw "LLVM installation failed: $($install.ExitCode)" }

# Locate Visual Studio rather than depending on its version or edition.
$vswhere = Join-Path ${env:ProgramFiles(x86)} 'Microsoft Visual Studio\Installer\vswhere.exe'
$vs = & $vswhere -latest -products '*' -requires Microsoft.VisualStudio.Component.VC.Tools.ARM64 -property installationPath
if (-not $vs) { throw 'Visual Studio ARM64 tools were not found' }
# Initialize the current PowerShell process without passing paths through cmd.
& (Join-Path $vs 'Common7\Tools\Launch-VsDevShell.ps1') -Arch arm64 -HostArch arm64 -SkipAutomaticLocation
$env:PATH = "$llvm\bin;$env:PATH"

cmake -S $source -B $build -G Ninja `
-DCMAKE_BUILD_TYPE=Release `
-DTARGET=ARMV8 `
-DDYNAMIC_ARCH=OFF `
-DBINARY=64 `
-DCMAKE_C_COMPILER=clang-cl `
-DCMAKE_Fortran_COMPILER=flang-new `
-DBUILD_SHARED_LIBS=ON `
-DCMAKE_SYSTEM_PROCESSOR=arm64 `
-DCMAKE_SYSTEM_NAME=Windows `
"-DCMAKE_INSTALL_PREFIX=$prefix"
cmake --build $build --parallel 4
cmake --install $build

# Meson uses the CMake package; delvewheel bundles the DLL found on PATH.
"CMAKE_PREFIX_PATH=$prefix" | Out-File -Append -Encoding utf8 $env:GITHUB_ENV
"$prefix\bin" | Out-File -Append -Encoding utf8 $env:GITHUB_PATH
48 changes: 32 additions & 16 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -241,29 +241,45 @@ jobs:
arch: auto
- os: windows-latest
arch: auto
- os: windows-11-arm
arch: auto

steps:
- uses: actions/checkout@v7
with:
submodules: true

- name: Set up MSVC for Windows
if: runner.os == 'Windows'
uses: egor-tensin/vs-shell@v2

- name: Install conda on Windows
if: runner.os == 'Windows'
uses: conda-incubator/setup-miniconda@v4
with:
miniconda-version: "latest"
channels: conda-forge, anaconda
- name: Install OpenBLAS on Windows x64
# meson finds OpenBLAS via its CMake config; delvewheel finds the DLL via PATH.
# 0.3.34 is skipped: its DGEMM kernels crash on AMD Zen 4/5 CPUs that
# expose AVX-512 (Fixed in OpenMathLib/OpenBLAS#6013. Bump with the next release.)
if: runner.os == 'Windows' && runner.arch == 'X64'
shell: pwsh
run: |
$version = '0.3.33'
$sha256 = '7ad797ef0c9a5c42e28903bf726eaaaade307dafe187ff0e923d90cd4002780c'
$zip = Join-Path $env:RUNNER_TEMP 'openblas.zip'
$dest = Join-Path $env:RUNNER_TEMP 'openblas'
Invoke-WebRequest -OutFile $zip `
-Uri "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/OpenMathLib/OpenBLAS/releases/download/v$version/OpenBLAS-$version-x64.zip"
if ((Get-FileHash $zip -Algorithm SHA256).Hash -ne $sha256) { throw 'OpenBLAS checksum mismatch' }
Expand-Archive $zip -DestinationPath $dest
$root = $dest
# The x64 (MinGW) CMake config points the linker at the DLL instead of its import library.
# (Fixed in OpenMathLib/OpenBLAS#6091. Can be removed with the next release.)
$cfg = Join-Path $root 'lib\cmake\openblas\OpenBLASConfig.cmake'
if (Test-Path $cfg) {
(Get-Content $cfg) -replace 'bin/libopenblas\.dll', 'lib/libopenblas.lib' | Set-Content $cfg
}
"CMAKE_PREFIX_PATH=$root" | Out-File -Append -Encoding utf8 $env:GITHUB_ENV
"$root\bin" | Out-File -Append -Encoding utf8 $env:GITHUB_PATH

- name: Install openblas from conda on Windows
if: runner.os == 'Windows'
# 0.3.33 pinned: conda-forge's win-64 0.3.34 build crashes inside its
# DGEMM kernels on AMD Zen 4/5 CPUs that expose AVX-512
# (conda-forge/openblas-feedstock#196). Unpin once a fixed build ships.
run: conda install -y "openblas=0.3.33" pkgconfig
- name: Build OpenBLAS for Windows ARM64
# The upstream woa64 DLL targets NEOVERSEN1 and requires LSE atomics.
# Build for ARMV8 so the wheels also work on older Windows ARM64 CPUs.
if: runner.os == 'Windows' && runner.arch == 'ARM64'
shell: pwsh
run: ./.github/scripts/install_openblas_arm64.ps1

- name: Build wheels
uses: pypa/cibuildwheel@v4.2.1
Expand Down
3 changes: 3 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ dependencies = [
[tool.cibuildwheel]
skip = [
"*-win32", # fails on locating Python headers, probably meson.build is misconfigured
# there are no CPython win_arm64 releases before 3.11
"cp39-win_arm64", "cp310-win_arm64",
"*musllinux*aarch64*" # no Scipy wheels for this
]
# Test
Expand All @@ -61,6 +63,7 @@ archs = [

[tool.cibuildwheel.windows]
before-build = "pip install delvewheel"
config-settings = {setup-args = "--vsenv"}
# This will probably become default in newer cibuildwheels versions
repair-wheel-command = "delvewheel repair -w {dest_dir} {wheel}"

Expand Down
Loading