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:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
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:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||||
|
|||||||
+19
-5
@@ -119,9 +119,11 @@ cmake.define.FAISS_OPT_LEVEL = "generic"
|
|||||||
|
|
||||||
[tool.cibuildwheel]
|
[tool.cibuildwheel]
|
||||||
# Build all Python versions on Windows (no abi3); cp310 only on Linux/macOS (abi3).
|
# 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-*"
|
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-requires = ["numpy", "pytest", "scipy"]
|
||||||
test-command = "python -m pytest {project}/tests/test_wheel_smoke.py -v"
|
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"
|
select = "*-macosx_x86_64"
|
||||||
environment = {MACOSX_DEPLOYMENT_TARGET = "15.0"}
|
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]
|
[tool.cibuildwheel.windows]
|
||||||
# Install prebuilt OpenBLAS (statically-linked MinGW runtime, no external deps).
|
# Install the native x64 or arm64 OpenBLAS package for the runner.
|
||||||
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\""
|
# 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"
|
repair-wheel-command = "pip install delvewheel && delvewheel repair -w {dest_dir} {wheel} --add-path C:/openblas/bin --ignore-in-wheel"
|
||||||
|
|
||||||
[tool.cibuildwheel.windows.environment]
|
[tool.cibuildwheel.windows.environment]
|
||||||
# BLAS_ROOT tells CMake's FindBLAS (via CMP0074) where to find OpenBLAS.
|
# 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"
|
BLAS_ROOT = "C:/openblas"
|
||||||
LAPACK_ROOT = "C:/openblas"
|
LAPACK_ROOT = "C:/openblas"
|
||||||
PATH = "C:/openblas/bin;$PATH"
|
PATH = "C:/openblas/bin;$PATH"
|
||||||
|
|||||||
Reference in New Issue
Block a user