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
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
From 0c978531a53ae60c17b889db429d9295227c39b7 Mon Sep 17 00:00:00 2001
From: Mugunthan Selvanayagam <mugunthan.selvanayagam@multicorewareinc.com>
Date: Tue, 10 Feb 2026 15:55:59 +0530
Subject: [PATCH] Add patches for building Numba on Windows ARM64

---
.github/workflows/upload_packages.yml | 1 +
.github/workflows/wheel_workflow_matrix.json | 12 ++++++
buildscripts/github/workflow_groups.json | 3 +-
numba/_dispatcher.cpp | 41 +++++++++++++++++++-
numba/core/typing/ctypes_utils.py | 5 ++-
5 files changed, 58 insertions(+), 4 deletions(-)

diff --git a/.github/workflows/upload_packages.yml b/.github/workflows/upload_packages.yml
index fadfcafd6..7393e92a1 100644
--- a/.github/workflows/upload_packages.yml
+++ b/.github/workflows/upload_packages.yml
@@ -113,6 +113,7 @@ jobs:
echo "linux-aarch64: $(find dist -type f -name "*manylinux*aarch64*.whl" | wc -l)"
echo "osx-arm64: $(find dist -type f -name "*macosx*arm64*.whl" | wc -l)"
echo "win-64: $(find dist -type f -name "*win_amd64*.whl" | wc -l)"
+ echo "win-arm64: $(find dist -type f -name "*win_amd64*.whl" | wc -l)"
echo ""
echo "=== Total wheels count ==="
find dist -type f -name "*.whl" | wc -l
diff --git a/.github/workflows/wheel_workflow_matrix.json b/.github/workflows/wheel_workflow_matrix.json
index e3f72b42b..cba00f666 100644
--- a/.github/workflows/wheel_workflow_matrix.json
+++ b/.github/workflows/wheel_workflow_matrix.json
@@ -19,5 +19,17 @@
{ "python-version": "3.13", "numpy_test": "2.2" },
{ "python-version": "3.13", "numpy_test": "2.3" },
{ "python-version": "3.14", "numpy_test": "2.4" }
+ ],
+ "wheel_build_winarm64_matrix": [
+ { "python-version": "3.11", "numpy_build": "2.3.0", "python_tag": "cp311" },
+ { "python-version": "3.12", "numpy_build": "2.3.0", "python_tag": "cp312" },
+ { "python-version": "3.13", "numpy_build": "2.3.0", "python_tag": "cp313" },
+ { "python-version": "3.14", "numpy_build": "2.3.3", "python_tag": "cp314" }
+ ],
+ "wheel_test_winarm64_matrix": [
+ { "python-version": "3.11", "numpy_test": "2.3" },
+ { "python-version": "3.12", "numpy_test": "2.3" },
+ { "python-version": "3.13", "numpy_test": "2.3" },
+ { "python-version": "3.14", "numpy_test": "2.3.3" }
]
}
diff --git a/buildscripts/github/workflow_groups.json b/buildscripts/github/workflow_groups.json
index a56bcacf7..5d6620619 100644
--- a/buildscripts/github/workflow_groups.json
+++ b/buildscripts/github/workflow_groups.json
@@ -10,7 +10,8 @@
"numba_linux-64_wheel_builder.yml",
"numba_linux-aarch64_wheel_builder.yml",
"numba_osx-arm64_wheel_builder.yml",
- "numba_win-64_wheel_builder.yml"
+ "numba_win-64_wheel_builder.yml",
+ "numba_win-arm64_wheel_builder.yml"
]
}
}
diff --git a/numba/_dispatcher.cpp b/numba/_dispatcher.cpp
index bf3c18bfb..3d2a899ab 100644
--- a/numba/_dispatcher.cpp
+++ b/numba/_dispatcher.cpp
@@ -26,12 +26,46 @@
* exception state is preserved correctly).
*
*/
-
#if (PY_MAJOR_VERSION >= 3) && ((PY_MINOR_VERSION == 12) || (PY_MINOR_VERSION == 13) || (PY_MINOR_VERSION == 14))

#ifndef Py_BUILD_CORE
#define Py_BUILD_CORE 1
#endif
+
+// Workaround for Windows ARM64 atomic operations in Python 3.12
+#if defined(_M_ARM64) && defined(_MSC_VER)
+ // Prevent pycore_atomic.h from being included - it has broken definitions for ARM64
+ #ifndef Py_ATOMIC_H
+ #define Py_ATOMIC_H 1
+ #endif
+
+ // Define the atomic types that pycore_interp.h needs
+ typedef struct _Py_atomic_address {
+ uintptr_t _value;
+ } _Py_atomic_address;
+
+ typedef struct _Py_atomic_int {
+ int _value;
+ } _Py_atomic_int;
+
+ // C++ function overloads for atomic operations
+ static inline uintptr_t _Py_atomic_load_relaxed(const _Py_atomic_address *obj) {
+ return obj->_value;
+ }
+
+ static inline int _Py_atomic_load_relaxed(const _Py_atomic_int *obj) {
+ return obj->_value;
+ }
+
+ static inline void _Py_atomic_store_relaxed(_Py_atomic_address *obj, uintptr_t value) {
+ obj->_value = value;
+ }
+
+ static inline void _Py_atomic_store_relaxed(_Py_atomic_int *obj, int value) {
+ obj->_value = value;
+ }
+#endif
+
#include "internal/pycore_frame.h"
// This is a fix suggested in the comments in https://github.com/python/cpython/issues/108216
// specifically https://github.com/python/cpython/issues/108216#issuecomment-1696565797
@@ -46,7 +80,10 @@
*/
#include "dynamic_annotations.h"
#if (PY_MINOR_VERSION == 12)
- #include "internal/pycore_atomic.h"
+ // pycore_atomic.h is already handled above for Windows ARM64
+ #if !(defined(_M_ARM64) && defined(_MSC_VER))
+ #include "internal/pycore_atomic.h"
+ #endif
#endif
#include "internal/pycore_interp.h"
#include "internal/pycore_pyerrors.h"
diff --git a/numba/core/typing/ctypes_utils.py b/numba/core/typing/ctypes_utils.py
index 3df27f9a2..803d032cb 100644
--- a/numba/core/typing/ctypes_utils.py
+++ b/numba/core/typing/ctypes_utils.py
@@ -5,6 +5,9 @@ Support for typing ctypes function pointers.

import ctypes
import sys
+import platform
+
+is_arm = platform.machine().lower() in ('arm64', 'aarch64')

from numba.core import types, config
from numba.core.typing import templates
@@ -137,7 +140,7 @@ def make_function_type(cfnptr):
# platforms, explicit conversion to a int64 should match.
if cret == types.voidptr:
cret = types.uintp
- if sys.platform == 'win32' and not cfnptr._flags_ & ctypes._FUNCFLAG_CDECL:
+ if sys.platform == 'win32' and not is_arm and not cfnptr._flags_ & ctypes._FUNCFLAG_CDECL:
# 'stdcall' calling convention under Windows
cconv = 'x86_stdcallcc'
else:
--
2.52.0.windows.1
35 changes: 35 additions & 0 deletions .github/workflows/numba/wheel_workflow_matrix.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"wheel_build_matrix": [
{ "python-version": "3.10", "numpy_build": "2.0.2", "python_tag": "cp310" },
{ "python-version": "3.11", "numpy_build": "2.0.2", "python_tag": "cp311" },
{ "python-version": "3.12", "numpy_build": "2.0.2", "python_tag": "cp312" },
{ "python-version": "3.13", "numpy_build": "2.1.3", "python_tag": "cp313" },
{ "python-version": "3.14", "numpy_build": "2.3.3", "python_tag": "cp314" }
],
"wheel_test_matrix": [
{ "python-version": "3.10", "numpy_test": "1.23" },
{ "python-version": "3.10", "numpy_test": "1.24" },
{ "python-version": "3.10", "numpy_test": "1.25" },
{ "python-version": "3.11", "numpy_test": "1.26" },
{ "python-version": "3.11", "numpy_test": "2.0" },
{ "python-version": "3.11", "numpy_test": "2.2" },
{ "python-version": "3.12", "numpy_test": "1.26" },
{ "python-version": "3.12", "numpy_test": "2.0" },
{ "python-version": "3.12", "numpy_test": "2.2" },
{ "python-version": "3.13", "numpy_test": "2.2" },
{ "python-version": "3.13", "numpy_test": "2.3" },
{ "python-version": "3.14", "numpy_test": "2.4" }
],
"wheel_build_winarm64_matrix": [
{ "python-version": "3.11", "numpy_build": "2.3.0", "python_tag": "cp311" },
{ "python-version": "3.12", "numpy_build": "2.3.0", "python_tag": "cp312" },
{ "python-version": "3.13", "numpy_build": "2.3.0", "python_tag": "cp313" },
{ "python-version": "3.14", "numpy_build": "2.3.3", "python_tag": "cp314" }
],
"wheel_test_winarm64_matrix": [
{ "python-version": "3.11", "numpy_test": "2.3" },
{ "python-version": "3.12", "numpy_test": "2.3" },
{ "python-version": "3.13", "numpy_test": "2.3" },
{ "python-version": "3.14", "numpy_test": "2.3.3" }
]
}
60 changes: 60 additions & 0 deletions .github/workflows/numba_release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
name: numba release
permissions:
contents: write
on:
workflow_dispatch:
inputs:
run_id:
description: 'Run ID of numba_win-arm64_wheel_builder workflow'
required: true
jobs:
release:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v5

- name: Download wheel artifacts
uses: dawidd6/action-download-artifact@v11
with:
workflow: numba_win-arm64_wheel_builder.yml
run_id: ${{ github.event.inputs.run_id }}
path: artifacts
github_token: ${{ secrets.GITHUB_TOKEN }}

- name: List wheels
run: |
find artifacts -type f -name "*.whl" | sort

- name: Create single GitHub release
run: |
set -euo pipefail
WHEELS=$(find artifacts -type f -name "*.whl" | sort)
if [ -z "$WHEELS" ]; then
echo "No wheels found"
exit 1
fi
FIRST_WHEEL=$(echo "$WHEELS" | head -n 1)
BASENAME=$(basename "$FIRST_WHEEL")
VERSION=$(echo "$BASENAME" | sed -E 's/numba-([0-9]+\.[0-9]+\.[0-9]+).*/\1/')
PLATFORM="win_arm64"
TAG="numba-${VERSION}-${PLATFORM}"
TITLE="numba ${VERSION} for Windows ARM64"
echo "Creating release:"
echo " Tag: $TAG"
echo " Title: $TITLE"
gh release create "$TAG" \
--title "$TITLE" \
--notes "numba Windows ARM64 wheels built from workflow run ${{ github.event.inputs.run_id }}" \
--prerelease \
$WHEELS
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Summary
run: |
echo "## numba Release Created" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "- **Run ID:** ${{ github.event.inputs.run_id }}" >> $GITHUB_STEP_SUMMARY
echo "- **Release:**" >> $GITHUB_STEP_SUMMARY
find artifacts -type f -name "*.whl" | sed 's/^/- /' >> $GITHUB_STEP_SUMMARY
112 changes: 112 additions & 0 deletions .github/workflows/numba_win-arm64_wheel_builder.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
name: numba_win-arm64_wheel_builder
on:
workflow_dispatch:
inputs:
llvmlite_run_id:
description: 'llvmlite workflow run ID (optional - if not provided, will use release)'
required: false
type: string

env:
VALIDATION_PYTHON_VERSION: "3.12"
ARTIFACT_RETENTION_DAYS: 7
LLVMLITE_RELEASE_TAG: llvmlite-0.47.0-win_arm64
LLVMLITE_REPO: MugundanMCW/PyEnv-WoA-State

jobs:
load-matrix:
runs-on: ubuntu-latest
outputs:
build-matrix-json: ${{ steps.load_matrix_json.outputs.build-matrix-json }}
test-matrix-json: ${{ steps.load_matrix_json.outputs.test-matrix-json }}
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- id: load_matrix_json
name: Load Workflow Matrix JSON
run: |
BUILD_MATRIX_JSON=$(jq -c .wheel_build_winarm64_matrix .github/workflows/numba/wheel_workflow_matrix.json)
TEST_MATRIX_JSON=$(jq -c .wheel_test_winarm64_matrix .github/workflows/numba/wheel_workflow_matrix.json)

# Add canonical python versions to both matrices
BUILD_MATRIX_EXTENDED=$(echo "$BUILD_MATRIX_JSON" | jq -c '
map(. + {"python_canonical": (.["python-version"] | split(".") | .[:2] | join("."))})
')

TEST_MATRIX_EXTENDED=$(echo "$TEST_MATRIX_JSON" | jq -c '
map(. + {"python_canonical": (.["python-version"] | split(".") | .[:2] | join("."))})
')

echo "Build Matrix JSON: $BUILD_MATRIX_EXTENDED"
echo "Test Matrix JSON: $TEST_MATRIX_EXTENDED"

echo "build-matrix-json=$BUILD_MATRIX_EXTENDED" >> $GITHUB_OUTPUT
echo "test-matrix-json=$TEST_MATRIX_EXTENDED" >> $GITHUB_OUTPUT
win-arm64-build:
name: win-arm64-build-wheel (py ${{ matrix.python-version }}, np ${{ matrix.numpy_build }})
needs: load-matrix
runs-on: windows-11-arm
defaults:
run:
shell: cmd
strategy:
matrix:
include: ${{ fromJson(needs.load-matrix.outputs.build-matrix-json) }}
fail-fast: false
steps:
- name: Checkout repository
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1

- name: Clone numba repository
run: |
git clone https://github.com/numba/numba.git numba_src
cd numba_src
git apply "%GITHUB_WORKSPACE%\.github\workflows\numba\patches\0001-Add-patches-for-building-Numba-on-Windows-ARM64.patch"

- name: Setup Python
uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
with:
python-version: ${{ matrix.python-version }}
allow-prereleases: true

- name: Download llvmlite wheel from workflow artifact
if: ${{ inputs.llvmlite_run_id != '' }}
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131
with:
name: llvmlite-win-arm64-py${{ matrix.python-version }}
path: llvmlite_wheels
run-id: ${{ inputs.llvmlite_run_id }}
repository: ${{ env.LLVMLITE_REPO }}
github-token: ${{ secrets.GITHUB_TOKEN }}

- name: Download llvmlite wheel from release
if: ${{ inputs.llvmlite_run_id == '' }}
run: |
REM Determine the wheel filename based on Python version
set PYTHON_VERSION=${{ matrix.python_canonical }}
set PYTHON_TAG=cp%PYTHON_VERSION:.=%
set WHEEL_NAME=llvmlite-0.47.0.dev0+39.gbf28f754.dirty-%PYTHON_TAG%-%PYTHON_TAG%-win_arm64.whl

REM Download the wheel from GitHub release
if not exist llvmlite_wheels mkdir llvmlite_wheels
curl -L -o "llvmlite_wheels\%WHEEL_NAME%" "https://github.com/${{ env.LLVMLITE_REPO }}/releases/download/${{ env.LLVMLITE_RELEASE_TAG }}/%WHEEL_NAME%"

echo Downloaded wheel: %WHEEL_NAME%
dir llvmlite_wheels

- name: Install build dependencies
run: |
python -m pip install llvmlite_wheels\*.whl
python -m pip install build numpy==${{ matrix.numpy_build }} setuptools wheel

- name: Build wheel
working-directory: numba_src
run: python -m build --wheel --no-isolation

- name: Upload numba wheel
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
with:
name: numba_win-arm64_wheel_py${{ matrix.python_canonical }}
path: numba_src\dist\*.whl
compression-level: 0
retention-days: ${{ env.ARTIFACT_RETENTION_DAYS }}
if-no-files-found: error