Skip to content

fix(conv): gate ASM-GTC fwd NHWC solver off int32-overflow tensors#9568

Open
yassinsolim wants to merge 8 commits into
developfrom
users/ysoliman/gate-asm-gtc-fwd-large-tensor
Open

fix(conv): gate ASM-GTC fwd NHWC solver off int32-overflow tensors#9568
yassinsolim wants to merge 8 commits into
developfrom
users/ysoliman/gate-asm-gtc-fwd-large-tensor

Conversation

@yassinsolim

Copy link
Copy Markdown
Member

Motivation

ConvAsmImplicitGemmGTCDynamicFwdXdlopsNHWC, the ASM-GTC forward solver from the
unmaintained MISA project, indexes global tensor memory with 32-bit element indices
and has no large-tensor support. On any problem whose flattened element count exceeds
INT_MAX it overflows that index and silently returns wrong results (forward
verification error ~0.37 on gfx942/gfx950; no crash, it runs, reports a time, and
produces incorrect output).

Because find selects a solver by timing alone and does not verify numerics, this
fast-but-wrong solver gets auto-selected over correct ones, and it currently breaks
develop in more than one configuration:

  • gfx950, default find: the heuristic selects MISA → wrong.
  • gfx942, exhaustive find (FIND_MODE=1/ENFORCE=4): MISA out-times CK on the 1024→1024
    shapes and is selected → wrong.

Neither a version bump nor a find-mode choice reliably avoids it. Since MISA is
deprecated/unmaintained and does not implement large-tensor support, it must be gated
during the applicability checks so it can never be selected for shapes it computes
incorrectly.

Technical Details

  • Added an element-count guard to ConvAsmImplicitGemmGTCDynamicFwdXdlopsNHWC::IsApplicable():
    returns not-applicable when GetIn()/GetOut()/GetWeights().GetElementSize() > INT_MAX.
  • The existing AllTensorsDimsFitIntoInt() check only validates that each individual
    length/stride fits in int32, it does not bound the flattened element count. For a
    packed NHWC tensor the largest stride ≈ elements/N, so a shape can have every stride fit
    int32 while the element count overflows; the new predicate is what catches these.
  • No-op for every int32-safe shape (the guard is false), so existing workloads take the
    identical code path, zero functional change outside the overflow regime.
  • Complementary to feat(conv): large-tensor grouped CK xdlops conv + split_k workspace backport #9427: that PR keys CK large-tensor instances on
    !AllTensorsDimsFitIntoInt() (stride regime) and does not touch MISA; this gate covers
    the element-count regime and removes the silently-wrong MISA candidate.
  • Scope: forward NHWC ASM-GTC solver. CHANGELOG.md updated. Related to ROCM-27526.

Files: src/solver/conv/conv_asm_implicit_gemm_gtc_fwd_nhwc.cpp,
test/gtest/unit_conv_solver_ConvAsmImplicitGemmGTCDynamicFwdXdlopsNHWC_LargeTensor.cpp,
CHANGELOG.md.

Test Plan

  • New CPU device-applicability gtest (CPU_UnitTestConvSolver...DevApplicability): a
    batch-size boundary pair with identical geometry so the element count crosses INT_MAX,
    asserting the solver stays applicable just below the limit (N=140, 2.14e9 elements) and
    is gated off just above (N=141, 2.15e9). MockHandle-based, runs host-side, no allocation.
  • Empirical end-to-end validation on real hardware from from-source builds: gfx942/MI300X
    and gfx950/MI355X, ROCm 7.0.2.1 and 7.14, MIOpenDriver -t 1 verify.

Test Result

  • Forcing MISA on the >INT_MAX shapes reproduces the silent failure on both arches and both
    stacks (verify error ~0.37, some NaN), confirming it is the solver, not the stack.
  • With the gate: forcing the solver on those shapes returns "no suitable algorithm was found"
    on gfx942 and gfx950; natural find selects grouped CK xdlops and verifies OK on all
    previously-failing shapes; int32-safe shapes are unchanged.
  • No other fast forward solver applies at these sizes (GEMM and Winograd both report
    not-applicable), so CK is the correct target the gate steers find toward.
  • The new gtest is exercised by CI. (It was not run on this host, no GPU/clang-format dev
    toolchain available; the gate code itself compiles, having been built identically in the
    from-source validation images.)

Submission Checklist

@therock-pr-bot

therock-pr-bot Bot commented Jul 17, 2026

Copy link
Copy Markdown

✅ All Checks Passed — Ready for Review

Check Status Details
🌿 Branch Name ✅ Pass
📝 PR Title/Description ✅ Pass
Forbidden Files ✅ Pass
🧪 Unit Test ✅ Pass
🔎 pre-commit ✅ Pass
🚫 Draft PR 🔜 To Be Enabled
🚩 Feature Flag 🔜 To Be Enabled
📊 Code Coverage 🔜 To Be Enabled
🤖 therock-pr-bot ✅ Pass

🎉 All checks passed! This PR is ready for review.

📖 Need help? See the Policy FAQ for details on every check and how to fix failures.

@therock-pr-bot

therock-pr-bot Bot commented Jul 17, 2026

Copy link
Copy Markdown

🎉 All checks passed! This PR is ready for review.

ConvAsmImplicitGemmGTCDynamicFwdXdlopsNHWC (the ASM-GTC forward solver
from the unmaintained MISA project) indexes global tensor memory with
32-bit element indices and does not implement large-tensor support.

Its IsApplicable() relied on AllTensorsDimsFitIntoInt(), which only
checks that each individual length/stride fits in int32 -- it never
bounds the flattened element count. A tensor whose total element count
exceeds INT_MAX therefore overflows the kernel's 32-bit indexing and is
silently computed incorrectly (observed forward verification error
~0.37 on gfx942 and gfx950).

Gate the solver not-applicable when any tensor's element count exceeds
INT_MAX, so a large-tensor-capable solver (e.g. grouped CK xdlops) is
selected instead. This is a no-op for every int32-safe shape, so
existing workloads are unaffected.

Adds a CPU device-applicability unit test that shares geometry across a
batch-size boundary so the element count crosses INT_MAX, asserting the
solver stays applicable just below the limit and is gated off just above.

Related to ROCM-27526.
@yassinsolim
yassinsolim force-pushed the users/ysoliman/gate-asm-gtc-fwd-large-tensor branch from ac74d92 to 420bf8a Compare July 17, 2026 20:13
yassinsolim and others added 7 commits July 17, 2026 16:47
The preceding commit gates ConvAsmImplicitGemmGTCDynamicFwdXdlopsNHWC
not-applicable when any tensor's element count exceeds INT_MAX. The
shipped find-dbs still list that solver for such shapes -- it had been
recorded there (in some entries as the fastest kernel) even though its
32-bit element indexing computes those shapes incorrectly.

The db_sync FDB consistency test asserts every solver listed in a
find-db entry is still IsApplicable(), so the now-gated entries fail
Dbsync on gfx908/gfx90a/gfx942/gfx950. Prune the solver from exactly
the find-db entries whose input or output element count exceeds
INT_MAX, mirroring the gate and the MIOPEN_DBSYNC_CLEAN removal path
(cf. #3725, "Clean db files to pass db_sync"). Entries at or below
INT_MAX are left untouched; lines where it was the only listed solver
are dropped.

  gfx90878.HIP.fdb.txt   :  43
  gfx90a68.HIP.fdb.txt   : 102
  gfx90a6e.HIP.fdb.txt   : 102
  gfx942130.HIP.fdb.txt  : 268
  gfx942e4.HIP.fdb.txt   : 206
  gfx950100.HIP.fdb.txt  : 309

Related to ROCM-27526.
Dbsync reports ten pre-existing gfx942 FP32 forward records whose
GemmFwdRest solver is no longer applicable. Remove only those stale solver
configs so the static find-db matches current solver applicability.

This cleanup is independent of the ASM-GTC large-tensor gate and is kept in
a separate commit for review.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant