Skip to content

feat(rccl): add fp8 (e4m3, e5m2) support to DDA collectives - #13311

Merged
alex-breslow-amd merged 4 commits into
developfrom
users/abreslow/ddaFP8
Oct 19, 2026
Merged

alex-breslow-amd merged 4 commits into
developfrom
users/abreslow/ddaFP8

Conversation

@alex-breslow-amd

@alex-breslow-amd alex-breslow-amd commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

Motivation

The DDA collectives (AllReduce, ReduceScatter, AllGather, AlltoAll) accepted only fp32, fp16 and bf16, so fp8 traffic fell back to the ring/tree kernels even at sizes where DDA serves the other types. This adds ncclFloat8e4m3 and ncclFloat8e5m2 to the DDA fabric tiers (VMM, LL, LL128) on gfx1250. Other architectures, and the IPC tier (gfx942/gfx950 only), keep rejecting fp8 and are left for a follow-up.

Technical Details

  • Datatype gate. The fp32/fp16/bf16 check repeated across the DDA fabric launchers is replaced by one helper, rcclDdaDatatypeSupported(comm, datatype) in rccl_wrap.cc. It admits both fp8 types only when comm->archName matches gfx1250, a prefix match that also covers gfx1250 strict.
  • Copy collectives (AllGather, AlltoAll) already move raw bytes as int8_t, so only the gate changes.
  • Reducing collectives (AllReduce, ReduceScatter) dispatch fp8 to kernels instantiated on new one-byte tags, dda::common::fp8e4m3 / fp8e5m2. rccl_float8 / rccl_bfloat8 are not used as template arguments because they name different types in the host pass and the gfx942 device pass (FNUZ vs OCP), which would register kernels under names the gfx942 code object lacks.
  • pk8 reduction. fp8 adds use the pk8 hadd8 / hadd8_b helpers from perf(rccl): pk8 fp8/bf8 sum reduction on gfx1250 #13415 (v_cvt_scale_pk8_f32_* + v_cvt_scalef32_pk8_*_f32), 8 bytes per call, through a new vecElementAddFp8x8. The LL payload add, the LL128 word add, and the 16-byte VMM add all go through it. On other architectures the fp8 instantiations compile to a trap; the gate keeps them from being launched.
  • Deterministic one-shot AllReduce. The LL and LL128 one-shot kernels used to start from the local input and add peers in (selfRank + r) % nRanks order, so ranks rounded differently and could disagree in the last bit. They now add all ranks in global rank order, so every rank computes the same result. This applies to all datatypes.

Issue Tracking

JIRA ID: AICOMRCCL-2915

Test Plan

On a single node with 4x gfx1250 (UALoE fabric), RCCL built with --amdgpu_targets gfx1250:

  1. rccl-tests, one process driving 4 GPUs (-g 4 -c 1 -A 1), out-of-place and in-place:
    • AllReduce and ReduceScatter x {fp8_e4m3, fp8_e5m2}, 256 B to 64 MB, default settings.
    • AllReduce and ReduceScatter x {fp8_e4m3, fp8_e5m2}, 1 KB to 4 MB, under each tier setting:
      • RCCL_DDA_LL_ONESHOT_THRESHOLD=0 (LL two-shot)
      • RCCL_DDA_LL_THRESHOLD=0 (LL128)
      • RCCL_DDA_LL_THRESHOLD=0 RCCL_DDA_LL128_ONESHOT_THRESHOLD=0 (LL128 two-shot)
      • RCCL_DDA_LL=0 RCCL_DDA_THRESHOLD=67108864 (fabric VMM)
    • All four collectives x fp8_e4m3, 1 KB to 64 MB, default and RCCL_DDA_ENABLE=0.
  2. Exhaustive add check (DdaVecElementAdd.Fp8*): rccl-tests picks inputs whose sums are exact in any order, so it validates data movement but not rounding. A kernel feeds all 65,536 fp8 byte pairs through ddaLLAddPayload and ddaLL128AddWord (8 lanes each) and the 16-byte vecElementAdd (16 lanes), and compares every result bit-for-bit with core RCCL's hadd2 / hadd2_b, for both formats. It skips on non-gfx1250 devices. The hadd8 / hadd8_b math itself, including the E8M0 scale, is covered by perf(rccl): pk8 fp8/bf8 sum reduction on gfx1250 #13415's Fp8ReduceTest.*, which this PR adds to the standard fixtures category.
  3. Eligibility tests (DdaFabricEligibilityTest.*, DdaFabricLL128EligibilityTest.*): fp8 is admitted on gfx1250 and rejected on gfx950 / gfx942 and for a null comm, for every fabric gate.
  4. Full build for gfx1250 (release and debug); device compile of the DDA fabric kernels for gfx942 and gfx950.
  5. Performance: rccl-tests with one thread per GPU and HIP graphs (-t 4 -g 1 -G 10 -n 20 -w 5 -c 1), 1 KB to 64 MB, default vs RCCL_DDA_ENABLE=0. fp8_e4m3 for all four collectives, plus bf16 AllReduce and ReduceScatter as a control. Three interleaved rounds; each figure is the median. A single thread driving all four GPUs (-g 4) serializes their launches and hides DDA's advantage for every datatype, so it is not used.

Test Result

  • rccl-tests: 0 wrong in every run. The -A 1 column shows DDA LL, LL128, and SIMPLE (VMM setting) serving fp8 in both formats; the AlltoAll rows above the DDA cap fall back to Direct.

  • Exhaustive add check: 0 mismatches for e4m3 and e5m2 in all three helpers. Swapping the e4m3 and e5m2 pk8 adds makes it fail at every width. Fp8ReduceTest.*: 15/15 pass.

  • Eligibility tests: pass. Two AllGather threshold tests (AllGatherLL_PastThresholdRejected, AllGatherLL128_PastThresholdRejected) fail the same way on develop.

  • gfx1250 disassembly of the fp8 kernels contains only pk8 conversions.

  • Performance: time saved by DDA relative to RCCL_DDA_ENABLE=0, as 1 - DDA time / non-DDA time, out-of-place. In-place is within a few points.

    1 KB - 1 MB 4 MB 16 MB 64 MB
    fp8 AllReduce 73-86% 38% 22% 2%
    fp8 ReduceScatter 51-54% 48% 26% 29%
    fp8 AllGather 54-77% 68% 18% 3%
    fp8 AlltoAll 14-85% not DDA not DDA not DDA
    bf16 AllReduce (control) 73-86% 54% 33% 22%
    bf16 ReduceScatter (control) 51-53% 61% 43% 36%

    Rounds varied by less than 5% in most cells (worst 19%, fp8 AllReduce at 16 MB). Up to 1 MB fp8 gains as much as bf16. From 4 MB up it gains less, and at 64 MB fp8 AllReduce and AllGather are about even with the non-DDA path; tuning the fp8 thresholds is left for a follow-up. AlltoAll above 1 MB is outside DDA's cap on both sides. e5m2 was not timed; it runs the same kernels with a different conversion instruction.

  • Not covered: DdaFp8MPITests (no MPI on this node), and fp8 AllGather/AlltoAll in e5m2 or under the forced tier settings.

Submission Checklist

@therock-pr-bot

therock-pr-bot Bot commented Oct 12, 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?

@therock-pr-bot

Copy link
Copy Markdown

🚫 Please fix the failed policies before requesting reviews.

The following policy checks failed:

  • ❌ PR Description

The Not ready to Review label has been added to this PR.
Once all policies pass, the label will be removed automatically.

@amd-argus

amd-argus Bot commented Oct 12, 2026

Copy link
Copy Markdown
Contributor

@cppccppccppc @sunguobao PTAL

1 similar comment
@amd-argus

amd-argus Bot commented Oct 13, 2026

Copy link
Copy Markdown
Contributor

@cppccppccppc @sunguobao PTAL

@mustafabar mustafabar 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, however, as suggested below, please restrict the support to gfx1250. We can extend support to previous platforms in a future PR so that this is smaller and more self-contained.
Also, your reduction is happening at dword granularity and it could be done better using pk8 instructions. I suspect the ROI maybe limited for smaller messages, so we can consider this for a future PR. My PR applies the pk8 instructions on the vanilla path #13415

@alex-breslow-amd
alex-breslow-amd marked this pull request as ready for review October 19, 2026 13:35
@alex-breslow-amd
alex-breslow-amd requested review from a team and a balanced review from Copilot October 19, 2026 13:35

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.

🟡 Changes recommended

The new tests have unresolved kernel-registration, MPI failure-coordination, and cached-tier isolation defects.

3 open issues
What changed in this PR

Adds both fp8 formats to RCCL’s DDA collectives across IPC, fabric VMM, LL, and LL128 tiers.

Changes:

  • Centralizes datatype eligibility and adds fp8 reduction dispatch.
  • Implements packed fp8 addition using stable kernel tags.
  • Adds eligibility, arithmetic, and MPI integration tests.
File Description
projects/​rccl/​test/​DdaIpcEligibilityTests.cpp Tests IPC fp8 eligibility and dispatch.
projects/​rccl/​test/​DdaFp8MPITests.cpp Adds fabric-tier fp8 integration tests.
projects/​rccl/​test/​DdaFabricEligibilityTests.cpp Tests fabric fp8 eligibility and dispatch.
projects/​rccl/​test/​DdaCollCommonTests.cpp Adds exhaustive fp8 addition checks.
projects/​rccl/​test/​common/​DdaFp8TestHelpers.hpp Shares eligibility and dispatch test helpers.
projects/​rccl/​test/​CMakeLists.txt Includes fp8 MPI test sources.
projects/​rccl/​src/​include/​rccl_common.h Centralizes supported DDA datatypes.
projects/​rccl/​src/​algorithms/​dda/​reduce_scatter/​dda_reduce_scatter_ipc.cu Enables IPC fp8 reduction dispatch.
projects/​rccl/​src/​algorithms/​dda/​reduce_scatter/​dda_reduce_scatter_fabric.cu Enables VMM fp8 reduction dispatch.
projects/​rccl/​src/​algorithms/​dda/​reduce_scatter/​dda_reduce_scatter_fabric_ll128.cu Enables LL128 fp8 reduction dispatch.
projects/​rccl/​src/​algorithms/​dda/​reduce_scatter/​dda_reduce_scatter_fabric_ll.cu Enables LL fp8 reduction dispatch.
projects/​rccl/​src/​algorithms/​dda/​device/​CollCommon.h Adds stable fp8 tags and packed addition.
projects/​rccl/​src/​algorithms/​dda/​device/​CollCommon_ll128.h Documents fp8 payload packing.
projects/​rccl/​src/​algorithms/​dda/​alltoall/​dda_alltoall_ipc.cu Admits fp8 IPC copies.
projects/​rccl/​src/​algorithms/​dda/​alltoall/​dda_alltoall_fabric.cu Admits fp8 VMM copies.
projects/​rccl/​src/​algorithms/​dda/​alltoall/​dda_alltoall_fabric_ll128.cu Admits fp8 LL128 copies.
projects/​rccl/​src/​algorithms/​dda/​alltoall/​dda_alltoall_fabric_ll.cu Admits fp8 LL copies.
projects/​rccl/​src/​algorithms/​dda/​all_reduce/​dda_all_reduce_ipc.cu Enables IPC fp8 reduction dispatch.
projects/​rccl/​src/​algorithms/​dda/​all_reduce/​dda_all_reduce_fabric.cu Enables VMM fp8 reduction dispatch.
projects/​rccl/​src/​algorithms/​dda/​all_reduce/​dda_all_reduce_fabric_ll.cu Enables fp8 LL/LL128 reduction variants.
projects/​rccl/​src/​algorithms/​dda/​all_gather/​dda_all_gather_ipc.cu Admits fp8 IPC copies.
projects/​rccl/​src/​algorithms/​dda/​all_gather/​dda_all_gather_fabric.cu Admits fp8 VMM copies.
projects/​rccl/​src/​algorithms/​dda/​all_gather/​dda_all_gather_fabric_ll128.cu Admits fp8 LL128 copies.
projects/​rccl/​src/​algorithms/​dda/​all_gather/​dda_all_gather_fabric_ll.cu Admits fp8 LL copies.

Review effort: Balanced

Comment thread projects/rccl/test/DdaFp8MPITests.cpp Resolved
Comment thread projects/rccl/test/DdaFp8MPITests.cpp Resolved

@amd-argus amd-argus Bot 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.

ARGUS

Findings

5 more finding(s), not posted inline
  • projects/rccl/test/DdaFp8MPITests.cpp:127 (Low) DdaFp8MPI fixtures rely on a comment for one-process-per-fixture; RCCL_PARAM caching fails later fixtures in an unfiltered run
  • projects/rccl/test/DdaCollCommonTests.cpp:37 (Low) Fp8*AddMatchesCoreForAllPairs compares hadd2 with hadd2 on every arch except gfx942/gfx1250, so rounding parity is only checked there
  • projects/rccl/test/DdaFabricEligibilityTests.cpp:1550 (Low) DdaDatatypeSupportTest.AdmitsFloatTypesAndBothFp8Formats restates the rcclDdaDatatypeSupported switch line for line
  • projects/rccl/src/algorithms/dda/all_reduce/dda_all_reduce_fabric_ll128.cu:154 (Low) Uncalled ncclAllReduceDdaFabricLL128Eligible_old / _old dispatcher still carry the old fp32/fp16/bf16 list In dda_all_reduce_fabric_ll128.cu (outside the diff), ncclAllReduceDdaFabricLL128Eligible_old at line 154 and ncclAllReduceDdaFabricLL128_old at lines 185-198 keep the pre-rcclDdaDatatypeSupported type list and have no callers in the tree. Worth a follow-up to delete them so a stale copy of the list does not linger.
  • projects/rccl/test/DdaFp8MPITests.cpp:73 (Low) isGfx1250Device() is now copied verbatim in three DDA MPI test files

This PR changes 1,123 lines across 24 files. A change this size is hard to review
well, for a person and for this bot alike: reviewers lose the thread, defects hide in the
volume, and the feedback arrives too late to be cheap to act on. Splitting it into a
stacked pull request
gives each piece a reviewable diff and keeps the history. This review covers the whole change
regardless.

Bottom line: Worth settling before approval: fp8AddFloatsKernel is instantiated on rccl_float8 / rccl_bfloat8, so the ExactSums tests cannot find their kernel on gfx942 runners where DdaCollCommon.* runs.

Comment @argus review to re-run, or @argus re-review after pushing.

Comment thread projects/rccl/test/DdaFp8MPITests.cpp Resolved
Comment thread projects/rccl/test/CMakeLists.txt Resolved
- Admit fp8 e4m3/e5m2 only on gfx1250 (incl. strict) via
  rcclDdaDatatypeSupported(comm, datatype); revert the IPC tier
  (gfx942/gfx950) to develop.
- Reduce fp8 with the pk8 hadd8/hadd8_b intrinsics, 8 bytes per op,
  in the LL, LL128, and VMM fabric kernels; drop the hadd2 path.
- Sum peers in global rank order in the LL and LL128 one-shot
  AllReduce kernels so every rank produces identical results.
- Tests: tag-templated fp8 kernels with exhaustive lane checks against
  hadd2/hadd2_b, arch-gate eligibility tests, and a
  DdaFabricMPITest-based fp8 MPI fixture with per-tier categories.

Co-authored-by: Cursor <cursoragent@cursor.com>
@alex-breslow-amd

Copy link
Copy Markdown
Contributor Author

Thanks. Both are done in this PR: fp8 is admitted only on gfx1250 (including strict), and the reductions use the pk8 helpers from #13415. gfx942/gfx950 will follow separately.

- Move the all-pairs DDA fp8 add check into the existing DdaVecElementAdd
  suite, on DeviceTestBase's buffer and launch helpers, and restore
  DdaCollCommonTests.cpp to develop.
- Drop the DDA exact-sums tests: they call the same hadd8 / hadd8_b that
  Fp8ReduceTest.ExactSmallSums* already pins.
- Share isGfx1250() on DeviceTestBase instead of a per-file copy in
  TestFp8Reduce.cpp.
- Add Fp8ReduceTest.* to the standard fixtures category.

Co-authored-by: Cursor <cursoragent@cursor.com>

@amd-argus amd-argus Bot 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.

ARGUS

This PR changes 1,211 lines across 28 files. A change this size is hard to review
well, for a person and for this bot alike: reviewers lose the thread, defects hide in the
volume, and the feedback arrives too late to be cheap to act on. Splitting it into a
stacked pull request
gives each piece a reviewable diff and keeps the history. This review covers the whole change
regardless.

Bottom line: Worth settling before approval: rcclDdaDatatypeSupported sends fp8 on gfx1250 to DDA by default, and there is no fp8-specific opt-in (rccl_wrap.cc:1212). The fp8 MPI tests are also missing from the gfx1250 runner configs.

Comment @argus review to re-run, or @argus re-review after pushing.

Comment thread projects/rccl/src/rccl_wrap.cc Resolved
@alex-breslow-amd
alex-breslow-amd merged commit 77544dc into develop Oct 19, 2026
70 of 75 checks passed
@alex-breslow-amd
alex-breslow-amd deleted the users/abreslow/ddaFP8 branch October 19, 2026 23:53
pvallem added a commit that referenced this pull request Oct 20, 2026
#13311 already folds the LL and LL128 one-shot AllReduce in rank order.
Take develop's all_reduce_dda_ll.h as is. In all_reduce_dda_ll128.h keep
develop's file and replace only the reduce loop with the one that loads the
own slice first and seeds from rank 0, which keeps the NRANKS_CT=8 float and
half kernels out of VGPR spills (develop: 128 VGPRs, 27 spilled).
aduforest added a commit that referenced this pull request Oct 20, 2026
#13311 moved the DDA fabric launchers' datatype check into
rcclDdaDatatypeSupported() in rccl_wrap.cc and added fp8 dispatch to the
reducing launchers. Seam the gate (default mirrors rccl_wrap.cc), check
each fabric eligibility defers to it, and pin the fp8 e4m3/e5m2 kernels.

Co-Authored-By: Claude <noreply@anthropic.com>
@systems-assistant

Copy link
Copy Markdown
Contributor

TheRock Submodule Bump Activity

Newest first

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