Repository navigation
Conversation
amd-flashinfer 0.6.18+amd.1's generated AITER prefill config names __hip_bfloat16 before anything declares it, because the JIT's -DUSE_ROCM=1 turns off the hip_bf16.h include in torch's BFloat16.h. Every bf16 model on FlashInfer's auto backend dies at setup with a ninja log. Give the JIT the header through FLASHINFER_EXTRA_CUDAFLAGS on ROCm; 0.6.18+amd.2 includes it itself.
… pool's workers The pool is built under a config patch at the top of warmup, since the setting is part of a graph's cache key and an env default would recompile everything a golden cache holds.
A submodule can compile at load, and klein does, so the pool built at the top of warmup came too late: the first compile had already built it under inductor's defaults, quiesce included. The call moves to the top of EngineManager.build, so no model has to ask for it.
merceod
force-pushed
the
users/atindra/pr-35-t8-firststart
branch
from
November 1, 2026 15:06
908b73f to
b12e249
Compare
vasilevklart
self-requested a review
November 1, 2026 22:04
vasilevklart
approved these changes
Nov 2, 2026
vasilevklart
left a comment
Collaborator
There was a problem hiding this comment.
LGTM. The mechanism matches torch 2.12.1 subproc_pool.py (SubprocMain._quiesce does self.pool.shutdown(wait=False)),
| # without waiting for it. A worker of the next pool forked meanwhile | ||
| # inherits the old pool's shutdown lock held by a thread it doesn't | ||
| # have, and hangs at its first full GC with the first job it took. | ||
| return {"quiesce_async_compile_pool": False} |
Collaborator
There was a problem hiding this comment.
The CPU repro hangs on SubprocPool alone, so CUDA should hit this on any start that retires a pool too, and the base class keeps the quiesce there
This branch has not been deployed
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.
Stacked on #1088 (pr-22-t4-fusion). Picks the commits of #1100 first; they drop out of this diff as those merge.
Why
A Qwen3.5 9B server's first start from a fresh compile-cache seed hung in 2 of 27 tries on the week-3 text tree and 0 of 26 on the base (5 of 44 against 0 of 43 in a second set), the engine waiting in
async_compile.get_resultwith the GPU idle. It's a fork race in torch 2.12.1's Inductor compile sidecar. The sidecar retires a pool that returned nothing for 60 s withshutdown(wait=False), and the old manager thread holdsshutdown_lockuntil its workers exit. A worker of the next pool forked in that window copies the lock held, and at its first full GCweakref_cbwaits on it forever, with the compile that gave it a job. No mstar frame is involved. The tree only exposes it: #1102's MI325X decode configs move 13 graphs out of a seeded cache, so a seeded start sends the pool 22 jobs instead of 1.What changed
Stacked on #1088 (#1087's engine.py is under it) with #1100 picked first, since the RocmPlatform hunk sits next to #1100's env default.
Platform.compile_pool_overrides():torch._inductor.configvalues in force while the engine builds Inductor's compile pool,{}on the base class. ROCm returns{"quiesce_async_compile_pool": False}.mstar/platforms/compile.py:start_compile_pool()builds the pool underinductor_config.patch(...). The pool reads the value once when it's built and keeps it after the patch, so the setting never reaches a graph's cache key and a golden compile cache stays valid. docs/architecture.rst says so.EngineManager.buildbefore any submodule loads, not first thing inEngine.warmup: a model that compiles at load (FLUX.2 klein, Z-Image, lingbot_world) had built the pool under Inductor's defaults.{}, sostart_compile_pool()returns before touching Inductor. This matters for main's CUDA path only if that platform sets the override, and it does not. The same torch code runs there, so the race probably exists on CUDA too (not tested).Verification
One MI325X per job on a shared node, so start times are direction only. First starts from a fresh seed, Qwen3.5 9B:
TORCHINDUCTOR_COMPILE_THREADS=1TORCHINDUCTOR_WORKER_START=spawnTORCHINDUCTOR_QUIESCE_ASYNC_COMPILE_POOL=0SubprocPoolalone hangs 13 of 13 at fork gaps of 0-2 ms. A CPU test assertspool.timer is None.Not in this PR
quiesce_async_compile_poolis part of every graph's cache key, so it recompiles 167 graphs on every first start of every ROCm model. A job without this fix can setTORCHINDUCTOR_COMPILE_THREADS=1instead.shutdown(wait=True)inSubprocMain._quiesceis the one-line fix (0 of 5 hung in the CPU repro). Not reported to torch yet; Python's note on the hazard is gh-90622.