mirror of
https://github.com/facebookresearch/faiss.git
synced 2026-10-11 22:50:00 +00:00
Add Windows ARM64 support to CI (#5544)
Summary: Hi team, I'm from Microsoft and recently I'm working on improving Python ecosystem support for Windows on Arm. So I updates the CI workflows to add support for Windows ARM64 build and release. Could you please help to review? Thanks. **Windows ARM64 support and OpenBLAS installation improvements:** * Added a new PowerShell script `install-openblas.ps1` that automatically detects the runner architecture (x64 or ARM64), downloads the appropriate OpenBLAS binary, verifies its hash, and installs it to `C:\openblas`. This ensures consistent and secure OpenBLAS setup on all Windows runners. * Updated the build matrix in `.github/workflows/build-pip.yml` to include `windows-11-arm`, enabling CI builds and tests on Windows ARM64 runners. * Refactored the Windows `before-all` build step in `pyproject.toml` to use the new PowerShell script, replacing the previous hardcoded x64-only download command. This allows seamless support for both x64 and ARM64 architectures. Pull Request resolved: https://github.com/facebookresearch/faiss/pull/5544 Reviewed By: mnorris11 Differential Revision: D117818430 Pulled By: trang-nm-nguyen fbshipit-source-id: dac342878d063828437952e1b19f76e6699e1b6b
This commit is contained in:
committed by
meta-codesync[bot]
parent
02ea14372c
commit
3a716ead1a
@@ -0,0 +1,112 @@
|
||||
# Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
#
|
||||
# This source code is licensed under the MIT license found in the
|
||||
# LICENSE file in the root directory of this source tree.
|
||||
|
||||
param(
|
||||
[string]$InstallPath = "C:\openblas"
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
# Windows PowerShell 5.1 redraws the progress bar on every read block, which
|
||||
# costs an order of magnitude of wall-clock on a download this size.
|
||||
$ProgressPreference = "SilentlyContinue"
|
||||
Set-StrictMode -Version Latest
|
||||
|
||||
# Bumping OpenBLAS means changing $openBlasVersion and every Hash below.
|
||||
# Regenerate a hash with: Get-FileHash -Algorithm SHA256 <downloaded zip>
|
||||
$openBlasVersion = "0.3.30"
|
||||
$packages = @{
|
||||
arm64 = @{
|
||||
Asset = "woa64-dll"
|
||||
Hash = "5BBD8C6CA5A4C415FF58D5E18378B35BC1E81F46E6C385753EFF367FF7474819"
|
||||
Subdirectory = "OpenBLAS"
|
||||
}
|
||||
x64 = @{
|
||||
Asset = "x64"
|
||||
Hash = "8B04387766EFC05C627E26D24797EC0D4ED4C105EC14FA7400AA84A02DB22B66"
|
||||
Subdirectory = ""
|
||||
}
|
||||
}
|
||||
|
||||
$nativeArchitectures = @(
|
||||
$env:PROCESSOR_ARCHITECTURE
|
||||
$env:PROCESSOR_ARCHITEW6432
|
||||
)
|
||||
|
||||
if ($nativeArchitectures -contains "ARM64") {
|
||||
$architecture = "arm64"
|
||||
} elseif ($nativeArchitectures -contains "AMD64") {
|
||||
$architecture = "x64"
|
||||
} else {
|
||||
throw "Unsupported Windows architecture: $($nativeArchitectures -join ', ')"
|
||||
}
|
||||
|
||||
$package = $packages[$architecture]
|
||||
$archiveUrl = "https://github.com/OpenMathLib/OpenBLAS/releases/download/v$openBlasVersion/OpenBLAS-$openBlasVersion-$($package.Asset).zip"
|
||||
$expectedHash = $package.Hash
|
||||
$archiveSubdirectory = $package.Subdirectory
|
||||
|
||||
$workingPath = Join-Path ([System.IO.Path]::GetTempPath()) "faiss-openblas-$architecture-$PID"
|
||||
$archivePath = Join-Path $workingPath "openblas.zip"
|
||||
$extractPath = Join-Path $workingPath "extract"
|
||||
|
||||
New-Item -ItemType Directory -Path $workingPath | Out-Null
|
||||
|
||||
try {
|
||||
# A blip here aborts before-all, losing every interpreter's wheel in this
|
||||
# job. Retrying is safe: the hash check below rejects a partial download.
|
||||
# -UseBasicParsing keeps PS 5.1 off the Internet Explorer parsing engine,
|
||||
# which is absent on freshly provisioned images.
|
||||
for ($attempt = 1; $attempt -le 3; $attempt++) {
|
||||
try {
|
||||
Invoke-WebRequest -Uri $archiveUrl -OutFile $archivePath -UseBasicParsing
|
||||
break
|
||||
} catch {
|
||||
if ($attempt -eq 3) {
|
||||
throw
|
||||
}
|
||||
Start-Sleep -Seconds (5 * $attempt)
|
||||
}
|
||||
}
|
||||
|
||||
$archiveStream = [System.IO.File]::OpenRead($archivePath)
|
||||
try {
|
||||
$hasher = [System.Security.Cryptography.SHA256]::Create()
|
||||
try {
|
||||
$actualHash = [System.BitConverter]::ToString(
|
||||
$hasher.ComputeHash($archiveStream)
|
||||
).Replace("-", "")
|
||||
} finally {
|
||||
$hasher.Dispose()
|
||||
}
|
||||
} finally {
|
||||
$archiveStream.Dispose()
|
||||
}
|
||||
|
||||
if ($actualHash -ne $expectedHash) {
|
||||
throw "OpenBLAS archive hash mismatch: expected $expectedHash, got $actualHash"
|
||||
}
|
||||
|
||||
Expand-Archive -LiteralPath $archivePath -DestinationPath $extractPath
|
||||
$sourcePath = if ($archiveSubdirectory) {
|
||||
Join-Path $extractPath $archiveSubdirectory
|
||||
} else {
|
||||
$extractPath
|
||||
}
|
||||
|
||||
foreach ($subdirectory in @("bin", "include", "lib")) {
|
||||
if (-not (Test-Path -LiteralPath (Join-Path $sourcePath $subdirectory))) {
|
||||
throw "OpenBLAS archive is missing the '$subdirectory' directory"
|
||||
}
|
||||
}
|
||||
|
||||
if (Test-Path -LiteralPath $InstallPath) {
|
||||
Remove-Item -LiteralPath $InstallPath -Recurse -Force
|
||||
}
|
||||
Move-Item -LiteralPath $sourcePath -Destination $InstallPath
|
||||
} finally {
|
||||
if (Test-Path -LiteralPath $workingPath) {
|
||||
Remove-Item -LiteralPath $workingPath -Recurse -Force
|
||||
}
|
||||
}
|
||||
@@ -39,7 +39,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-14, macos-15-intel, windows-2022, 2-core-ubuntu-arm]
|
||||
os: [ubuntu-latest, macos-14, macos-15-intel, windows-2022, windows-11-arm, 2-core-ubuntu-arm]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
|
||||
+19
-5
@@ -119,9 +119,11 @@ cmake.define.FAISS_OPT_LEVEL = "generic"
|
||||
|
||||
[tool.cibuildwheel]
|
||||
# Build all Python versions on Windows (no abi3); cp310 only on Linux/macOS (abi3).
|
||||
# Skip 32-bit and free-threaded builds. musllinux is built (see override below).
|
||||
# Skip Windows arm64 for Python 3.10 because Python 3.10 is not available as a
|
||||
# supported Windows arm64 target. Also skip 32-bit and free-threaded builds.
|
||||
# musllinux is built below.
|
||||
build = "cp310-* cp311-* cp312-* cp313-* cp314-*"
|
||||
skip = "*-win32 *-manylinux_i686 cp3*t-*"
|
||||
skip = "cp310-win_arm64 *-win32 *-manylinux_i686 cp3*t-*"
|
||||
test-requires = ["numpy", "pytest", "scipy"]
|
||||
test-command = "python -m pytest {project}/tests/test_wheel_smoke.py -v"
|
||||
|
||||
@@ -167,14 +169,26 @@ environment = {MACOSX_DEPLOYMENT_TARGET = "14.0"}
|
||||
select = "*-macosx_x86_64"
|
||||
environment = {MACOSX_DEPLOYMENT_TARGET = "15.0"}
|
||||
|
||||
# Windows arm64: drop scipy for the same reason as musllinux above — the smoke
|
||||
# test does not import it, and a missing win_arm64 scipy wheel would force a
|
||||
# failing sdist build (needs a Fortran toolchain and a BLAS on the runner).
|
||||
[[tool.cibuildwheel.overrides]]
|
||||
select = "*-win_arm64"
|
||||
test-requires = ["numpy", "pytest"]
|
||||
|
||||
[tool.cibuildwheel.windows]
|
||||
# Install prebuilt OpenBLAS (statically-linked MinGW runtime, no external deps).
|
||||
before-all = "powershell -Command \"Invoke-WebRequest -Uri 'https://github.com/OpenMathLib/OpenBLAS/releases/download/v0.3.30/OpenBLAS-0.3.30-x64.zip' -OutFile openblas.zip; Expand-Archive openblas.zip -DestinationPath C:/openblas -Force\""
|
||||
# Install the native x64 or arm64 OpenBLAS package for the runner.
|
||||
# delvewheel only has to vendor the OpenBLAS DLL itself, because the x64 package
|
||||
# links the MinGW runtime statically. Re-check that property when bumping the
|
||||
# OpenBLAS version or adding an architecture: `delvewheel show` on a repaired
|
||||
# wheel lists what was vendored, and the PATH below hides a missed DLL from the
|
||||
# smoke test, so a wheel broken this way still passes CI.
|
||||
before-all = 'powershell -NoProfile -ExecutionPolicy Bypass -File "{package}\.github\scripts\install-openblas.ps1"'
|
||||
repair-wheel-command = "pip install delvewheel && delvewheel repair -w {dest_dir} {wheel} --add-path C:/openblas/bin --ignore-in-wheel"
|
||||
|
||||
[tool.cibuildwheel.windows.environment]
|
||||
# BLAS_ROOT tells CMake's FindBLAS (via CMP0074) where to find OpenBLAS.
|
||||
# PATH includes the bin/ dir so delvewheel and tests can find libopenblas.dll.
|
||||
# PATH includes the bin/ dir so delvewheel and tests can find the OpenBLAS DLL.
|
||||
BLAS_ROOT = "C:/openblas"
|
||||
LAPACK_ROOT = "C:/openblas"
|
||||
PATH = "C:/openblas/bin;$PATH"
|
||||
|
||||
Reference in New Issue
Block a user