Repository navigation
Fix 2 kernel bugs - #8406
Fix 2 kernel bugs#8406
Conversation
31966e6 to
3cf854b
Compare
Codecov Report✅ All modified and coverable lines are covered by tests. ❌ Your project status has failed because the head coverage (77.89%) is below the target coverage (80.00%). You can increase the head coverage or adjust the target coverage. Additional details and impacted files@@ Coverage Diff @@
## develop #8406 +/- ##
========================================
Coverage 71.43% 71.43%
========================================
Files 2612 2612
Lines 407002 407002
Branches 60775 60775
========================================
+ Hits 290731 290733 +2
+ Misses 94967 94966 -1
+ Partials 21304 21303 -1
*This pull request uses carry forward flags. Click here to find out more.
🚀 New features to boost your workflow:
|
3cf854b to
17f96fb
Compare
4676650 to
e5754d6
Compare
Before: TDM + double-buffer tail forced the tail LR offsets back to
buffer0, but the TDM write pointer may stay at buffer1.
(after an odd number of main-loop iters)
After: No longer forces buffer 0 in the tail, unless wider local read
needs the offset recomputed (numReadsIterCoalesced>1).
Repro/affected tests: TDM kernels with a tail
e.g. bf6_tdm_gfx1250, tdm_gfx1250, ...
1. Set LDS>=64KB and 1LDSB and SIA0 to reproduce the issue 2. Fix test yaml: f64_gfx1250 (using LocalReadVALU)
401898e to
41887aa
Compare
There was a problem hiding this comment.
Pull request overview
This PR addresses three gfx1250 kernel correctness issues around TDM tail local-reads, LDS addressing for LocalReadVALU when LDS offsets exceed 64KB, and a known-bad TDM prefetch configuration (PGR=2/PLR=0) by rejecting it.
Changes:
- Adjust tail-loop local-read offset reset logic to avoid forcing buffer-0 for TDM tails unless required (e.g., wider local-read / StreamK).
- Fix
LocalReadVALULDS source-address selection so reads past 64KB use the correctLocalReadAddr+NVGPR segment. - Update test/logic YAMLs to exercise the bug scenario and to move affected solutions off PLR=0 (and reject the unsupported combo in solution derivation).
Reviewed changes
Copilot reviewed 12 out of 12 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| projects/hipblaslt/tensilelite/Tensile/Tests/common/gemm/gfx12/tdm_gfx1250.yaml | Adds an “odd DU + tail” exact size to exercise the TDM tail behavior. |
| projects/hipblaslt/tensilelite/Tensile/Tests/common/gemm/gfx12/f64_gfx1250.yaml | Forces 1LDSBuffer=0 (and SIA0) to reproduce/cover the LocalReadVALU >=64KB addressing case. |
| projects/hipblaslt/tensilelite/Tensile/SolutionStructs/Solution.py | Rejects the known-bad TDMInst=3 + PGR=2 + PLR=0 configuration. |
| projects/hipblaslt/tensilelite/Tensile/KernelWriterAssembly.py | Extends tail TDM descriptor reset conditions to align with tail LR offset reset policy (incl. StreamK). |
| projects/hipblaslt/tensilelite/Tensile/KernelWriter.py | Refines tail local-read reset gating for TDM tails and preserves wider-LR state across recalculation. |
| projects/hipblaslt/tensilelite/Tensile/Components/LocalRead.py | Fixes LocalReadVALU to use the correct LDS base VGPR when offsets exceed 64KB. |
| projects/hipblaslt/library/src/amd_detail/rocblaslt/src/Tensile/Logic/asm_full/gfx1250/GridBased/gfx1250_Cijk_Alik_Bjlk_HSS_BH_Bias_GG_HA_S_SAV_UserArgs.yaml | Moves solution from PLR=0 to PLR=1 and updates solution/kernel name strings accordingly. |
| projects/hipblaslt/library/src/amd_detail/rocblaslt/src/Tensile/Logic/asm_full/gfx1250/GridBased/gfx1250_Cijk_Alik_Bjlk_HHS_BH_Bias_GG_HA_S_SAV_UserArgs.yaml | Same: PLR=0 → PLR=1 update. |
| projects/hipblaslt/library/src/amd_detail/rocblaslt/src/Tensile/Logic/asm_full/gfx1250/GridBased/gfx1250_Cijk_Ailk_Bljk_HSS_BH_Bias_GG_HA_S_SAV_UserArgs.yaml | Same: PLR=0 → PLR=1 update. |
| projects/hipblaslt/library/src/amd_detail/rocblaslt/src/Tensile/Logic/asm_full/gfx1250/GridBased/gfx1250_Cijk_Ailk_Bljk_HHS_BH_Bias_GG_HA_S_SAV_UserArgs.yaml | Same: PLR=0 → PLR=1 update. |
| projects/hipblaslt/library/src/amd_detail/rocblaslt/src/Tensile/Logic/asm_full/gfx1250/GridBased/gfx1250_Cijk_Ailk_Bjlk_HSS_BH_Bias_GG_HA_S_SAV_UserArgs.yaml | Same: PLR=0 → PLR=1 update. |
| projects/hipblaslt/library/src/amd_detail/rocblaslt/src/Tensile/Logic/asm_full/gfx1250/GridBased/gfx1250_Cijk_Ailk_Bjlk_HHS_BH_Bias_GG_HA_S_SAV_UserArgs.yaml | Same: PLR=0 → PLR=1 update. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
41887aa to
4db9b4d
Compare
4db9b4d to
65166e3
Compare
## Summary This change fixes tensor-DMA bounds contracts exposed while reducing the stock gfx1250 TensileLite TDM tail failure tracked by #9935. It is independent of the VMID correction in #9775 at the source level. Both changes are needed to advance the original workload through the currently known rocJITsu model gaps. ## Related producer-side evidence - ROCm/rocm-libraries#7976 introduced TDM iterate mode and the `tdm_gfx1250.yaml` configuration lineage that exposed this gap. - ROCm/rocm-libraries#8406 contains the same affected configuration after iterate mode was enabled and reports passing FFM and B0 validation. This is file-level evidence rather than a published per-solution trace. - ROCm/rocm-libraries#9410 added iterate-mode edge cases with waves that have zero valid rows specifically to exercise descriptor bounds clamping, and reports passing FFM validation. ## Failure before this fix Iterate mode advanced the starting global address for each repeated tile, but rocJITsu continued to apply bounds using tile-local coordinates. A final row outside the tensor was therefore copied into LDS instead of being zero-filled. An active tensor extent of zero was treated as unbounded. The complete dense or gather tile could therefore be copied instead of being masked. ## Fixes ### Include iterate-mode address advancement in tensor bounds The model decomposes each advancing iteration's linear global-address increment into an absolute tensor-coordinate origin, then applies one bounds predicate to that origin plus the tile-local coordinate. This handles sub-row advances, row advances, and rank-3 plane advances through the same path. Overlapping-stride layouts are rejected only when multiple iterations actually advance the global origin; repeated-origin descriptors do not require inverse coordinate decomposition. ### Treat zero active tensor extents as empty For an active dense or gather tile dimension, tensor extent zero masks the complete dimension. Loads zero-fill the affected LDS elements and stores suppress the corresponding global writes. Optional null descriptor groups retain their architectural zero-filled value. A rank-3 tile with null D2 therefore has a zero third tensor extent: it masks the transfer without aborting execution, still completes an enabled barrier, and releases TENSORCNT normally. ### Avoid unnecessary origin decomposition Non-iterating descriptors use an all-zero origin directly. This avoids inverse stride decomposition, including accepted rank-5 layouts whose large default strides can wrap. ## Test coverage Focused decoded-instruction regressions verify: - partial final-row load zero-fill and corresponding store suppression; - active zero-length dense and gather extents; - null-D2 rank-3 load masking and store suppression; - completion-barrier arrival and TENSORCNT release for null D2; - sub-row, row, and rank-3 plane iteration origins; - rejection of advancing overlapping-stride layouts; - acceptance of repeated-origin overlapping-stride layouts; and - safe non-iterating rank-5 execution. The complete `Gfx1250ExecutionTest.TensorDma*` test set and changed-file pre-commit checks pass locally. ## Workload status This PR intentionally does not claim to fix the complete TensileLite reproducer. It removes independently testable descriptor-model discrepancies and gets the workload closer to the unresolved tail-loop semantic question. ## Issue tracking Progress toward #9935.
## Summary This change fixes tensor-DMA bounds contracts exposed while reducing the stock gfx1250 TensileLite TDM tail failure tracked by #9935. It is independent of the VMID correction in #9775 at the source level. Both changes are needed to advance the original workload through the currently known rocJITsu model gaps. ## Related producer-side evidence - ROCm/rocm-libraries#7976 introduced TDM iterate mode and the `tdm_gfx1250.yaml` configuration lineage that exposed this gap. - ROCm/rocm-libraries#8406 contains the same affected configuration after iterate mode was enabled and reports passing FFM and B0 validation. This is file-level evidence rather than a published per-solution trace. - ROCm/rocm-libraries#9410 added iterate-mode edge cases with waves that have zero valid rows specifically to exercise descriptor bounds clamping, and reports passing FFM validation. ## Failure before this fix Iterate mode advanced the starting global address for each repeated tile, but rocJITsu continued to apply bounds using tile-local coordinates. A final row outside the tensor was therefore copied into LDS instead of being zero-filled. An active tensor extent of zero was treated as unbounded. The complete dense or gather tile could therefore be copied instead of being masked. ## Fixes ### Include iterate-mode address advancement in tensor bounds The model decomposes each advancing iteration's linear global-address increment into an absolute tensor-coordinate origin, then applies one bounds predicate to that origin plus the tile-local coordinate. This handles sub-row advances, row advances, and rank-3 plane advances through the same path. Overlapping-stride layouts are rejected only when multiple iterations actually advance the global origin; repeated-origin descriptors do not require inverse coordinate decomposition. ### Treat zero active tensor extents as empty For an active dense or gather tile dimension, tensor extent zero masks the complete dimension. Loads zero-fill the affected LDS elements and stores suppress the corresponding global writes. Optional null descriptor groups retain their architectural zero-filled value. A rank-3 tile with null D2 therefore has a zero third tensor extent: it masks the transfer without aborting execution, still completes an enabled barrier, and releases TENSORCNT normally. ### Avoid unnecessary origin decomposition Non-iterating descriptors use an all-zero origin directly. This avoids inverse stride decomposition, including accepted rank-5 layouts whose large default strides can wrap. ## Test coverage Focused decoded-instruction regressions verify: - partial final-row load zero-fill and corresponding store suppression; - active zero-length dense and gather extents; - null-D2 rank-3 load masking and store suppression; - completion-barrier arrival and TENSORCNT release for null D2; - sub-row, row, and rank-3 plane iteration origins; - rejection of advancing overlapping-stride layouts; - acceptance of repeated-origin overlapping-stride layouts; and - safe non-iterating rank-5 execution. The complete `Gfx1250ExecutionTest.TensorDma*` test set and changed-file pre-commit checks pass locally. ## Workload status This PR intentionally does not claim to fix the complete TensileLite reproducer. It removes independently testable descriptor-model discrepancies and gets the workload closer to the unresolved tail-loop semantic question. ## Issue tracking Progress toward #9935. (cherry picked from commit a659172)
Motivation
Fix kernel bugs:
Fix TDM tail local-read using wrong LDS buffer (bf6_tdm_gfx1250, tdm_gfx1250,...)
-- key config: 1LDSBuffer=0
Fix LocalReadVALU overwriting correct LDS>=64KB read address (f64_gfx1250.yaml)
-- key config: 1LDSBuffer=0 + EPS=True (both SIA0/SIA1)
The bug requires DeviceLDS > 64KB (so that num > 0 becomes possible) on the double-buffer path.
Only gfx950 and gfx1250 satisfy this. On gfx950 the non-MI test datatype is bf16, which derives EPS = False → hasMultipleBuffer = False; the only way bf16 can make a single operand region (A or B) reach ≥ 64KB is DepthU = 512, but such kernels exceed the 256-VGPR limit and fail to generate. Hence no buildable num > 0 kernel exists on gfx950.
Fix TDM PGR=2/PLR=0: force ds waitcnt before LR->TDM barrier to fix write-after-read :
The "wait current LR finish for next GR(TDM)" barrier had no preceding dscnt wait, and PGR>=2 made syncThreads skip the force waitcnt0, so the next trip's tensor_load_to_lds could overwrite the LDS buffer still being local-read.
Technical Details
Fix TDM tail local-read using wrong LDS buffer
Before: TDM + double-buffer tail forced the tail LR offsets back to
buffer0, but the TDM write pointer may stay at buffer1.
(after an odd number of main-loop iters)
After: No longer forces buffer 0 in the tail, unless wider local read
needs the offset recomputed
(numReadsIterCoalesced>1).Fix the overwrite bug when using function
LocalReadVALUds_read_b64 destVgpr, srcAddr offset:paramList[0]
..........................└─dst─┘ └─src─┘ └────ds────┘
srcAddr: N*64KB
ds = DSModifiers ; immediate offset
Before (develop):
After (PR):
Test Plan
Tox test for all tests.
Test Result
tox passed on ffm&B0
Submission Checklist