This is an automated email from the ASF dual-hosted git repository.
tqchen pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tvm-ffi.git
The following commit(s) were added to refs/heads/main by this push:
new 7213f222 [FIX] Link free-threaded Windows torch addon and build Python
3.15 wheels (#845)
7213f222 is described below
commit 7213f222b478ff37aedbfe899c5cd5fe20db7ccb
Author: Yaxing Cai <[email protected]>
AuthorDate: Wed Oct 14 06:57:46 2026 +0800
[FIX] Link free-threaded Windows torch addon and build Python 3.15 wheels
(#845)
## Why
The v0.1.15-rc0 wheel run failed on the new Windows ARM64 leg (#691): on
`cp314t-win_arm64`, `test_build_torch_c_dlpack_extension` and
`test_parallel_build` failed with `LINK : fatal error LNK1104: cannot
open file 'python314.lib'`.
`_build_optional_torch_c_dlpack.py` has two gaps for free-threaded
Python on Windows:
- It searches for `python3.lib` to find Python's `libs` directory. A
free-threaded install only ships `python314t.lib` and `python3t.lib`, so
no `/LIBPATH` is added.
- It compiles without `Py_GIL_DISABLED`. On Windows, `pyconfig.h` does
not define it even for free-threaded Python (the CPython docs say
extensions must define it themselves), so the addon is compiled with the
regular object layout and `pyconfig.h` auto-links `python314.lib`, which
does not exist in that install.
The bug dates back to at least v0.1.13. Windows AMD64 never ran into it
because torch is installed only below Python 3.14 there, so these tests
skip on 3.14t. The ARM64 override from #691 installs a torch nightly on
every version, including 3.14t.
CPython 3.15.0 was released on 2026-10-09, and the wheel matrix stops at
`cp314t`.
## What changed
- On free-threaded Windows Python, define `Py_GIL_DISABLED=1` and look
for the import library the headers request, `python3XX[t].lib`. The same
builder serves both the runtime JIT and the AOT `torch-c-dlpack-ext`
build.
- Build `cp315` and `cp315t` wheels, and bump cibuildwheel in the
publish action from v4.1.0 to v4.2.1, which builds CPython 3.15 by
default. v4.2.1 is the newest release whose pinned build tools all
predate the repository's 14-day uv `exclude-newer` window. v4.3.x pins
packages published in October (`tomli==2.5.0`, `virtualenv==21.14.5`,
…), so its build-tool install fails to resolve. v4.2.1 bundles CPython
3.15.0rc2, which is ABI-compatible with 3.15.0 from rc1 on. The OrcJIT
action keeps its pin.
- Limit the Windows ARM64 torch override to `cp31[2-4]*`. NVIDIA's
nightly index has no cp315 torch yet; PyPI doesn't either, so on 3.15
the torch tests skip on every platform.
## Validation
- Publish matrix on a fork, using a copy of the publish job that only
builds and tests (no upload): all 5 runners passed, 45 wheels
(cp39–cp315t on each), with no test failures on any tested version:
https://github.com/cyx-6/tvm-ffi/actions/runs/38411441467
- `cp314t-win_arm64`: `test_build_torch_c_dlpack_extension` and
`test_parallel_build` pass, compiled with `/DPy_GIL_DISABLED=1` and
linked against `python314t.lib` (`2585 passed, 49 skipped, 4 xfailed`)
- `cp315-win_arm64` and `cp315t-win_arm64`: `2561 passed, 74 skipped, 3
xfailed` and `2562 passed, 73 skipped, 3 xfailed`; the torch tests skip
as intended
- Adds 10 wheels (`cp315` and `cp315t` on each of the 5 runners) and
drops or untests none
- Python lookup checked against the official Windows CPython packages:
free-threaded 3.14 resolves `python314t.lib` with `/DPy_GIL_DISABLED=1`;
regular 3.14 and 3.9 resolve `python314.lib` and `python39.lib` with no
extra flags
- Local source builds on CPython 3.15.0 and 3.15.0t (Linux aarch64):
`2562 passed, 74 skipped, 2 xfailed` and `2563 passed, 73 skipped, 2
xfailed`
- All repository pre-commit hooks on changed files
---
.github/actions/build-wheel-for-publish/action.yml | 2 +-
pyproject.toml | 5 +++--
python/tvm_ffi/utils/_build_optional_torch_c_dlpack.py | 9 ++++++++-
3 files changed, 12 insertions(+), 4 deletions(-)
diff --git a/.github/actions/build-wheel-for-publish/action.yml
b/.github/actions/build-wheel-for-publish/action.yml
index fded3153..04b98cde 100644
--- a/.github/actions/build-wheel-for-publish/action.yml
+++ b/.github/actions/build-wheel-for-publish/action.yml
@@ -85,7 +85,7 @@ runs:
- name: Build wheels
if: ${{ inputs.build_wheels == 'true' }}
- uses: pypa/cibuildwheel@294735312765b09d24a2fbec22660ce817587d55 #
v4.1.0
+ uses: pypa/cibuildwheel@e090b81e30c4d855ea63bf4b6e59204c09a101ae #
v4.2.1
env:
CIBW_ARCHS_MACOS: ${{ inputs.arch }}
CIBW_ARCHS_LINUX: ${{ inputs.arch }}
diff --git a/pyproject.toml b/pyproject.toml
index 4fe77c73..169e4068 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -253,7 +253,7 @@ docstring-code-line-length = 80
build-verbosity = 1
# Per-Python-version wheels (no abi3 / limited API).
-build = ["cp39-*", "cp310-*", "cp311-*", "cp312-*", "cp313-*", "cp314-*",
"cp314t-*"]
+build = ["cp39-*", "cp310-*", "cp311-*", "cp312-*", "cp313-*", "cp314-*",
"cp314t-*", "cp315-*", "cp315t-*"]
skip = ["*musllinux*"]
# cp39-cp311 are covered by the cp312 test run.
test-skip = ["cp39-*", "cp310-*", "cp311-*"]
@@ -273,7 +273,8 @@ archs = ["AMD64", "ARM64"]
repair-wheel-command = "delvewheel repair --ignore-existing -w {dest_dir} -v
{wheel}"
[[tool.cibuildwheel.overrides]]
-select = "*-win_arm64"
+# NVIDIA's nightly index has no cp315 torch yet; widen once it does.
+select = "cp31[2-4]*-win_arm64"
before-test = "uv pip install torch"
[tool.cibuildwheel.overrides.environment]
diff --git a/python/tvm_ffi/utils/_build_optional_torch_c_dlpack.py
b/python/tvm_ffi/utils/_build_optional_torch_c_dlpack.py
index e8466d93..38d3ed0b 100644
--- a/python/tvm_ffi/utils/_build_optional_torch_c_dlpack.py
+++ b/python/tvm_ffi/utils/_build_optional_torch_c_dlpack.py
@@ -865,7 +865,14 @@ def main() -> None: # noqa: PLR0912, PLR0915
# Add Python library linking
if IS_WINDOWS:
- python_lib = f"python{sys.version_info.major}.lib"
+ # pyconfig.h on Windows leaves Py_GIL_DISABLED undefined even for
free-threaded
+ # Python, so define it to compile the free-threaded object layout.
Python's headers
+ # then auto-link python3XXt.lib, the only import library such an
install ships.
+ free_threaded = bool(sysconfig.get_config_var("Py_GIL_DISABLED"))
+ if free_threaded:
+ cflags.append("/DPy_GIL_DISABLED=1")
+ abiflag = "t" if free_threaded else ""
+ python_lib =
f"python{sys.version_info.major}{sys.version_info.minor}{abiflag}.lib"
python_libdir_list = [
sysconfig.get_config_var("LIBDIR"),
str(Path(sys.base_exec_prefix) / "libs"),