Skip to content

fix(miopen): align LRN/LayerNorm grids and guard OOB threads on gfx1250 - #10251

Open
SreecharanGundaboluAMD wants to merge 4 commits into
developfrom
users/SreecharanGundaboluAMD/lrn_fix_gfx1250
Open

fix(miopen): align LRN/LayerNorm grids and guard OOB threads on gfx1250#10251
SreecharanGundaboluAMD wants to merge 4 commits into
developfrom
users/SreecharanGundaboluAMD/lrn_fix_gfx1250

Conversation

@SreecharanGundaboluAMD

Copy link
Copy Markdown
Contributor

JIRA ID : ROCM-28415

Motivation

MIOpen unit tests on gfx1250 reported 180 failures across two test suites:

  • Full/GPU*LayerNormBwdTest*{FP32,FP16,BFP16}.LayerNormTestBw — NaN gradients in dw and db for 5D tensors (NCDHW-style, layout 8)
  • Full/GPU*Lrn*{FP32,FP16}.TestFloat[16 (CrossChannel mode only) — large forward-result mismatches well above tolerance

Both failures share the same root cause: kernel launch global work sizes were set to raw problem dimensions that are not guaranteed to be multiples of the local work size. HIP silently drops the boundary threads in misaligned launches, causing incorrect results for inputs whose spatial extent is not evenly divisible by the tile size.

Technical Details

Three commits each follow the same two-step fix pattern:

1. fix(miopen/lrn): align forward LRN across-channels grid and guard OOB threads

  • projects/miopen/src/hip/mloNorm.cpp: rounded the x-grid for MIOpenLRNAcrossChannels4 up to the nearest multiple of _grp_tile0 using AlignUp(map_size_4, _grp_tile0).
  • projects/miopen/src/kernels/MIOpenLRNFwd.cpp: added an early-return guard so excess threads exit before touching global memory.

2. fix(miopen/lrn): align backward LRN across-channels grid and guard OOB threads

  • projects/miopen/src/hip/mloNorm.cpp: rounded up both x and y grid dimensions for MIOpenLRNAcrossChannelsBwd1 using AlignUp on _in_df_width / _in_df_height.
  • projects/miopen/src/kernels/MIOpenLRNBwd.cpp: added an early-return guard to prevent out-of-bounds reads/writes into top_df, scale, top, bot, and bot_df.

3. fix(miopen/layernorm): align backward weight/bias grid and guard OOB threads

  • projects/miopen/src/solver/layernorm/backward_layernorm.cpp: applied AlignUp(problem.inner_size, xlocalsize) to xgridsize in the non-parallel path, matching the pattern already used by the parallel and reduce-sum sibling paths.
  • projects/miopen/src/kernels/MIOpenLayerNorm.cpp: added an early-return guard in layernormbwdweightbias so excess threads do not perform out-of-bounds writes to dw and db.

The fixes are minimal and surgical — no algorithmic or data-layout changes. The AlignUp pattern is already used elsewhere in MIOpen for grid sizing; this change brings the affected code paths into conformance with that convention.

Risk Assessment

Risk Level: 🟢 Low

Level Indicators
🟢 Low Isolated changes to three kernel/solver files within the LRN and LayerNorm subsystems; no new logic, dependencies, or API surface introduced; consistent with patterns already present in the same codebase

Impacted Components

  • projects/miopen/src/hip/mloNorm.cpp — LRN kernel launch parameters
  • projects/miopen/src/kernels/MIOpenLRNFwd.cpp — LRN forward kernel (across-channels)
  • projects/miopen/src/kernels/MIOpenLRNBwd.cpp — LRN backward kernel (across-channels)
  • projects/miopen/src/kernels/MIOpenLayerNorm.cpp — LayerNorm backward weight/bias kernel
  • projects/miopen/src/solver/layernorm/backward_layernorm.cpp — LayerNorm backward solver

Potential Side Effects

  • No behavioral change for inputs already aligned to the tile size (the common case on other ASICs).
  • Extra threads on boundary launches now exit early rather than producing wrong results; no functional difference for in-bounds threads.

Mitigation Steps

  • The fix is limited to the known-broken code paths; sibling paths were already correct and are unchanged.
  • Changes are covered by the existing MIOpen UT suite (GPU*Lrn* and GPU*LayerNormBwdTest*), which previously reproduced the failures.

Test Plan

Ran the following test suites on gfx1250 (MI455X - A0, ROCm 7.15.0-dev):

Full/GPU*LayerNormBwdTest*FP32.LayerNormTestBw
Full/GPU*LayerNormBwdTest*FP16.LayerNormTestBw
Full/GPU*LayerNormBwdTest*BFP16.LayerNormTestBw
Full/GPU*Lrn*FP32.TestFloat[16  (CrossChannel mode)
Full/GPU*Lrn*FP16.TestFloat[16  (CrossChannel mode)

Test Result

All previously failing test cases pass after the fix. WithinChannel LRN tests (which were already passing) continue to pass, confirming no regressions in the sibling code path.

Submission Checklist

SreecharanGundaboluAMD and others added 4 commits July 30, 2026 19:11
… threads

The global work size for MIOpenLRNAcrossChannels4 was set to the raw
map_size_4 value, which is not guaranteed to be a multiple of GROUP_SIZE_X.
HIP requires global work size to be a multiple of local work size; misaligned
launches produce incorrect results by silently dropping boundary threads.

Round up the grid x-dimension to the nearest multiple of _grp_tile0 (==
GROUP_SIZE_X) using AlignUp, then add an early-return guard in the kernel
so the extra threads exit before touching global memory.

Co-Authored-By: Claude <noreply@anthropic.com>
…B threads

The global work size for MIOpenLRNAcrossChannelsBwd1 was set to the raw
_in_df_width / _in_df_height values, which are not guaranteed to be multiples
of GROUP_SIZE_X / GROUP_SIZE_Y. This could cause invalid kernel launches and
dropped boundary threads.

Round up both x and y grid dimensions using AlignUp, and add an early-return
guard in the kernel to prevent excess threads from indexing out of bounds into
top_df, scale, top, bot, and bot_df.

Co-Authored-By: Claude <noreply@anthropic.com>
…threads

The non-parallel path of LayernormBackward set xgridsize to the raw
problem.inner_size, which is not guaranteed to be a multiple of xlocalsize.
The parallel and reduce-sum sibling paths already used AlignUp correctly;
this path was an omission.

Apply AlignUp(problem.inner_size, xlocalsize) to match the sibling paths,
and add an early-return guard in layernormbwdweightbias so excess threads
do not perform out-of-bounds writes to dw and db.

Co-Authored-By: Claude <noreply@anthropic.com>
@therock-pr-bot

therock-pr-bot Bot commented Jul 31, 2026

Copy link
Copy Markdown

✅ All Checks Passed — Ready for Review

Check Status Details
📝 PR Description ✅ Pass
Forbidden Files ✅ Pass
🧪 Unit Test ⚠️ Warning Error: Source/code files changed without an accompanying unit test.
Expected: add at least one test file named like test_<name>.py / test_<name>.cpp (or <name>_test.*).
Current: code file(s) changed: projects/miopen/src/hip/mloNorm.cpp, projects/miopen/src/kernels/MIOpenLRNBwd.cpp, projects/miopen/src/kernels/MIOpenLRNFwd.cpp, projects/miopen/src/kernels/MIOpenLayerNorm.cpp, projects/miopen/src/solver/layernorm/backward_layernorm.cpp; no test file found
🔎 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.

🙋 Wish to Override Policy?

@therock-pr-bot

Copy link
Copy Markdown

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

@JonathanLichtnerAMD JonathanLichtnerAMD left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

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.

2 participants