Skip to content

fix(rccl): replace __hip_atomic builtins with Clang scoped atomics - #11321

Merged
alex-breslow-amd merged 5 commits into
rccl-developfrom
users/abreslow/scoped_atomics-rccl-develop
Sep 9, 2026
Merged

alex-breslow-amd merged 5 commits into
rccl-developfrom
users/abreslow/scoped_atomics-rccl-develop

Conversation

@alex-breslow-amd

@alex-breslow-amd alex-breslow-amd commented Sep 8, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • Retarget of the scoped-atomics work onto rccl-develop (see also fix(rccl): replace deprecated __hip_atomic builtins with __scoped_atomic #11316 against develop).
  • Device atomics now use Clang __scoped_atomic_* / __atomic_* instead of __hip_atomic_*, with explicit memory scopes.
  • Adds a compile-time poison (RCCL_POISON_HIP_ATOMICS, default ON) and a host-test CI probe that __hip_atomic_load and the rest of the __hip_atomic_* builtins fail to compile in RCCL sources.

src/algorithms/gin/sdma/all_reduce_gin_sdma.h is gone on rccl-develop, so those five call-site edits from the develop PR are omitted here.

Remaining __hip_atomic_* coverage

There are no remaining __hip_atomic_* call sites in RCCL sources after this PR. The only remaining hits are the poison header, the CI probe, and comments.

HIP wrapper APIs that still go through __hip_atomic_* inside HIP headers are still present. Those compile with the poison because HIP parses them before the pragma, so they are the remaining way __hip_atomic_* can still land in librccl.so:

API Where
atomicAdd prims_ll.h, prims_simple.h, gin_anvil_sdma.h, gin_rocshmem_gda.h, llx_latency_bench.c
atomicMax prims_simple.h
atomicCAS DOCA verbs headers under src/transport/net_ib/gdaki/

Closing that gap means porting those wrappers to __scoped_atomic_* with explicit scopes. I will do that as a separate PR.

Test plan

  • ./install.sh -l still builds with poison enabled
  • python3 projects/rccl/src/include/test_poison_hip_atomics.py (or test/host/run_host_tests.sh guards)
  • Confirm a deliberate __hip_atomic_load in a device TU fails with attempt to use a poisoned identifier

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

Code wise this looks good. I wonder if there is any potential performance risk here though, or risk of older compilers / versions of ROCm that don't support __scoped_atomic_* that RCCL is supposed to support.

@alex-breslow-amd

alex-breslow-amd commented Sep 8, 2026 •

Copy link
Copy Markdown
Contributor Author

Code wise this looks good. I wonder if there is any potential performance risk here though, or risk of older compilers / versions of ROCm that don't support __scoped_atomic_* that RCCL is supposed to support.

I'll check with the compilers folks. This is a clang builtin. It's been there at least as far back as October of 2025. I saw @lfmeadow use it back then. I'll check with him.

It looks like they were added in clang15. We're on clang20. Let me check which version of ROCm used clang14. Update: It looks like we moved to clang 15 for ROCm 5.4. I think this is fine.

@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

Bottom line: Worth settling before approval: the poison probe exits 0 when no HIP compiler is found (test_poison_hip_atomics.py:117), so the guard can pass without ever probing. The 37 call-site conversions themselves check out, with no scope or memory-order drift.

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

Comment thread projects/rccl/src/CMakeLists.txt Resolved
Comment thread projects/rccl/CMakeLists.txt Resolved
The poison probe could pass without ever probing: with no HIP compiler
found, _find_cxx() returned None, every test skipped, and unittest exited
0.  Make that a failure instead, and move the checks that need no compiler
(header present, pragma contents) into their own class so they still gate
on a toolchain-less box.  RCCL_POISON_TEST_ALLOW_SKIP=1 opts out locally.

Also in the probe:
  - assert the pragma and the POISONED tuple are set-equal, so dropping a
    name from either side fails rather than silently shrinking coverage
  - compile every _call_expr() with the poison off, which is what keeps the
    per-name arity table honest for all 12 names instead of just the one
    the load tests use
  - pin the __scoped_atomic_compare_exchange_n shape for both widths; it is
    the only conversion in the port whose argument list changed
  - reformat with black

do_guards ran the two guards back to back, so under set -e a kernel-count
failure aborted the phase before the poison probe.  do_run had the same
short-circuit one level up.  Collect both with || rc=1 and return rc, the
idiom do_host_tests already uses.

The CMake comment justified the joined --include= spelling by saying
rccl-device-compile would take the path for a source file, which the
-include/-imacros branch added in this same PR contradicts.  State the
actual reason (single token, needs no cooperation from a flag forwarder)
and say why that branch is worth keeping.

Re-indent the continuation lines the rename left hanging: the callee grew
5 characters but the wrapped arguments kept their old column, and
prims_ll.h:325 ran to 121 against ColumnLimit 120.  clang-format over the
changed ranges only; ce_reduce_impl.h.in included since the pre-commit
hook matches .h$ and not .h.in.  Guard the poison pragma with clang-format
off/on -- clang-format has no notion of a line-continued #pragma and joins
it onto one ~300-column line.

Fix the header comment that said four headers were pulled in while three
were, and list RCCL_POISON_HIP_ATOMICS in the README and install.sh option
lists.
@alex-breslow-amd

alex-breslow-amd commented Sep 8, 2026 •

Copy link
Copy Markdown
Contributor Author

@amd-argus thanks — the bottom line was right, and worse than the comment says. Pushed f3e6526 addressing all 12 threads; replies are inline on each.

The guard could pass without probing

Confirmed: _find_cxx() returns None, the blanket @unittest.skipUnless skips all six tests, and unittest.main() exits 0. To see how far it goes I gutted poison_hip_atomics.h down to a bare include guard and hid the compiler — the guard still printed OK (skipped=6) and exited 0. A fully disarmed poison reported success.

The fix has two parts. A missing HIP compiler is now a failure rather than a skip (ToolchainTest), with RCCL_POISON_TEST_ALLOW_SKIP=1 to opt out when running locally without ROCm. And the checks that need no compiler — header present, pragma contents — moved into their own PoisonHeaderTest, so they still gate on a toolchain-less box instead of being swept up by the skip.

After the change, the same no-compiler run fails:

Ran 9 tests in 0.000s
FAILED (failures=1, skipped=6)     exit 1

and the gutted-header case now trips two tests, because the pragma check no longer depends on a compiler.

One finding extended

The set -e problem in do_guards was also present one level up in do_run: do_host_tests "$@" followed by do_guards, so a gtest failure dropped both guards entirely. Both now collect with || rc=1 and return rc.

Two notes back

.pre-commit-config.yaml is not the safety net it looks like for the formatting thread. It pins mirrors-clang-format v18.1.4, but projects/rccl/.clang-format uses three clang-format 21-only keys (AlignPPAndNotPP, OneLineFormatOffRegex, BreakBeforeCloseBracketBracedList), so both 18 and ROCm's own 20 refuse to parse the config outright. Pre-existing and out of scope here, but worth knowing.

On the compare_exchange thread I added the probe you asked for, but flagged in its docstring that it pins the builtin rather than hip_compat.h — it would not catch a weak/memory-order swap, since both convert to int. That gap needs a runtime test of atomic_ref, which has no host harness today.

Test evidence

  • Poison guard: 9 tests pass. Six negative scenarios each fail as intended — no compiler; gutted header; name dropped from POISONED; name dropped from the pragma; broken _call_expr arity; and RCCL_POISON_TEST_ALLOW_SKIP=1 still exits 0.
  • run_host_tests.sh guards end to end: 22 kernel-count + 9 poison tests, exit 0. Stubbed-failure runs confirm both guards report rather than short-circuit.
  • CMake configures with the poison on; --include=...poison_hip_atomics.h lands in the rccl target's CXX_FLAGS.
  • Compiled real device TUs with the poison active — common.cu.cpp, ce_reduce.cc, and common.h + all_gather.h / reduce_scatter.h (which pull in primitives.h → prims_ll.h and op128.h). A deliberate __hip_atomic_load injected into a device TU fails with attempt to use a poisoned identifier, which is the PR's own test-plan item.
  • All eight reformatted headers verified token-identical to the previous revision by whitespace-normalized comparison.
  • black --check and clang-format both clean on the changed files.

@alex-breslow-amd

Copy link
Copy Markdown
Contributor Author

@argus re-review

@alex-breslow-amd
alex-breslow-amd merged commit baec974 into rccl-develop Sep 9, 2026
38 of 40 checks passed
@alex-breslow-amd
alex-breslow-amd deleted the users/abreslow/scoped_atomics-rccl-develop branch September 9, 2026 17:21
rahulvaidya20 pushed a commit that referenced this pull request Sep 11, 2026
…11321)

- Retarget of the scoped-atomics work onto `rccl-develop` (see also
- Device atomics now use Clang `__scoped_atomic_*` / `__atomic_*`
instead of `__hip_atomic_*`, with explicit memory scopes.
- Adds a compile-time poison (`RCCL_POISON_HIP_ATOMICS`, default ON) and
a host-test CI probe that `__hip_atomic_load` and the rest of the
`__hip_atomic_*` builtins fail to compile in RCCL sources.

`src/algorithms/gin/sdma/all_reduce_gin_sdma.h` is gone on
`rccl-develop`, so those five call-site edits from the develop PR are
omitted here.

There are **no remaining `__hip_atomic_*` call sites** in RCCL sources
after this PR. The only remaining hits are the poison header, the CI
probe, and comments.

HIP wrapper APIs that still go through `__hip_atomic_*` **inside HIP
headers** are still present. Those compile with the poison because HIP
parses them **before** the pragma, so they are the remaining way
`__hip_atomic_*` can still land in `librccl.so`:

| API | Where |
|---|---|
| `atomicAdd` | `prims_ll.h`, `prims_simple.h`, `gin_anvil_sdma.h`,
`gin_rocshmem_gda.h`, `llx_latency_bench.c` |
| `atomicMax` | `prims_simple.h` |
| `atomicCAS` | DOCA verbs headers under `src/transport/net_ib/gdaki/` |

Closing that gap means porting those wrappers to `__scoped_atomic_*`
with explicit scopes. I will do that as a separate PR.

- [x] `./install.sh -l` still builds with poison enabled
- [x] `python3 projects/rccl/src/include/test_poison_hip_atomics.py` (or
`test/host/run_host_tests.sh guards`)
- [ ] Confirm a deliberate `__hip_atomic_load` in a device TU fails with
`attempt to use a poisoned identifier`
rahulvaidya20 pushed a commit that referenced this pull request Sep 11, 2026
…11321)

- Retarget of the scoped-atomics work onto `rccl-develop` (see also
- Device atomics now use Clang `__scoped_atomic_*` / `__atomic_*`
instead of `__hip_atomic_*`, with explicit memory scopes.
- Adds a compile-time poison (`RCCL_POISON_HIP_ATOMICS`, default ON) and
a host-test CI probe that `__hip_atomic_load` and the rest of the
`__hip_atomic_*` builtins fail to compile in RCCL sources.

`src/algorithms/gin/sdma/all_reduce_gin_sdma.h` is gone on
`rccl-develop`, so those five call-site edits from the develop PR are
omitted here.

There are **no remaining `__hip_atomic_*` call sites** in RCCL sources
after this PR. The only remaining hits are the poison header, the CI
probe, and comments.

HIP wrapper APIs that still go through `__hip_atomic_*` **inside HIP
headers** are still present. Those compile with the poison because HIP
parses them **before** the pragma, so they are the remaining way
`__hip_atomic_*` can still land in `librccl.so`:

| API | Where |
|---|---|
| `atomicAdd` | `prims_ll.h`, `prims_simple.h`, `gin_anvil_sdma.h`,
`gin_rocshmem_gda.h`, `llx_latency_bench.c` |
| `atomicMax` | `prims_simple.h` |
| `atomicCAS` | DOCA verbs headers under `src/transport/net_ib/gdaki/` |

Closing that gap means porting those wrappers to `__scoped_atomic_*`
with explicit scopes. I will do that as a separate PR.

- [x] `./install.sh -l` still builds with poison enabled
- [x] `python3 projects/rccl/src/include/test_poison_hip_atomics.py` (or
`test/host/run_host_tests.sh guards`)
- [ ] Confirm a deliberate `__hip_atomic_load` in a device TU fails with
`attempt to use a poisoned identifier`
rahulvaidya20 pushed a commit that referenced this pull request Sep 12, 2026
…11321)

- Retarget of the scoped-atomics work onto `rccl-develop` (see also
- Device atomics now use Clang `__scoped_atomic_*` / `__atomic_*`
instead of `__hip_atomic_*`, with explicit memory scopes.
- Adds a compile-time poison (`RCCL_POISON_HIP_ATOMICS`, default ON) and
a host-test CI probe that `__hip_atomic_load` and the rest of the
`__hip_atomic_*` builtins fail to compile in RCCL sources.

`src/algorithms/gin/sdma/all_reduce_gin_sdma.h` is gone on
`rccl-develop`, so those five call-site edits from the develop PR are
omitted here.

There are **no remaining `__hip_atomic_*` call sites** in RCCL sources
after this PR. The only remaining hits are the poison header, the CI
probe, and comments.

HIP wrapper APIs that still go through `__hip_atomic_*` **inside HIP
headers** are still present. Those compile with the poison because HIP
parses them **before** the pragma, so they are the remaining way
`__hip_atomic_*` can still land in `librccl.so`:

| API | Where |
|---|---|
| `atomicAdd` | `prims_ll.h`, `prims_simple.h`, `gin_anvil_sdma.h`,
`gin_rocshmem_gda.h`, `llx_latency_bench.c` |
| `atomicMax` | `prims_simple.h` |
| `atomicCAS` | DOCA verbs headers under `src/transport/net_ib/gdaki/` |

Closing that gap means porting those wrappers to `__scoped_atomic_*`
with explicit scopes. I will do that as a separate PR.

- [x] `./install.sh -l` still builds with poison enabled
- [x] `python3 projects/rccl/src/include/test_poison_hip_atomics.py` (or
`test/host/run_host_tests.sh guards`)
- [ ] Confirm a deliberate `__hip_atomic_load` in a device TU fails with
`attempt to use a poisoned identifier`
rahulvaidya20 pushed a commit that referenced this pull request Sep 12, 2026
…11321)

- Retarget of the scoped-atomics work onto `rccl-develop` (see also
- Device atomics now use Clang `__scoped_atomic_*` / `__atomic_*`
instead of `__hip_atomic_*`, with explicit memory scopes.
- Adds a compile-time poison (`RCCL_POISON_HIP_ATOMICS`, default ON) and
a host-test CI probe that `__hip_atomic_load` and the rest of the
`__hip_atomic_*` builtins fail to compile in RCCL sources.

`src/algorithms/gin/sdma/all_reduce_gin_sdma.h` is gone on
`rccl-develop`, so those five call-site edits from the develop PR are
omitted here.

There are **no remaining `__hip_atomic_*` call sites** in RCCL sources
after this PR. The only remaining hits are the poison header, the CI
probe, and comments.

HIP wrapper APIs that still go through `__hip_atomic_*` **inside HIP
headers** are still present. Those compile with the poison because HIP
parses them **before** the pragma, so they are the remaining way
`__hip_atomic_*` can still land in `librccl.so`:

| API | Where |
|---|---|
| `atomicAdd` | `prims_ll.h`, `prims_simple.h`, `gin_anvil_sdma.h`,
`gin_rocshmem_gda.h`, `llx_latency_bench.c` |
| `atomicMax` | `prims_simple.h` |
| `atomicCAS` | DOCA verbs headers under `src/transport/net_ib/gdaki/` |

Closing that gap means porting those wrappers to `__scoped_atomic_*`
with explicit scopes. I will do that as a separate PR.

- [x] `./install.sh -l` still builds with poison enabled
- [x] `python3 projects/rccl/src/include/test_poison_hip_atomics.py` (or
`test/host/run_host_tests.sh guards`)
- [ ] Confirm a deliberate `__hip_atomic_load` in a device TU fails with
`attempt to use a poisoned identifier`
abchoudh-amd pushed a commit that referenced this pull request Sep 16, 2026
…11321)

- Retarget of the scoped-atomics work onto `rccl-develop` (see also
- Device atomics now use Clang `__scoped_atomic_*` / `__atomic_*`
instead of `__hip_atomic_*`, with explicit memory scopes.
- Adds a compile-time poison (`RCCL_POISON_HIP_ATOMICS`, default ON) and
a host-test CI probe that `__hip_atomic_load` and the rest of the
`__hip_atomic_*` builtins fail to compile in RCCL sources.

`src/algorithms/gin/sdma/all_reduce_gin_sdma.h` is gone on
`rccl-develop`, so those five call-site edits from the develop PR are
omitted here.

There are **no remaining `__hip_atomic_*` call sites** in RCCL sources
after this PR. The only remaining hits are the poison header, the CI
probe, and comments.

HIP wrapper APIs that still go through `__hip_atomic_*` **inside HIP
headers** are still present. Those compile with the poison because HIP
parses them **before** the pragma, so they are the remaining way
`__hip_atomic_*` can still land in `librccl.so`:

| API | Where |
|---|---|
| `atomicAdd` | `prims_ll.h`, `prims_simple.h`, `gin_anvil_sdma.h`,
`gin_rocshmem_gda.h`, `llx_latency_bench.c` |
| `atomicMax` | `prims_simple.h` |
| `atomicCAS` | DOCA verbs headers under `src/transport/net_ib/gdaki/` |

Closing that gap means porting those wrappers to `__scoped_atomic_*`
with explicit scopes. I will do that as a separate PR.

- [x] `./install.sh -l` still builds with poison enabled
- [x] `python3 projects/rccl/src/include/test_poison_hip_atomics.py` (or
`test/host/run_host_tests.sh guards`)
- [ ] Confirm a deliberate `__hip_atomic_load` in a device TU fails with
`attempt to use a poisoned identifier`
dlamd1dai pushed a commit to dlamd1dai/rocm-systems that referenced this pull request Sep 16, 2026
…OCm#11321)

- Retarget of the scoped-atomics work onto `rccl-develop` (see also
- Device atomics now use Clang `__scoped_atomic_*` / `__atomic_*`
instead of `__hip_atomic_*`, with explicit memory scopes.
- Adds a compile-time poison (`RCCL_POISON_HIP_ATOMICS`, default ON) and
a host-test CI probe that `__hip_atomic_load` and the rest of the
`__hip_atomic_*` builtins fail to compile in RCCL sources.

`src/algorithms/gin/sdma/all_reduce_gin_sdma.h` is gone on
`rccl-develop`, so those five call-site edits from the develop PR are
omitted here.

There are **no remaining `__hip_atomic_*` call sites** in RCCL sources
after this PR. The only remaining hits are the poison header, the CI
probe, and comments.

HIP wrapper APIs that still go through `__hip_atomic_*` **inside HIP
headers** are still present. Those compile with the poison because HIP
parses them **before** the pragma, so they are the remaining way
`__hip_atomic_*` can still land in `librccl.so`:

| API | Where |
|---|---|
| `atomicAdd` | `prims_ll.h`, `prims_simple.h`, `gin_anvil_sdma.h`,
`gin_rocshmem_gda.h`, `llx_latency_bench.c` |
| `atomicMax` | `prims_simple.h` |
| `atomicCAS` | DOCA verbs headers under `src/transport/net_ib/gdaki/` |

Closing that gap means porting those wrappers to `__scoped_atomic_*`
with explicit scopes. I will do that as a separate PR.

- [x] `./install.sh -l` still builds with poison enabled
- [x] `python3 projects/rccl/src/include/test_poison_hip_atomics.py` (or
`test/host/run_host_tests.sh guards`)
- [ ] Confirm a deliberate `__hip_atomic_load` in a device TU fails with
`attempt to use a poisoned identifier`
alex-breslow-amd added a commit that referenced this pull request Sep 26, 2026
## Summary

Fixes a potentially serious semantic bug in the codebase that previously
required the compiler to fuse two adjacent 8-byte accesses into a single
16-byte access per lane. Instead, explicitly use 16-byte operations for
most datatypes.

* Add `loadLLLine` / `storeLLLine` helpers in `prims_ll.h`, mirroring
the LL128 `load128NT` / `store128Plain` approach
* Replace paired 64-bit nontemporal loads and plain stores in LL FIFO
access (`readLL`, `readLLBeginAll`, `readLLFinish`, `storeLL`) with
single explicit `v4u` vector operations
* Make `ncclLLFifoLine` always carry a `v4u` view so the helpers have
one layout to work against
* Preserve the GFX11 inline-asm b128 path, the gfx1250 system-scope path
(`RCCL_LL_FIFO_SYS_SCOPE`, added to `develop` since this PR was opened),
and the gfx1200/gfx1201 store fallback, which now uses
`__scoped_atomic_store_n` to match `develop` after #11321

On the legacy (non-`RCCL_LL_FIFO_SYS_SCOPE`) paths, a single explicit
128-bit op removes the dependence on the backend fusing two independent
64-bit nontemporal ops into one 16-byte access, and keeps the data and
flag words of a line in one memory transaction.

## Jira
JIRA ID: ROCM-31751

## Test plan

* [x] Release build on gfx950, gfx1201 and gfx1100 with ROCm 7.0.2
(`ONLY_FUNCS="AllReduce RING LL Sum f32|SendRecv"`): `librccl.so` and
`rcclras` link with no new diagnostics. These three targets cover the
`RCCL_HAVE_GLOBAL_DWORDX4_BUILTINS` vector path, the gfx1200/gfx1201
scoped-atomic store fallback, and the `__GFX11__` inline-asm arm
respectively.
* [ ] gfx1250 build: not covered locally (needs ROCm 7.1.x). The
`RCCL_LL_FIFO_SYS_SCOPE` arm that gfx1250 selects is unchanged by this
PR.
* [ ] LL protocol collectives on gfx942/gfx950/gfx1250
* [ ] Verify assembly emits `global_load/store_dwordx4` rather than
paired flat/dword ops on the HIP paths

Made with Cursor

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Praneeth Vallem <pvallem@amd.com>
corey-derochie-amd pushed a commit that referenced this pull request Oct 14, 2026
…11321)

- Retarget of the scoped-atomics work onto `rccl-develop` (see also
- Device atomics now use Clang `__scoped_atomic_*` / `__atomic_*`
instead of `__hip_atomic_*`, with explicit memory scopes.
- Adds a compile-time poison (`RCCL_POISON_HIP_ATOMICS`, default ON) and
a host-test CI probe that `__hip_atomic_load` and the rest of the
`__hip_atomic_*` builtins fail to compile in RCCL sources.

`src/algorithms/gin/sdma/all_reduce_gin_sdma.h` is gone on
`rccl-develop`, so those five call-site edits from the develop PR are
omitted here.

There are **no remaining `__hip_atomic_*` call sites** in RCCL sources
after this PR. The only remaining hits are the poison header, the CI
probe, and comments.

HIP wrapper APIs that still go through `__hip_atomic_*` **inside HIP
headers** are still present. Those compile with the poison because HIP
parses them **before** the pragma, so they are the remaining way
`__hip_atomic_*` can still land in `librccl.so`:

| API | Where |
|---|---|
| `atomicAdd` | `prims_ll.h`, `prims_simple.h`, `gin_anvil_sdma.h`,
`gin_rocshmem_gda.h`, `llx_latency_bench.c` |
| `atomicMax` | `prims_simple.h` |
| `atomicCAS` | DOCA verbs headers under `src/transport/net_ib/gdaki/` |

Closing that gap means porting those wrappers to `__scoped_atomic_*`
with explicit scopes. I will do that as a separate PR.

- [x] `./install.sh -l` still builds with poison enabled
- [x] `python3 projects/rccl/src/include/test_poison_hip_atomics.py` (or
`test/host/run_host_tests.sh guards`)
- [ ] Confirm a deliberate `__hip_atomic_load` in a device TU fails with
`attempt to use a poisoned identifier`
corey-derochie-amd pushed a commit that referenced this pull request Oct 15, 2026
…11321)

- Retarget of the scoped-atomics work onto `rccl-develop` (see also
- Device atomics now use Clang `__scoped_atomic_*` / `__atomic_*`
instead of `__hip_atomic_*`, with explicit memory scopes.
- Adds a compile-time poison (`RCCL_POISON_HIP_ATOMICS`, default ON) and
a host-test CI probe that `__hip_atomic_load` and the rest of the
`__hip_atomic_*` builtins fail to compile in RCCL sources.

`src/algorithms/gin/sdma/all_reduce_gin_sdma.h` is gone on
`rccl-develop`, so those five call-site edits from the develop PR are
omitted here.

There are **no remaining `__hip_atomic_*` call sites** in RCCL sources
after this PR. The only remaining hits are the poison header, the CI
probe, and comments.

HIP wrapper APIs that still go through `__hip_atomic_*` **inside HIP
headers** are still present. Those compile with the poison because HIP
parses them **before** the pragma, so they are the remaining way
`__hip_atomic_*` can still land in `librccl.so`:

| API | Where |
|---|---|
| `atomicAdd` | `prims_ll.h`, `prims_simple.h`, `gin_anvil_sdma.h`,
`gin_rocshmem_gda.h`, `llx_latency_bench.c` |
| `atomicMax` | `prims_simple.h` |
| `atomicCAS` | DOCA verbs headers under `src/transport/net_ib/gdaki/` |

Closing that gap means porting those wrappers to `__scoped_atomic_*`
with explicit scopes. I will do that as a separate PR.

- [x] `./install.sh -l` still builds with poison enabled
- [x] `python3 projects/rccl/src/include/test_poison_hip_atomics.py` (or
`test/host/run_host_tests.sh guards`)
- [ ] Confirm a deliberate `__hip_atomic_load` in a device TU fails with
`attempt to use a poisoned identifier`
corey-derochie-amd pushed a commit that referenced this pull request Oct 15, 2026
…11321)

- Retarget of the scoped-atomics work onto `rccl-develop` (see also
- Device atomics now use Clang `__scoped_atomic_*` / `__atomic_*`
instead of `__hip_atomic_*`, with explicit memory scopes.
- Adds a compile-time poison (`RCCL_POISON_HIP_ATOMICS`, default ON) and
a host-test CI probe that `__hip_atomic_load` and the rest of the
`__hip_atomic_*` builtins fail to compile in RCCL sources.

`src/algorithms/gin/sdma/all_reduce_gin_sdma.h` is gone on
`rccl-develop`, so those five call-site edits from the develop PR are
omitted here.

There are **no remaining `__hip_atomic_*` call sites** in RCCL sources
after this PR. The only remaining hits are the poison header, the CI
probe, and comments.

HIP wrapper APIs that still go through `__hip_atomic_*` **inside HIP
headers** are still present. Those compile with the poison because HIP
parses them **before** the pragma, so they are the remaining way
`__hip_atomic_*` can still land in `librccl.so`:

| API | Where |
|---|---|
| `atomicAdd` | `prims_ll.h`, `prims_simple.h`, `gin_anvil_sdma.h`,
`gin_rocshmem_gda.h`, `llx_latency_bench.c` |
| `atomicMax` | `prims_simple.h` |
| `atomicCAS` | DOCA verbs headers under `src/transport/net_ib/gdaki/` |

Closing that gap means porting those wrappers to `__scoped_atomic_*`
with explicit scopes. I will do that as a separate PR.

- [x] `./install.sh -l` still builds with poison enabled
- [x] `python3 projects/rccl/src/include/test_poison_hip_atomics.py` (or
`test/host/run_host_tests.sh guards`)
- [ ] Confirm a deliberate `__hip_atomic_load` in a device TU fails with
`attempt to use a poisoned identifier`
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