Skip to content

[rocjitsu] Fix ds_read_b64_tr_b16 lane layout in gfx950 simulator - #10175

Merged
kuhar merged 3 commits into
ROCm:developfrom
feikou:fix-ds-read-tr-b16-sim
Aug 18, 2026
Merged

kuhar merged 3 commits into
ROCm:developfrom
feikou:fix-ds-read-tr-b16-sim

Conversation

@feikou

@feikou feikou commented Aug 14, 2026 •

Copy link
Copy Markdown
Contributor

Motivation

ds_read_b64_tr_b16 returns incorrect results under the gfx950 (CDNA4) simulator. The instruction performs a 4x16-lane halfword transpose: within each 16-lane group, destination lane l halfword n comes from source lane ((l & ~0xf) | ((l >> 2) & 3)) + 4 * n, halfword l & 3 — the layout already encoded by the DBT reference in tests/dbt/cdna4_to_cdna3_lds_hip_test.cpp (LargeStaticLdsReadB64TrB16). The pure-simulation path's transpose_b16() instead performed a 4x4 transpose within groups of 4 consecutive lanes (lane 0 received source lanes 0,1,2,3 halfword 0 instead of lanes 0,4,8,12), so every gfx950 kernel that loads bf16/f16 MFMA operands with ds_read_b64_tr_b16 computed on wrong data under the simulator.

Technical Details

  • lib/rocjitsu/src/rocjitsu/isa/arch/amdgpu/shared/ds_transpose.h: transpose_b16() now handles the wave64 B64 case (4 halfwords per lane, i.e. ds_read_b64_tr_b16) with the 4x16-lane stride-4 layout above. This changes only that path; the B128 path used by gfx1250 ds_load_tr16_b128 / global_load_tr16_b128 and RDNA4 global_load_tr_b128 is left byte-for-byte unchanged. tr_b4 / tr_b6 / tr_b8 are untouched and were not hardware-verified here.
  • tests/amdgpu_vm_test.cpp: new DsTransposeTest.ReadB64TrB16_LaneLayout (CPU-only). Fills LDS with a per-lane halfword pattern, dispatches an encoded ds_read_b64_tr_b16 on the cdna4 VM fixture, and checks all 64 lanes x 4 halfwords against the same reference formula the DBT test uses.
  • TransposeKind is split into TR16_B128 (gfx1250/RDNA4 B128 loads, unchanged) and B64_TR_B16 (CDNA4 ds_read_b64_tr_b16), emitted from InstructionSemantics; transpose_response() dispatches on the kind.

Issue Tracking

No existing GitHub issue. Related: #6829 (AccVGPR acc bit handling for the same DS transpose reads).

Test Plan

  • ctest / rocjitsu_tests --gtest_filter='DsTransposeTest.*' for the new CPU-side layout test, before and after the transpose_b16() change.
  • Existing test suite for regressions.

Test Result

  • DsTransposeTest.ReadB64TrB16_LaneLayout: built and run locally (CPU only, GCC 13, Release): fails on the pre-change transpose_b16() with 128 mismatches (64 lanes x 2 dwords; e.g. lane 0 low dword 0x12111200 vs expected 0x12441200) and passes after.
  • Cross-checked on gfx950 hardware (ROCm 7.2.0) with an equivalent inline-asm ds_write_b64/ds_read_b64_tr_b16 kernel: hardware matches the expected layout; the simulator matched only after this change (all 64 lanes differed before).
  • Full ctest shows no status changes versus develop other than the added DsTransposeTest.ReadB64TrB16_LaneLayout.

Submission Checklist

The pure-sim transpose_b16() performed a 4x4 halfword transpose within
groups of 4 consecutive lanes for ds_read_b64_tr_b16. On gfx950 the
instruction is a 4x16-lane halfword transpose: destination lane l
halfword n comes from source lane ((l & ~0xf) | ((l >> 2) & 3)) + 4*n,
halfword (l & 3) -- the layout the DBT reference in
tests/dbt/cdna4_to_cdna3_lds_hip_test.cpp already encodes.

Handle the wave64 B64 case (4 halfwords per lane) with that layout and
leave the B128 path used by gfx1250 *_tr16_b128 and RDNA4
global_load_tr_b128 unchanged.

Add DsTransposeTest.ReadB64TrB16_LaneLayout, a CPU-side check of all 64
lanes x 4 halfwords against the DBT reference formula (fails on the old
layout, passes now), and hip_ds_read_tr_b16_sim_test, a HIP reproducer
that passes on gfx950 hardware (ROCm 7.2.0) and failed 64/64 lanes
under the simulator before this change.
@feikou
feikou requested review from a team and atgutier as code owners August 14, 2026 16:24
@therock-pr-bot

therock-pr-bot Bot commented Aug 14, 2026 •

Copy link
Copy Markdown

✅ All Policy Checks Passed

Check Status Details
📝 PR Description ✅ Pass —
⛔ Forbidden Files ✅ Pass —
🧪 Unit Test ✅ Pass —
🚫 Draft PR 🔜 To Be Enabled —
🚩 Feature Flag 🔜 To Be Enabled —
📊 Code Coverage 🔜 To Be Enabled —

🎉 All policy checks passed!

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

🙋 Wish to Override Policy?

@kuhar
kuhar requested a review from lua1235 August 14, 2026 16:34
@therock-pr-bot

Copy link
Copy Markdown

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

@lua1235 lua1235 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.

Thanks for fixing this! The changes look good, just 2 small comments.

Comment thread emulation/rocjitsu/tests/CMakeLists.txt Outdated
# generic HIP smoke tests are built for a local RDNA host such as
# gfx1201.
rj_add_hip_test(hip_ds_transpose_acc_test ARCH gfx950)
rj_add_hip_test(hip_ds_read_tr_b16_sim_test ARCH gfx950)

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.

Please also register this test with ctest. rj_add_hip_test only creates the build target.

eg: rj_add_hip_test_case(hip_ds_read_tr_b16_sim_test "DsReadTrB16SimTest.LaneLayout")


std::vector<uint8_t> output(response_data.size(), 0);

if (halfwords_per_source_lane == 4 && wf_size == 64) {

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.

Could we preserve this layout distinction in InstructionSemantics instead of inferring it here from read width and wave size?

TransposeKind::TR_B16 is now both CDNA4 ds_read_b64_tr_b16 and B128 TR16 loads. Since these are distinct layouts, please split them into separate transpose/layout kinds and dispatch on that here.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

SG, let me refactor this part. thanks for the reivew!

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done in a466e5a — split into TR16_B128 (id 4, gfx1250/RDNA4 B128 loads, unchanged) and a new B64_TR_B16 (id 5, CDNA4 ds_read_b64_tr_b16), emitted from InstructionSemantics; transpose_response() now dispatches on the kind. Gave the new id to the CDNA4 form so only cdna4/ds_exec.cpp needed regenerating.

TransposeKind::TR_B16 covered two distinct layouts. Split it: TR16_B128
(id 4, unchanged) carries the gfx1250 ds/global_load_tr16_b128 and RDNA4
global_load_tr_b128 grouped 16-bit layout, and a new B64_TR_B16 (id 5)
carries the CDNA4 ds_read_b64_tr_b16 4x16-lane layout. InstructionSemantics
and the codegen now emit the kind, so ds_transpose.h dispatches on it
instead of inferring the layout from read width and wave size. Regenerated
output changes only cdna4/ds_exec.cpp (DsReadB64TrB16 transpose 4 -> 5).

Register hip_ds_read_tr_b16_sim_test with ctest via rj_add_hip_test_case.

@lua1235 lua1235 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.

Looks good!

@kuhar kuhar left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM, thanks for fixing this

@kuhar

kuhar commented Aug 14, 2026

Copy link
Copy Markdown
Member

@feikou FYI, I root caused the tsan failure and it's novel but pre-existing and unrelated to your PR. I will wait for the test of the checks to finish before merging, and then fix up tsan in a follow up PR.

@feikou

feikou commented Aug 14, 2026 •

Copy link
Copy Markdown
Contributor Author

@feikou FYI, I root caused the tsan failure and it's novel but pre-existing and unrelated to your PR. I will wait for the test of the checks to finish before merging, and then fix up tsan in a follow up PR.

SG, thanks @kuhar for investigating and fixing the tsan!
I can rebase on top of yours later.

@kuhar

kuhar commented Aug 15, 2026 •

Copy link
Copy Markdown
Member

Update @feikou: I have a fix up for review that should makes your test work properly under sanitizers: #10195 , but I think we want to drop the test file anyway for the same reason @atgutier stated in #10192 (review).
We prefer not to rely on HIP C++ tests w/ inline assembly and instead test in-process like in

// Verify that ds_read_b64_tr_b16 with acc=1 writes to AccVGPR (vb+256+vdst),
// not to VGPR (vb+vdst).
TEST(DsTransposeTest, ReadB64TrB16_AccBit) {
VmFixture f("cdna4", 1, 10);
auto *snap = f.capture_halts();
constexpr uint32_t VDST = 4;
constexpr uint32_t ADDR_REG = 0;
constexpr uint32_t DS_OP = 227; // ds_read_b64_tr_b16
// Kernel:
// v_mov_b32 v0, 0 ; addr = LDS offset 0
// v_mov_b32 v4, 0x42 ; sentinel in VGPR v4
// v_mov_b32 v5, 0x42 ; sentinel in VGPR v5
// ds_read_b64_tr_b16 a[4:5], v0 ; acc=1: write to AccVGPR
// s_waitcnt lgkmcnt(0)
// s_endpgm
using namespace enc;
const uint32_t code[] = {
v_mov_b32(ADDR_REG, INLINE_CONST(0)),
v_mov_b32(VDST, INLINE_CONST(42)),
v_mov_b32(VDST + 1, INLINE_CONST(42)),
ds_lo(DS_OP, /*offset0=*/0, /*offset1=*/0, /*acc=*/1),
ds_hi(VDST, /*data0=*/0, ADDR_REG),
S_WAITCNT_0,
S_ENDPGM,
};
uint64_t ko = f.write_kernel(0x1000, code, sizeof(code));
auto *cu = f.cu();
// Write a known non-zero pattern to LDS.
for (uint32_t i = 0; i < 256; ++i)
cu->lds().write32(i * 4, 0xDEADBEEF);
test::AqlQueue queue(f.mem(), f.cp());
queue.dispatch(ko, 64);
f.engine->run();
ASSERT_EQ(snap->snapshots().size(), 1u);
const auto &wf = snap->snapshots().front();
// VGPR v4 should still hold the sentinel (42), not overwritten by ds_read.
uint32_t vgpr_val = wf.vgpr(VDST, 0);
EXPECT_EQ(vgpr_val, 42u) << "VGPR v" << VDST << " should NOT have been written when acc=1";
// AccVGPR a4 should have been written with LDS data (not 42, not 0).
uint32_t acc_val = wf.vgpr(256 + VDST, 0);
EXPECT_NE(acc_val, 0u) << "AccVGPR a" << VDST << " should have been written by ds_read";
EXPECT_NE(acc_val, 42u) << "AccVGPR a" << VDST
<< " should contain LDS data, not the VGPR sentinel";
}
.

Keep the in-process DsTransposeTest.ReadB64TrB16_LaneLayout; per review, HIP inline-asm tests per instruction are not wanted.
@feikou

feikou commented Aug 17, 2026

Copy link
Copy Markdown
Contributor Author

Done in 1314f99 — dropped the HIP test file and its CMake registration; the in-process DsTransposeTest.ReadB64TrB16_LaneLayout stays. Thanks for #10195.

@kuhar
kuhar merged commit 95b6c41 into ROCm:develop Aug 18, 2026
28 of 30 checks passed
atgutier pushed a commit that referenced this pull request Aug 19, 2026
…0175)

## Motivation

`ds_read_b64_tr_b16` returns incorrect results under the gfx950 (CDNA4)
simulator. The instruction performs a 4x16-lane halfword transpose:
within each 16-lane group, destination lane `l` halfword `n` comes from
source lane `((l & ~0xf) | ((l >> 2) & 3)) + 4 * n`, halfword `l & 3` —
the layout already encoded by the DBT reference in
`tests/dbt/cdna4_to_cdna3_lds_hip_test.cpp`
(`LargeStaticLdsReadB64TrB16`). The pure-simulation path's
`transpose_b16()` instead performed a 4x4 transpose within groups of 4
consecutive lanes (lane 0 received source lanes 0,1,2,3 halfword 0
instead of lanes 0,4,8,12), so every gfx950 kernel that loads bf16/f16
MFMA operands with `ds_read_b64_tr_b16` computed on wrong data under the
simulator.

## Technical Details

- `lib/rocjitsu/src/rocjitsu/isa/arch/amdgpu/shared/ds_transpose.h`:
`transpose_b16()` now handles the wave64 B64 case (4 halfwords per lane,
i.e. `ds_read_b64_tr_b16`) with the 4x16-lane stride-4 layout above.
This changes only that path; the B128 path used by gfx1250
`ds_load_tr16_b128` / `global_load_tr16_b128` and RDNA4
`global_load_tr_b128` is left byte-for-byte unchanged. `tr_b4` / `tr_b6`
/ `tr_b8` are untouched and were not hardware-verified here.
- `tests/amdgpu_vm_test.cpp`: new
`DsTransposeTest.ReadB64TrB16_LaneLayout` (CPU-only). Fills LDS with a
per-lane halfword pattern, dispatches an encoded `ds_read_b64_tr_b16` on
the `cdna4` VM fixture, and checks all 64 lanes x 4 halfwords against
the same reference formula the DBT test uses.
- `TransposeKind` is split into `TR16_B128` (gfx1250/RDNA4 B128 loads,
unchanged) and `B64_TR_B16` (CDNA4 `ds_read_b64_tr_b16`), emitted from
`InstructionSemantics`; `transpose_response()` dispatches on the kind.

## Issue Tracking

No existing GitHub issue. Related: #6829 (AccVGPR `acc` bit handling for
the same DS transpose reads).

## Test Plan

- `ctest` / `rocjitsu_tests --gtest_filter='DsTransposeTest.*'` for the
new CPU-side layout test, before and after the `transpose_b16()` change.
- Existing test suite for regressions.

## Test Result

- `DsTransposeTest.ReadB64TrB16_LaneLayout`: built and run locally (CPU
only, GCC 13, Release): fails on the pre-change `transpose_b16()` with
128 mismatches (64 lanes x 2 dwords; e.g. lane 0 low dword 0x12111200 vs
expected 0x12441200) and passes after.
- Cross-checked on gfx950 hardware (ROCm 7.2.0) with an equivalent
inline-asm `ds_write_b64`/`ds_read_b64_tr_b16` kernel: hardware matches
the expected layout; the simulator matched only after this change (all
64 lanes differed before).
- Full `ctest` shows no status changes versus `develop` other than the
added `DsTransposeTest.ReadB64TrB16_LaneLayout`.

## Submission Checklist

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

(cherry picked from commit 95b6c41)
atgutier added a commit that referenced this pull request Aug 20, 2026
…t calls (#10444)

## Motivation

hipTensor and rocThrust gfx1250 objects are refused at code-object load
time with "indirect branch or call target recovery is not implemented
for relocated kernel text" on `s_swap_pc_i64`. A refused object leaves
HIP holding an invalid kernel
handle, so the failure surfaces as a segfault rather than a diagnostic.
The fix is upstream as #10376; this backports it to
`release/bkc/therock-10.1-20260811`.

## Commits Cherry-Picked

  | # | Upstream | PR | Backport | Subject |
  |---|----------|-----|----------|---------|
| 1 | `b6d838028e` | #10197 | `846fb16d12` | [rocjitsu][docs] Refresh
architecture support documentation |
| 2 | `5c8e33e391` | #10200 | `db5c58b1be` | [rocjitsu] Define
standalone decoder ownership |
| 3 | `be1f91998f` | #10199 | `ed102baf1c` | [rocjitsu] Apply async
IOFFSET to LDS addresses |
| 4 | `fda635e5b4` | — | `ad32ff7c18` | [rocjitsu] Extract per-scope
rollback and object-level checks from translate() |
| 5 | `8f75eb781e` | — | `4c0cb05207` | [rocjitsu] Emit leading V_NOPs
ahead of a gfx1250 MODE write |
| 6 | `00aa1e260f` | #9941 | `ded43b1787` | fix(rocjitsu): disable
zero-count TDM descriptors |
| 7 | `c810647609` | #10192 | `50ca7f1732` | [rocjitsu] Apply MUBUF
LDS-load instruction offset to the LDS address |
| 8 | `1d7866269d` | #9560 | `2e6bf26943` | [rocjitsu] code rewrite
condition validator |
| 9 | `95b6c410bb` | #10175 | `8418901076` | [rocjitsu] Fix
ds_read_b64_tr_b16 lane layout in gfx950 simulator |
| 10 | `bfaebcfb5c` | #10240 | `c4eac1e1f7` | [rocjitsu][util] Add
result and diagnostic utilities |
| 11 | `dbb7221fa7` | #9775 | `cdd0993a5f` | fix(rocjitsu): route tensor
DMA through wave VMID |
| 12 | `2779247222` | #9779 | `7bfeba6f5d` | feat(rocjitsu): Lazy vgpr
allocation system |
| 13 | `a659172a31` | #9936 | `180cf00325` | fix(rocjitsu): honor TDM
tensor bounds across iterations |
| 14 | `60c29efb39` | #10204 | `370bfb9796` | [rocjitsu] Fix gfx950
decoder extension handling |
| 15 | `c1dba564e7` | #10345 | `536110a083` | [rocjitsu] Model gfx1250
wave ABI state |
| 16 | `7f71be9f32` | #10346 | `3f922ad5f2` | [rocjitsu] Model gfx1250
barrier synchronization |
| 17 | `bea7ac8937` | #10368 | `7b5ecf6c7b` | [rocjitsu] Replace decoder
exceptions with results |
| 18 | `f2e878694e` | #10371 | `8cf750d23f` | [rocjitsu] Dispatch
operand validation by type |
| 19 | `dd619bed77` | #9735 | `1a612c47c0` | fix(rocjitsu): respect
same-wave LDS ordering |
| 20 | `c5fae8d2b2` | #10137 | `4360c4b978` | [rocjitsu] Rename gfx1250
to cdna5 for enums, configs, amdisa codegen helpers and generated
symbols. (NFC) |
| 21 | `b05a587f89` | #10274 | `bfb5f9fab0` | [rocjitsu] Align CDNA4
MI350X configs with captured topology |
| 22 | `f81f9d40db` | #10362 | `8177b5725c` | feat(rocjitsu): cdna5 OOB
behavior implementation |
| 23 | `53a939bd00` | #10283 | `141b109432` | [rocjitsu] add per-XCD
workgroup dispatch observability |
| 24 | `a0fb11bc17` | #10414 | `6bb4c5a959` | [rocjitsu] Refactor test
encoding handling in execution tests (NFC) |
| 25 | `e5109e315e` | #9844 | `322ac26b44` | feat(emulation): debug
emulated GPU kernels with real ROCgdb |
| 26 | `efa24f23c9` | — | `c3c9641073` | rocjitsu: Point the XCD
distribution test at the config that exists |
| 27 | `8b7763ef5e` | #10376 | `c3f419555a` | [rocjitsu] Translate
gfx1250 lane-banked and kernarg-supplied indirect calls |

## Issue Tracking

[ROCM-29436]

## Submission Checklist

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


[ROCM-29346]:
https://amd-hub.atlassian.net/browse/ROCM-29346?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ

[ROCM-29436]:
https://amd-hub.atlassian.net/browse/ROCM-29436?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ

---------

Signed-off-by: Tony Gutierrez <anthony.gutierrez@amd.com>
Signed-off-by: hanhanW <hanhan0912@gmail.com>
Co-authored-by: Jakub Kuderski <jakub@nod-labs.com>
Co-authored-by: James Newling <james.newling@gmail.com>
Co-authored-by: Fei Kou <feikou@meta.com>
Co-authored-by: Austin Lu <austin.lu@amd.com>
Co-authored-by: Fei Kou <feikou@anthropic.com>
Co-authored-by: Erick Ochoa Lopez <eochoalo@amd.com>
Co-authored-by: Han-Chung Wang <hanhan0912@gmail.com>
Co-authored-by: Rosa, Ada <arosa@amd.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.

3 participants