Skip to content

[hipBLASLt] Fix SIA0+PGR2+PLR0: drain dscnt before barrier sync - #8204

Merged
chicyang merged 2 commits into
developfrom
users/chicyang/fix_SIA0_PGR2_PLR0
Jun 15, 2026
Merged

chicyang merged 2 commits into
developfrom
users/chicyang/fix_SIA0_PGR2_PLR0

Conversation

@chicyang

@chicyang chicyang commented Jun 9, 2026 •

Copy link
Copy Markdown
Contributor

Motivation

SIA0+PGR2+PLR0 TDM kernels gave wrong results because the cross-wave TDM buffer swap barrier didn't wait for in-flight local reads to drain

Technical Details

Insert a dscnt=0 wait before the TDM swap _syncThreads barrier when numItersPLR==0, ensuring all local reads finish before the buffer is reused.

Test Plan

Add a case

Test Result

Pass

tox test (those failed case are known issues: sk no solution)
image

Submission Checklist

@codecov-commenter

codecov-commenter commented Jun 9, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 0% with 2 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
...ects/hipblaslt/tensilelite/Tensile/KernelWriter.py 0.00% 2 Missing ⚠️

❌ Your project status has failed because the head coverage (77.83%) 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    #8204   +/-   ##
========================================
  Coverage    61.54%   61.54%           
========================================
  Files         2095     2095           
  Lines       361375   361377    +2     
  Branches     54697    54698    +1     
========================================
+ Hits        222389   222396    +7     
+ Misses      120140   120135    -5     
  Partials     18846    18846           
Flag Coverage Δ *Carryforward flag
TensileLite 28.65% <0.00%> (-0.01%) ⬇️
hipBLAS 90.65% <ø> (ø) Carriedforward from 9fba90b
hipBLASLt 41.25% <ø> (+0.08%) ⬆️
hipCUB 82.68% <ø> (ø) Carriedforward from 9fba90b
hipDNN 86.62% <ø> (ø) Carriedforward from 9fba90b
hipFFT 50.97% <ø> (ø) Carriedforward from 9fba90b
hipRAND 76.12% <ø> (ø) Carriedforward from 9fba90b
hipSOLVER 69.18% <ø> (ø) Carriedforward from 9fba90b
hipSPARSE 86.55% <ø> (ø) Carriedforward from 9fba90b
rocBLAS 48.10% <ø> (ø) Carriedforward from 9fba90b
rocFFT 47.15% <ø> (ø) Carriedforward from 9fba90b
rocRAND 57.02% <ø> (ø) Carriedforward from 9fba90b
rocSOLVER 77.83% <ø> (ø) Carriedforward from 9fba90b
rocSPARSE 72.31% <ø> (ø) Carriedforward from 9fba90b

*This pull request uses carry forward flags. Click here to find out more.

Files with missing lines Coverage Δ
...ects/hipblaslt/tensilelite/Tensile/KernelWriter.py 9.29% <0.00%> (-<0.01%) ⬇️

... and 3 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@chicyang
chicyang force-pushed the users/chicyang/fix_SIA0_PGR2_PLR0 branch 2 times, most recently from 84b8e1f to 0884567 Compare June 9, 2026 11:16
@jichangjichang
jichangjichang requested a review from Copilot June 10, 2026 05:51

Copilot AI 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.

Pull request overview

Fixes incorrect results in specific gfx12 TDM GEMM kernels by ensuring cross-wave LDS buffer swap synchronization does not occur while LDS local reads are still in flight (PLR=0 case).

Changes:

  • Add an explicit s_waitcnt dscnt=0 (via _wait(..., skipLocalRead=0)) immediately before the cross-wave TDM swap _syncThreads barrier when numItersPLR == 0.
  • Add a new Tensile YAML benchmark case to cover the problematic configuration (SIA0 + PGR2 + PLR0) on gfx1250.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
projects/hipblaslt/tensilelite/Tensile/KernelWriter.py Inserts a local-read drain (dscnt=0) before the cross-wave TDM swap barrier for the PLR=0 path to prevent buffer reuse hazards.
projects/hipblaslt/tensilelite/Tensile/Tests/common/gemm/gfx12/tdm_gfx1250.yaml Adds a targeted benchmark problem group intended to exercise the fixed synchronization scenario on gfx1250.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@chicyang
chicyang force-pushed the users/chicyang/fix_SIA0_PGR2_PLR0 branch 2 times, most recently from 3e896bb to 00aaddc Compare June 12, 2026 09:58
@chicyang
chicyang merged commit 01d9c04 into develop Jun 15, 2026
87 of 89 checks passed
@chicyang
chicyang deleted the users/chicyang/fix_SIA0_PGR2_PLR0 branch June 15, 2026 02:06
@mengzcai mengzcai mentioned this pull request Jun 24, 2026
1 task done
mengzcai added a commit that referenced this pull request Jun 25, 2026
## Motivation
Fix kernel bugs:

1. Fix **TDM tail** local-read using wrong LDS buffer (bf6_tdm_gfx1250,
tdm_gfx1250,...)
    -- key config:  **1LDSBuffer=0**

2. 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.

<img width="810" height="225" alt="image"
src="https://github.com/user-attachments/assets/e4765089-30ff-4262-8389-149fc32ad39c"
/>



3. --> the bug already fixed in the merged PR
#8204
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.
<!-- Explain the purpose of this PR and the goals it aims to achieve.
-->

## Technical Details
1. 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)`.

2. Fix the overwrite bug when using function `LocalReadVALU`

      ds_read_b64  destVgpr,    srcAddr    offset:paramList[0]
     ..........................└─dst─┘    └─src─┘ └────ds────┘
srcAddr: N*64KB
ds = DSModifiers ; immediate offset 

**Before (develop):**
```
num = paramList[0] // 65536
paramList[0] = paramList[0] - num * 65536      # paramList[0] is now reduced mod 65536, so it is always < 65536
srcVgpr = vgpr("LocalReadAddr%s+%d"%(tc,num))  # (A) correct high-part split, but stored in srcVgpr -> never used (**dead**)

if numOffsets == 1:
    addrIdx = paramList[0] // 65536            # (B) paramList[0] is already < 65536, so addrIdx is ALWAYS 0
    srcAddr = vgpr("LocalReadAddr%s+%u"%(tc, addrIdx))  # -> always LocalReadAddr+0 (high 64KB part dropped: BUG)
    paramList[0] -= addrIdx * 65536            # -> subtract 0, a no-op
    ds = DSModifiers(na=1, offset=paramList[0])
```

**After (PR):**
```
# The ds_read const offset field is only 16-bit. For LDS >= 64KB, split the byte
# offset into a high part (selects the base-address VGPR, each pre-advanced by
# 64KB) and a low part (the 16-bit offset immediate).
num = paramList[0] // maxLDSConstOffset                           # high part: which 64KB base register
paramList[0] = paramList[0] - num * maxLDSConstOffset     # low part: fits the 16-bit offset field
srcAddr = vgpr("LocalReadAddr%s+%d"%(tc, num))  # base VGPR already advanced by num * 64KB

if numOffsets == 1:  //-->f64 pass from here
    # e.g. ds_read_b64
    ds = DSModifiers(na=1, offset=paramList[0])
if numOffsets == 2:
    # combine two reads
    # e.g. ds_read2_b32 : two chunks share one base with two offsets.;one base &offset0 & offset1; 
    ds = DSModifiers(na=2, offset0=paramList[0], offset1=paramList[1])
    srcAddr = vgpr("LocalReadAddr%s"%tc)
```

3. Modified GroupedGemm logic yamls from TDM+PGR2+PLR0 to PLR1

<!-- Explain the changes along with any relevant GitHub links. -->

## Test Plan
Tox test for all tests.
<!-- Explain any relevant testing done to verify this PR. -->

## Test Result
tox passed on ffm&B0
<!-- Briefly summarize test outcomes. -->

## Submission Checklist

- [x] Look over the contributing guidelines at
https://github.com/ROCm/ROCm/blob/develop/CONTRIBUTING.md#pull-requests.

---------

Co-authored-by: mengzcai <mengzcai@amd.com>
Co-authored-by: test <test@test>
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.

4 participants