Skip to content

Re-enable building under a free-threaded Python interpreter#4537

Merged
vkuzo merged 2 commits into
pytorch:mainfrom
nascheme:free-threaded-api-build
Jul 10, 2026
Merged

Re-enable building under a free-threaded Python interpreter#4537
vkuzo merged 2 commits into
pytorch:mainfrom
nascheme:free-threaded-api-build

Conversation

@nascheme

Copy link
Copy Markdown
Contributor

This PR re-applies the changes from #4428.

Free-threaded interpreters do not support the CPython Limited C API, and hence use of the limited API has to be disabled. With this one change, torchao builds fine.

The is_freethreaded function is in widespread use, and documented as the canonical way of doing this check here:
https://py-free-threading.github.io/running-gil-disabled/#check-if-using-a-free-threaded-build

PR #4428 (commit f43befe) was inadvertently reverted by #4446 ("Back out D105996100 — breaks fbpkg build light_cli"). That back-out was meant to revert only the multi-ISA work in #4159 (D105996100), but instead of computing a reverse diff it restored a whole-file snapshot of setup.py that predated both #4159 and #4428, silently clobbering the free-threading support.

Re-applied on top of the current add_options_for_x86 base; the only adaptation from the original is the placement of is_freethreaded() (both functions are kept).

(cherry picked from commit f43befe)

Free-threaded interpreters do not support the CPython Limited C API,
and hence use of the limited API has to be disabled. With this
one change, `torchao` builds fine.

The `is_freethreaded` function is in widespread use, and documented
as the canonical way of doing this check here:
https://py-free-threading.github.io/running-gil-disabled/#check-if-using-a-free-threaded-build

This re-applies pytorch#4428 (commit f43befe), which was inadvertently
reverted by pytorch#4446 ("Back out D105996100 — breaks `fbpkg build
light_cli`"). That back-out was meant to revert only the multi-ISA
work in pytorch#4159 (D105996100), but instead of computing a reverse diff
it restored a whole-file snapshot of setup.py that predated both
pytorch#4159 and pytorch#4428, silently clobbering the free-threading support.

Re-applied on top of the current `add_options_for_x86` base; the only
adaptation from the original is the placement of `is_freethreaded()`
(both functions are kept).

(cherry picked from commit f43befe)

Assisted-by: Claude
@pytorch-bot

pytorch-bot Bot commented Jun 26, 2026

Copy link
Copy Markdown

🔗 Helpful Links

🧪 See artifacts and rendered test results at hud.pytorch.org/pr/pytorch/ao/4537

Note: Links to docs will display an error until the docs builds have been completed.

❌ 1 Awaiting Approval, 1 New Failure

As of commit 796003f with merge base 9b3684a (image):

AWAITING APPROVAL - The following workflow needs approval before CI can run:

NEW FAILURE - The following job has failed:

This comment was automatically generated by Dr. CI and updates every 15 minutes.

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Jun 26, 2026
@vkuzo

vkuzo commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

@claude review, why was the original PR reverted?

@claude

claude Bot commented Jul 6, 2026

Copy link
Copy Markdown

Claude finished @vkuzo's task in 1m 37s —— View job


Review + answer

Why was the original PR reverted?

It wasn't reverted on purpose — it was collateral damage from a whole-file revert, per the PR description and the commit graph:

  1. Enable building under a free-threaded Python interpreter #4428 (commit f43befe6b) originally added free-threading support to setup.py.
  2. [X86] multi-ISA portable kernel compilation and runtime dispatch #4159 (D105996100) added unrelated multi-ISA (x86) work, also touching setup.py.
  3. Back out D105996100 — breaks fbpkg build light_cli (S668656) #4446 ("Back out D105996100 — breaks fbpkg build light_cli") was meant to revert only [X86] multi-ISA portable kernel compilation and runtime dispatch #4159. But instead of applying a reverse diff, it restored a whole-file snapshot of setup.py that predated both [X86] multi-ISA portable kernel compilation and runtime dispatch #4159 and Enable building under a free-threaded Python interpreter #4428. That snapshot silently clobbered the free-threading changes as a side effect.

So the free-threading support was never intentionally rejected — it was overwritten by a coarse-grained revert that reset the entire file. This PR cherry-picks f43befe6b back on top of the current add_options_for_x86 base. (I couldn't confirm the internal D-diff chain from this shallow checkout, but the explanation is consistent with the setup.py history and the referenced PR/commit numbers.)

Review of the change

The change is small, correct, and internally consistent. It funnels every use of Py_LIMITED_API through the single is_freethreaded() gate, since free-threaded CPython does not support the Limited C API:

  • setup.py:500is_freethreaded() uses the documented canonical check (sysconfig.get_config_var("Py_GIL_DISABLED")). 👍
  • setup.py:542-544maybe_cpython_limited_api holds the -DPy_LIMITED_API=... flag only when not free-threaded, and is reused consistently for the torchao._C (:548), mxfp8 (:792), and cutlass compile args.
  • setup.py:755, :833py_limited_api=not is_freethreaded() on the extension objects.
  • setup.py:914 — the bdist_wheel py_limited_api option is dropped on free-threaded builds so the wheel isn't tagged cp310 (abi3).

All the py_limited_api extension flags and the -DPy_LIMITED_API compile flags now flip together, which is what you want — a wheel tagged abi3 while the C code isn't actually built against the Limited API would be a latent ABI mismatch, and this avoids that.

Minor observations (non-blocking):

  • Pre-existing inconsistency (not introduced here): the mxfp8 CUDAExtension (setup.py:778) adds maybe_cpython_limited_api to its cxx flags but never sets py_limited_api= on the extension itself, unlike torchao._C and _C_cutlass_90a. This asymmetry predates the PR and is faithfully preserved, so it's out of scope — just flagging it.
  • is_freethreaded() placement: defined between add_options_for_x86 and get_extensions. Fine; the PR notes this is the only adaptation from the original cherry-pick.

Verdict: LGTM. The revert was accidental (whole-file snapshot in #4446), and re-applying it here is the right fix. I couldn't run the build under a free-threaded interpreter in this environment to empirically confirm, but the logic is sound and matches the documented approach.
· free-threaded-api-build

@vkuzo

vkuzo commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

lgtm! and sorry for long delay, I was OOO and now back.

Could you please fix ruff, by running ruff format && ruff check . --fix from root? then should be good to go

@nascheme

nascheme commented Jul 6, 2026

Copy link
Copy Markdown
Contributor Author

Reformatted with ruff, check passes without errors.

@vkuzo vkuzo added the module: core changes affecting multiple modules, e.g. base config/tensor, observers, quant ops label Jul 8, 2026
@vkuzo
vkuzo merged commit d31dad6 into pytorch:main Jul 10, 2026
35 of 37 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. module: core changes affecting multiple modules, e.g. base config/tensor, observers, quant ops

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants