Repository navigation
torch_c on CPython 3.15t: builds, imports, keeps the GIL (#51 step 1) - #70
Merged
Merged
Conversation
abi3 becomes a default cargo feature; --no-default-features builds a version-pinned _C against a free-threaded interpreter. pyo3 0.29 declares a module GIL-free by default, and the first 3.15t build read sys._is_gil_enabled() == False before any global was audited, so the module now says gil_used = true. tests/api/test_freethreaded.py checks both in a 3.15t subprocess; with the attribute removed it goes red.
Contributor
Gate on CI (issue #24)Full gate: 126 suites = 118 run on at least one CI runner + 8 local-only. The local gate (
Local-only: verified by no CI runner (8)
Suites that verified nothing, or failed, on a runner
Every suite, every runner
A SKIP is unverified on that runner, never passed. UNVERIFIED means the suite ran and every one of its tests skipped by name. |
build.py --abi ft builds _C with --no-default-features against a 3.15t target interpreter and tags the wheel from its sysconfig (ftabi.py). Windows, iOS, Android and wasm refuse by name: no free-threaded target CPython, or a Windows path written against python313. publish-pypi gains a build-ft job (host, linux-x86_64, linux-aarch64) on PBS 3.15.0rc1 freethreaded; collect expects those three wheels by name. test_ftwheel 25 ok; GIL-check and tag mutants go red.
Dry run 37287742911 built both Linux cp315t wheels and then refused them: verify() remapped `expected` for ft but still searched the archive for the target's abi3 member. The host passed only because its target is None. test_verify_finds_the_ft_member_for_a_cross_target was red on the old code.
4 tasks
…am's are (#76) Both were process-wide: torch.no_grad() in one thread stopped grad_fn recording in another, and torch.device('meta') on one thread moved another thread's factories to meta. Wrong with the GIL on, not only on 3.15t. tensor.rs GRAD_ENABLED is a thread_local Cell; the bootstrap's grad flag and _MODE_STACK sit on threading.local. tests/api/test_threadstate.py: 3 tests, green on upstream torch, red on the shim before, green after.
… out from under a live draw (#76) Streams were Box::leak'ed and reclaimed by Box::from_raw in stream_free, sound only while a kernel's guard and the generator's __del__ could not overlap under the GIL. stream() now returns a GenGuard that holds its own Arc clone; stream_free drops the table's reference. The new cargo test frees a locked stream and reuses its memory: SIGSEGV on the old code, green now.
…; test_threadstate sets TORCH_USE_RTLD_GLOBAL CAPTURING was cleared by whichever thread ended its capture first, so a thread still mid-capture stopped recording and its later ops vanished from its trace. It is now an AtomicUsize of open regions (one per thread at most, since capture_begin refuses nesting); the door still pays one relaxed load. test_threadstate.py never ran in the gate before this commit: it died at import torch for want of TORCH_USE_RTLD_GLOBAL, which every other suite that imports torch sets. Now 4 ok in the gate (2010 -> 2014).
… mode (#51, #76) 8 threads behind a Barrier in a 3.15t subprocess that overrides gil_used. Against a build without #76's fixes, grad and mode go red ('another thread's no_grad applied here', 'pop from an empty torch function mode stack'); with them all three are green. The RNG case stays green on the old code too: the use-after-free is proven by the cargo test, not by this hammer. The first version collected errors under the wrapper's name and so could never fail; the nullification above is how that was found. Also git-ignores target-ft/, build.py --abi ft's default cargo dir.
Member
Author
|
This branch now also contains #77 (merged in locally so the 3.15t hammer could exercise its fixes), plus the hammer in
|
Member
Author
|
CI evidence (run 37321276340, d1f265e):
|
Member
Author
|
Paused (user's instruction). The macOS job was re-run on run 37321276340 after an ENOTFOUND artifact upload. Remaining #51 steps: the 9 'unclear' audit items, the full gate on 3.15t (blocked: no upstream torch build for 3.15t to compare against), and Py_mod_gil. |
PBS release 20261013 ships 3.15.0 freethreaded for aarch64-apple-darwin and both linux-gnu triples. The ft rows now fetch from their own PBS_FT_RELEASE so the cp313-abi3 interpreter pin (PBS_RELEASE 20260825, 3.13.15) stays where the published 0.1.0b5 wheels were built. test_ftwheel now requires 3.15.0 final and no 3.15 pre-release anywhere; it was red on the rc1 pin. Locally: _C built against PBS 3.15.0t, tests/api/test_freethreaded.py 5/5 ok (including the PYTHON_GIL=0 hammer).
This was referenced Oct 16, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Refs #51 (step 1 of the order set on the issue; the issue stays open).
Feature added
torch_cbuilds against CPython 3.15.0rc1+freethreaded:cargo build --release --no-default-featureswithPYO3_PYTHONset to the 3.15t interpreter.abi3is now a default cargo feature, so the cp313-abi3 build is unchanged (cargo check --releasepasses).torch.ones(2)+1gives[2., 2.]and_aten_implementedis present. Grade: reaches.Defect fixed
sys._is_gil_enabled() == Falsebefore any global had been audited.#[pymodule(gil_used = true)]keeps the GIL until the audit and its thread tests land. 3.15t now re-enables the GIL and warns.Test added
tests/api/test_freethreaded.py(2 tests,BOTHin the manifest). It skips by name unlessTORCHNATIVE_FT_PYTHONandTORCHNATIVE_FT_STAGEare set. Run live on the host: 2 ok.gil_used = true, andtest_module_keeps_the_gil_until_the_audit_landswent FAIL.Not done (remaining #51 criteria)
publish-pypi.ymlfor the macOS, iOS, Android, Linux and Windows targets.Py_mod_gil.