[jit] Rebuild a module when its prebuilt .so lacks the running GPU arch (fixes gfx1201 crash)#3839
[jit] Rebuild a module when its prebuilt .so lacks the running GPU arch (fixes gfx1201 crash)#3839carlushuang wants to merge 1 commit into
Conversation
…PU arch A prebuilt module .so is a valid *host* Python extension on any GPU, so get_module_custom_op's importlib.import_module succeeds even when the .so was built for a different arch (e.g. a gfx942/gfx950 wheel imported on gfx1201). The missing device code object then only surfaces at kernel launch as an uncatchable HIP fault (SIGSEGV) -- never as the ModuleNotFoundError that would trigger compile_ops to JIT-rebuild. So a CDNA-only prebuilt silently shadows the JIT and crashes instead of rebuilding for the running arch. Add an arch-coverage check before importing: parse the on-disk .so's clang offload-bundle targets; if it carries device code for other arches but NOT get_gfx_runtime(), raise ModuleNotFoundError so compile_ops rebuilds for the native arch. Checking before the import is required -- once a stale extension is loaded into the process it cannot be reloaded. Host-only modules (no offload targets) and undetectable-arch environments fall through to a normal import. This is the general fix for "prebuilt wheel missing my arch": any reachable module auto-JITs for the running GPU instead of faulting. - aiter/jit/core.py: _so_offload_archs() + arch guard in get_module_custom_op - op_tests/test_jit_arch_guard.py: offload-target parser unit tests Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
🏷️ CI GuideRuns automatically on every PR:
Extended tests (opt-in via labels):
|
|
Closing — not needed for ATOM ROCm/ATOM#811. The simplest resolution for gfx1201 is to build aiter with This loader arch-coverage guard is still a reasonable general robustness improvement — auto-rebuild (or a clear error) when an installed prebuilt wheel lacks the running GPU's arch, instead of an uncatchable SIGSEGV at launch. The underlying behavior is tracked in #3846, which stays open. If maintainers want that auto-rebuild behavior, this can be revived; it's just not a dependency for #811. |
Summary
Make the JIT loader rebuild a module for the running GPU when its prebuilt
.sodoesn't cover that arch, instead of importing a wrong-arch prebuilt that then faults at kernel launch.Problem
A prebuilt module
.sois a valid host Python extension on any GPU. Soget_module_custom_op'simportlib.import_modulesucceeds even when the.sowas built for a different arch (e.g. agfx942;gfx950wheel imported on gfx1201). The missing device code object then only surfaces later, at kernel launch, as an uncatchable HIP fault (SIGSEGV) — never as theModuleNotFoundErrorthat would makecompile_opsJIT-rebuild. Net: a CDNA-only prebuilt silently shadows the JIT and crashes instead of rebuilding for the running arch.This is the root cause behind the gfx1201 (RDNA4) KV-cache crash, and it generalizes to any wheel whose prebuilt set omits the user's GPU.
Fix
Add an arch-coverage check before importing (a stale extension can't be reloaded once loaded into the process):
_so_offload_archsparses the.so's clang offload-bundle entry ids (thegfxNNNNin…amdhsa--gfxNNNN).build_moduleoverwrites the.sowith a native-arch build and the subsequent import loads it.Any reachable module now auto-JITs for the running GPU instead of faulting.
Validation (RX 9070 XT, gfx1201)
Unit (
op_tests/test_jit_arch_guard.py): offload-target parser — multi-arch, host-only, missing-file.End-to-end, the real shipped-prebuilt scenario: restored a CDNA-only
module_cache.so(gfx942;gfx950, no gfx1201), then ran ATOM + aiter on gfx1201. The loader loggedrebuilt in place, and the server booted clean (no SIGSEGV):
Matches prior runs exactly — correctness and perf unchanged; the only difference is it no longer crashes.
Relationship to other PRs
_hip_cache_supported()allowlist — with this guard, gfx1201 just JITsmodule_cache. I'll close [gfx1201] Dedicated CK-free reshape_and_cache (paged KV write) for RDNA4 #3837 if this lands.