Repository navigation
[FlyDSL] [AOT] Build gfx1250-strict wheels from the gfx1250 kernel family - #7379
Conversation
🏷️ CI GuideRuns automatically on every PR:
Extended tests (opt-in via labels):
One backend per PR: PR title tags & labels: |
NOT READY FOR HUMAN REVIEWPR Self-ReviewRevision Waiting for the PR author. The readiness report will appear after the self-review answers are complete for this revision. Questions to answer in the PR description
Edit the Missing or invalid answers
Shadow mode reports what would block but keeps the status successful. Set |
501e85a to
1943392
Compare
Self-review (aiter
|
…mily GPU_ARCHS=gfx1250-strict matched zero FlyDSL tuned rows and printed "All compilations succeeded" -- a silent empty wheel -- because the AOT job filters compared the tuned-row arch (gfx1250) against the exact requested target (gfx1250-strict) and dropped everything. chunk_gdn_h ignored GPU_ARCHS entirely and compiled gfx942 kernels while labelling the run strict. gfx1250-strict (MI450 A0) and gfx1250 (B0) are one source/kernel family, so a gfx1250-tuned row should serve a gfx1250-strict build and be compiled for the exact strict target (ELF mach 0xeb, not gfx1250 0x49). Add common.resolve_target_arch (family-match + retarget to the exact requested arch) and common.assert_targets_covered (fail loud when a family present in the tuned data produces no job). Every AOT entry now honors GPU_ARCHS for strict: - gemm.py / conv.py: keep family-matching rows, retarget the compile. - chunk_gdn_h.py: honor GPU_ARCHS (previously unfiltered -> gfx942), retarget. - moe.py: family-match + retarget in both the orchestrator and the per-arch replay worker; the GateMode/quant gfx1250 checks become family-aware. - mega_moe.py / fmha_fp8.py / mxfp4_moe.py are gfx950-only; they now skip a strict build instead of emitting gfx950 kernels into it (mega_moe already did; fmha_fp8 and mxfp4_moe gained the same GPU_ARCHS guard). FlyDSL compiles the strict target as of flydsl 0.4.2.dev1008 (bare gfx1250 to MLIR Chipset::parse, full gfx1250-strict to LLVM codegen), landing in the 0.4.2 release; the pin bump is tracked separately. Verified on real MI450 A0: a gfx1250 row compiled for gfx1250-strict yields an artifact with rocdl chip=gfx1250-strict and ELF e_flags 0x4eb (mach 0xeb). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1943392 to
48380a9
Compare
|
Correction to the self-review above: per the "don't add op_tests unless necessary" convention (they add CI machine time), the |
main's #6956 moved the GEMM/conv/chunk_gdn_h/FP8-FMHA AOT drivers into a shared aiter/aot/flydsl/replay.py. Re-apply the gfx1250-strict family-match + retarget there (one place) instead of the now-removed per-entry filters; take main's version of the four refactored entries. moe.py and mxfp4_moe.py keep their own drivers and retain the strict fix; common.py keeps resolve_target_arch / assert_targets_covered. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…0-strict wheels (#7434) * [FlyDSL][AOT] Map gfx1250-strict to the gfx1250 kernel family at AOT dispatch/tuned-lookup sites Follow-up to #7379. With GPU_ARCHS=gfx1250-strict, #7379 fixed job *selection* (strict was selecting 0 jobs), but the enqueued jobs were then rejected a second time inside the op layer, where 8 sites compared the exact arch to the literal "gfx1250". That capped the strict AOT wheel at ~7% coverage (140 vs 1002 artifacts) with 5 hard [FAIL]s. This maps strict to the gfx1250 family at exactly those AOT-traversed sites: - 3 dispatch gates (capability / codegen choice) -> is_gfx1250_family(): gemm_op_a8w8 mxfp8_128 gate and blockscale_abpreshuffle guard (the rc=1 raise), and flydsl moe_kernels LDS selection. - 5 tuned-config lookups -> exact identity first, gfx1250-family fallback when strict has no tuned row of its own: tuned_gemm (a16w16), gemm_op_a4w4 (a4w4 mxscale), grouped_moe CSV, plus the a8w8 mxscale and shared CK config helpers reached once the gates above open. A0 bring-up reuses the gfx1250 tuned data (A0 and B0 share the gfx1250 ISA; performance parity is a later follow-up). An exact strict tuned row still wins when one exists, and the fallback guard (base_gfx_arch(gfx) != gfx) keeps the table scan off the normal non-strict runtime path. Build targets, cache keys, and prebuilt .co paths stay keyed by the exact identity, per #6767's two-layer model. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * [FlyDSL][AOT] Family-map the second layer of gfx1250 op gates for strict A0 acceptance of the first commit surfaced a deeper layer: opening the first-layer gates let 816 previously-silently-dropped jobs reach a *second* set of exact-"gfx1250" checks -- all GATE, zero genuine kernel failures. Deduped to 2 hard points + the silent coverage gaps: - [A] gemm_op_a8w8 gemm_a8w8_mxfp8_128_bpreshuffle_flydsl guard (812 of 816 FAILs) + the bpreshuffle WMMA dispatch gate (189) and untuned fallback (917). - [B] opus get_kernel_instance now folds arch to the gfx1250 family (get_registry already did; this was the missed sibling -> "unknown OPUS kid" on strict). - [D] flydsl batched_gemm_a8w8 _RUNNERS lookup. - [C]/[E] a8w8 int8 and mxfp8_32 tuned-config lookups -> exact-then-family fallback; plus the mxfp8_bpreshuffle_tuned predicate and the a_scale_preshuffled gate, mapped proactively to avoid a third round. Same two patterns as the first commit (dispatch gate -> is_gfx1250_family; tuned lookup -> exact identity first, gfx1250 fallback). Pending A0 re-acceptance. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * [FlyDSL][AOT] Family-map the BMM tuned-config lookup for strict An A0 per-row kernel-identity diff against the gfx1250 baseline found one remaining silent single-op drop: lookup_mxscale_bmm_config (opus/policy.py) keyed the mxscale BMM tuned table by the exact gfx, so a strict build missed all 50 BMM rows and 43 of them silently compiled a different heuristic kernel than gfx1250 (tile_k 512/nb2 instead of the tuned 256/nb4), with no log. Same exact-identity-first, gfx1250-family fallback as the other tuned lookups. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * [FlyDSL][AOT] Gate the opus strict->gfx1250 fold to AOT replay only The get_kernel_instance fold this PR added was unconditional, which let a non-CO kid resolve under a strict *runtime* identity instead of being rejected -- breaking op_tests/test_gfx1250_strict_alias::test_non_co_kid_keeps_real_id (the expected ValueError was no longer raised). Only an AOT replay (AITER_AOT_REPLAY=1) compiles the whole gfx1250 kernel family for the strict target and needs the fold; the product is still emitted for the exact strict arch (0xeb). At runtime the exact identity is kept, so a non-CO kid under strict is rejected as before, and CO kids keep resolving via get_registry's existing fold. Verified locally: the test passes again. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * [FlyDSL][AOT] Gate A0-errata ops off strict + fail the build on hollow kernels gfx1250-strict deliberately disables wmma-f4-insts and wmma-16x16x128fp8-insts for A0 silicon errata, so a strict build of the ops that need them (a8w8 ptpc, a4w4 / a4w4_mx32_compute, MoE mxfp4) silently compiled HOLLOW, compute-less kernels (rc 0). Earlier family-mapping routed these to the gfx1250 fast-WMMA kernels, which is wrong for strict. - Gate the errata ops off the strict AOT build: skip the a8w8_bpreshuffle and a4w4_mxscale_bpreshuffle tables (STRICT_ERRATA_TABLES) and MoE mxfp4 rows (_is_mxfp4_kname) when the target is a gfx1250-strict identity. A0 falls back to runtime JIT for these. The good ops (mx128/mx32/BMM/a16w16/fp8-TDM, which use retained instructions) are unaffected. - Defense in depth: fail_build_on_missing_target_feature wraps run_aot and fails the build (fd-level capture of the LLVM 'requires target feature' diagnostic) if any hollow kernel is still produced, so a missed errata op can never silently ship a hollow wheel. The feature-disable is correct; the compiler-side ask (hard-fail / safe lowering) is tracked separately. Pending A0 validation. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * [FlyDSL][AOT] Fix the MoE strict gate: key on fp4 q_dtype_a, gate the worker too A0 STEP-0 validation found the MoE errata gate was a no-op: _is_mxfp4_kname matches "flydsl_mxmoe_g", but the gfx1250 grouped rows name their kernel grouped_gemm1_fp4_gugu (also shared by the fine fp8-activation a8w4 rows), so no row was gated. Key on q_dtype_a == float4 instead, which cleanly separates the hollow fp4 rows from the fp8-activation ones. Also add the gate to the `--arch` worker, which re-reads the CSV and filters independently of run(). GEMM gate confirmed correct by STEP 0 (a8w8_bpreshuffle ptpc + a4w4_mxscale tables, all hollow; every other table clean). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * [FlyDSL][AOT] Guard direct driver invocation too, and make the guard reentrant The hollow-kernel build guard only wrapped run_aot (the setup.py wheel path), so a direct `python -m aiter.aot.flydsl.<driver>` build was unguarded. Wrap the driver orchestrator entry points (replay.main, moe.main) as well. To avoid double-capturing fd 2 when guards nest -- run_aot's guard around a driver whose main also guards, or an orchestrator around its per-arch worker subprocesses -- the guard now sets AITER_AOT_FEATURE_GUARD=1 (inherited by children); a nested or child guard sees it and no-ops, so only the outermost capture is active. (The remaining cache-hit gap -- a stale pre-gate hollow object that is not recompiled, so prints no diagnostic -- is addressed by building strict wheels from a clean cache; the complete errata gate means a fresh build never produces one.) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * [FlyDSL][AOT] Audit the strict cache for stale hollow errata kernels A0 showed the compile-time guard misses a hollow kernel already in the FlyDSL cache: a cache hit recompiles nothing and prints no 'requires target feature' diagnostic, and setup.py's cache persists across builds, so a stale hollow object would ship silently. Add a cheap post-build name audit: after a strict run_aot, fail if the cache still holds any gemm_a4w4* / gemm_a8w8_ptpc* / mxfp4_tdm_fp4* object -- the errata families strict gates off. It inspects the cache, not the compiler output, so it is immune to cache hits. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * [FlyDSL][AOT] Rewrite the stale-hollow cache audit to read kernel IR A0 found the glob-by-filename audit could not work: cache paths are <launcher>_<manager_key>/<hash>.pkl, so the kernel name is not in the path -- ptpc shares launch_gemm_a8w8 with mx128 and fp4 MoE shares launch_gemm_a8w4_tdm with fp8, so the ptpc/mxfp4 globs never matched, gemm_a4w4 matched only a directory name, and a mixed gfx1250+strict build false-positived on legitimate gfx1250 a4w4 objects. Read each cached object's IR instead: flag an errata-family kernel (gemm_a4w4 / gemm_a8w8_ptpc / mxfp4_tdm_fp4) only in objects whose ROCDL target chip is a strict identity. A0-validated on the same cache set: dirty caches report 134 / 282 / 101 offenders; clean, plain, and mixed-target all pass. ~1000 pkl, a few seconds. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: zufayu <8138883+zufayu@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Main's gfx1250-strict wheel builds (#7379, #7434) and MegaMoEV2 (#6881) edited the code this branch rewrites; both sides are kept: - moe.py: an arch's replay keeps the jobs of that arch's family, retargets them to it and leaves out the MXFP4 ones on gfx1250-strict; deployment jobs now pass through that filter as rows do. run_aot and moe.py's main run inside fail_build_on_missing_target_feature(), and run_aot still ends with the strict errata check. - mega_moe.py: the MTPR 8192 instances build the opt-in small- and large-input paths, and --check compiles nothing. FUSED_PATHS_MTPR and FUSED_PATHS_ENV stay module constants: they say how the replay builds an instance, not what a deployment is. - README: main's gdn_fused_prefill entries next to the deployment ones. #6464 moved DeepSeek-V4-Pro's TP8 rows at M 32 and 2048 to MXMOE stage 1, which compiles the clamp in, so the clamp the TP8 deployment passes now picks kernels the deployment builds. The merge changes no job list: the 1195 deployment jobs are 88ab025's, the 14374 tuned-row jobs main's (apart from the empty expert_mask_size this branch adds) and the 192 MegaMoE jobs main's. Co-authored-by: Cursor <cursoragent@cursor.com>
Problem
GPU_ARCHS=gfx1250-strictproduced a silently empty / wrong FlyDSL AOT wheel: GEMM matched 0 tuned rows yet reported success (empty wheel), andchunk_gdn_hcompiled gfx942 kernels while labelling the run strict.Root cause is on the aiter side (not FlyDSL): the AOT job filters compared the tuned-row arch (
gfx1250) against the exact requested target (gfx1250-strict) and dropped everything, because tuning is done ongfx1250and there are nogfx1250-stricttuned rows.What this fixes (one line)
Makes a
GPU_ARCHS=gfx1250-strictwheel build actually emitgfx1250-strict(ELF mach0xeb) FlyDSL kernels — or fail loudly — instead of a silent empty/wrong wheel.Fix
gfx1250-strict(MI450 A0) andgfx1250(B0) are one source/kernel family, so agfx1250-tuned row serves agfx1250-strictbuild and is compiled for the exact strict target (0xeb, notgfx12500x49). Two small helpers incommon.py:resolve_target_arch(job_arch, targets)— exact requested target in the same family (viabase_gfx_arch), orNone; retargets agfx1250row togfx1250-strict.assert_targets_covered(...)— fail loud when a family present in the tuned data produces no job, instead of shipping an empty/partial wheel.Applied where each AOT driver filters and groups by arch:
replay.py(the shared driver from #6956)moe.pygfx1250checks become family-awaremxfp4_moe.pymega_moe.py/ FP8 FMHA are gfx950-only and correctly skip a strict build (the latter now throughreplay.py's family-aware filter).Depends on
FlyDSL compiles the strict target as of flydsl 0.4.2.dev1008 (bare
gfx1250to MLIRChipset::parse, fullgfx1250-strictto LLVM codegen), landing in the 0.4.2 release. The pin bump is tracked separately; with an older pin these drivers select the right rows but the compile still fails at the FlyDSL layer.Validation
gfx1250row compiled forgfx1250-strict(flydsl 0.4.2.dev1008) yields an artifact withrocdl chip=gfx1250-strictand embedded ELFe_flags=0x4eb(mach0xeb). FlyDSL runtime-JIT sanity (batched gemm / mha 256 cfg / quant / rmsnorm2d) is bit-identical to 0.4.1.Rebased onto main's #6956 (shared
replay.pyAOT driver); the strict family-match now lives in that one driver rather than per-entry. Follow-up to #6767 (strict identity) and #7185 (old-ROCm A0 Opus fallback), both merged.🤖 Generated with Claude Code