Skip to content

[AICOMRCCL-1851] [RCCL] test: cover rma_proxy cpuAccessSignals MR type - #12756

Merged
prasanna-amd merged 6 commits into
developfrom
users/prasanna-amd/aicomrccl-1851
Oct 16, 2026
Merged

prasanna-amd merged 6 commits into
developfrom
users/prasanna-amd/aicomrccl-1851

Conversation

@prasanna-amd

Copy link
Copy Markdown
Contributor

Motivation

ncclRmaProxyCtxAllocGraph registers cpuAccessSignalsDev with the net plugin.
That buffer comes from allocMemCPUAccessible, which returns host-NUMA pinned
memory
whenever GDRCopy is off — and NCCL_GDRCOPY_ENABLE defaults to 0, so
on ROCm the host path is the default path, not an edge case.

Before the fix the registration type was hardcoded NCCL_PTR_CUDA, so the net
plugin rejected the MR. Upstream fixed this in NCCL 2.30.7 (NVIDIA/nccl PR #2187)
by deriving the type from the GDR handle. RCCL develop is at NCCL 2.31.2 and
already carries the fix, so no production code changes here — the line was
simply uncovered, and a regression would silently break every RMA-proxy run
without GDRCopy. RCCL has already had to patch two neighbouring symptoms of the
same "these signals may be host memory" confusion (rcclParamRmaProxyUseDMABUF
and the props_tmp DMA-BUF strip in the same function), which is why pinning
this behaviour down is worth doing.

This PR adds the regression coverage.

Technical Details

New host-only microtest test/host/rma-proxy-test.cc plus its own binary,
rccl-UnitTestsMicroRmaProxy. Host-only: it links gtest + fmt, not
librccl.so, libamdhip64.so or libhsa-runtime64.so, and needs no GPU.

It gets a dedicated binary rather than joining rccl-UnitTestsMicro because
that target already resolves ncclRmaProxyConnectOnce, ncclRmaProxyRegister
and ncclRmaProxyDeregister from fakes/dev_runtime_micro_fakes.cc, and
rma_proxy.cc defines all three — linking the unit under test there is a
duplicate symbol. MICROTEST_README.md sanctions one binary per unit, and
rccl-UnitTestsMicroInit / ...Enqueue are the precedent.

ncclRmaProxyCtxAllocGraph is file-static, so the test TU #includes the
hipified .cc via a build-time RMA_PROXY_CC_PATH macro — the documented micro
idiom, same as the sibling rma-proxy-progress-test.cc.

Two seams make this a test of the fix rather than a restatement of it:

  1. allocMemCPUAccessible is a static template in gdrwrap.h, so it cannot be
    stubbed at link time. That is a feature here: the test runs the real helper
    and pivots it on the real discriminator, the extern global ncclGdrCopy. The
    GDR handle the production ternary branches on is the one production actually
    produced, not a mocked premise.
  2. In StrictPluginRejectsWrongMemoryType_AllocGraphStillSucceeds, FakeRma
    rejects NCCL_PTR_CUDA for any pointer present in a set populated by the
    hipHostMalloc seam. "Is this host memory?" is answered by real provenance,
    so the test models the defect rather than asserting the conclusion.

Also in this PR:

  • fakes/hip_fakes.{h,cc}: hipMemset was a fail-loud stub with no hook, which
    would have aborted this function's cudaMemset(flushBufDev, ...) under
    CUDACHECK. Upgraded to a g_hipMemset seam whose default really memsets. No
    existing host test referenced hipMemset.
  • run_host_tests.sh: added the new binary to the run list. Without this the CI
    host-test job would build it and never run it, and still go green.
  • test/test_categories_micro_rma_proxy.yaml: category registration, structurally
    identical to test_categories_micro_enqueue.yaml.

Issue Tracking

JIRA ID: AICOMRCCL-1851
Upstream: NVIDIA/nccl PR #2187 (NCCL 2.30.7)

Test Plan

All compiles and all binary runs were done on compute nodes, never a login node.

  1. Build and run the new binary both standalone (test/host project) and in-tree.
  2. Prove it catches the defect. Revert the fix in the hipified rma_proxy.cc
    — the exact TU the binary #includes — back to the pre-PR-Rock: hip-tests installation path to remain same for linux/windows #2187 unconditional
    NCCL_PTR_CUDA, rebuild, rerun, then restore and re-verify green.
  3. Branch coverage via llvm-cov --show-branches=count: both arms of the
    cpuAccessSignalsGdrHandle != NULL ternary must be non-zero. Line hits alone
    are not evidence — the bug lives entirely in which arm is taken.
  4. Order-independence under --gtest_shuffle (CI shuffles), and a JUnit report
    actually written.

Test Result

Green, in-tree and standalone: 5/5, rc=0, and ldd confirms no
librccl/libamdhip/libhsa.

Pre-fix revert — rc=1, 2 failed / 3 passed:

[  FAILED  ] RmaProxyAllocGraphTest.GdrCopyOff_RegistersCpuAccessSignalsAsHost
  rma-proxy-test.cc:319: Expected equality of these values:
    0x1 (NCCL_PTR_HOST)   Which is: 1
    reg->type             Which is: 2
  host-NUMA cpuAccessSignals registered as device memory (NVIDIA/nccl PR #2187)

[  FAILED  ] RmaProxyAllocGraphTest.StrictPluginRejectsWrongMemoryType_AllocGraphStillSucceeds
  rma-proxy-test.cc:353: Expected equality of these values:
    ncclSuccess    Which is: 0
    AllocGraph()   Which is: 3   (ncclInternalError)
  net plugin rejected the cpuAccessSignals registration due to wrong memory type (NVIDIA/nccl PR #2187)

[       OK ] RmaProxyAllocGraphTest.GdrCopyOn_RegistersCpuAccessSignalsAsCuda
[       OK ] RmaProxyAllocGraphTest.FlushBufferStaysCudaOnBothGdrArms
[       OK ] RmaProxyAllocGraphTest.ForceStrongOrderingPreservedOnBothGdrArms

Restoring the line returns 5/5. The second failure is the defect stated verbatim:
a strict plugin refusing a mistyped MR takes ncclRmaProxyCtxAllocGraph to
ncclInternalError.

The three passes are as important as the failures — they show the suite is not
simply "everything red when the line changes". The GDRCopy-on arm, the flush
buffer and the FORCE_SO flag are unaffected, so an over-correction to always
NCCL_PTR_HOST would be caught too.

Branch coverage:

229|  7|  int cpuAccessSignalsType = (rmaProxyCtx->cpuAccessSignalsGdrHandle != NULL) ? NCCL_PTR_CUDA : NCCL_PTR_HOST;
  |  Branch (229:30): [True: 3, False: 4]

Shuffle: 5/5 and a valid <testsuites> report at seeds 0, 1, 7, 42, 1851.

Scope limit, stated plainly

This is host-microtest evidence. The real-world claim — that a net plugin stops
rejecting the MR — is modelled by a FakeRma vtable, not exercised against a
live IB plugin on multi-node hardware. For a one-line memory-type fix on a path
that is already the ROCm default, I judged a host microtest the proportionate
gate; a reviewer who wants an MPI/IB functional test should say so.

Submission Checklist

@therock-pr-bot

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

@prasanna-amd
prasanna-amd force-pushed the users/prasanna-amd/aicomrccl-1851 branch from ed9f738 to 0f66325 Compare October 4, 2026 04:59
@prasanna-amd
prasanna-amd marked this pull request as ready for review October 4, 2026 05:06
@prasanna-amd
prasanna-amd requested review from a team and a balanced review from Copilot October 4, 2026 05:06

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.

Copilot review overview

🟡 Changes recommended

Graph allocations leak during fixture teardown and between test iterations, accumulating during repeated runs and failing leak detection.

Review effort: Balanced
Findings: 1 Medium severity

Open (1)
What changed in this PR

Adds host-only regression coverage for RCCL’s existing RMA-proxy memory registration fix, without changing production code.

Changes:

  • Tests host and GDRCopy registration types, strict plugin rejection, and ordering flags.
  • Adds a resettable synchronous hipMemset fake.
  • Integrates the dedicated test binary into builds, execution, categories, and documentation.
File Description
projects/​rccl/​test/​test_categories_micro_rma_proxy.yaml Registers test categories.
projects/​rccl/​test/​host/​run_host_tests.sh Runs the new binary.
projects/​rccl/​test/​host/​rma-proxy-test.cc Adds five regression tests.
projects/​rccl/​test/​host/​MICROTEST_README.md Documents the binary and usage.
projects/​rccl/​test/​host/​fakes/​hip_fakes.h Declares the memset hook.
projects/​rccl/​test/​host/​fakes/​hip_fakes.cc Implements and resets the hook.
projects/​rccl/​test/​host/​CMakeLists.txt Defines the dedicated host-test target.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@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: Looks approval ready. The regression coverage holds up against a pre-fix revert, and the inline notes are polish on the new test file.

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

@prasanna-amd
prasanna-amd requested review from mch and pvallem October 4, 2026 16:08
@prasanna-amd

Copy link
Copy Markdown
Contributor Author

@mch @pvallem — review request for this one. @dlamd1dai tagging you for visibility.

Adds host-only regression coverage for the rma_proxy cpuAccessSignals MR-registration-type fix (NVIDIA/nccl PR #2187, already in develop via NCCL 2.31.2). The host-NUMA arm is the default path on ROCm since GDRCopy is off by default, and the line was previously uncovered.

Six tests in a new rccl-UnitTestsMicroRmaProxy binary. The test drives the real allocMemCPUAccessible via ncclGdrCopy rather than stubbing it, so the GDR handle production branches on is the one production produced, and the strict-plugin case reproduces the reported failure (a plugin refusing a host pointer offered as NCCL_PTR_CUDA) rather than just asserting an argument value.

Evidence it would have caught the defect: with rma_proxy.cc:229 locally reverted to the pre-fix literal, tests 1 and 3 fail and the rest pass; restored, all green. Branch coverage on the ternary is [True: 3, False: 4].

Review comments from Copilot and argus-bot are addressed and 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

Bottom line: Worth settling before approval: whether ncclRmaProxyCtxAllocGraph nulls what it frees on its error path, since the new reject-all test is the first to run FreeGraph() against a partially built ctx_.

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

@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

1 finding(s) that could not be posted as inline comments
  • projects/rccl/src/rma/rma_proxy.cc:233 (Low) ncclCalloc is passed a byte count where it expects an element count, over-allocating cpuAccessSignalsHost 8x ncclCalloc takes an element count, but rma_proxy.cc:233 (and :164) pass signalsBufSize, which is already signalSlots * sizeof(uint64_t). Both targets are uint64_t*, so each allocates 8x: 512 bytes for a 64-byte buffer at nRanks=8, numRmaSig=1. Over-allocation only, and the free() stays correct. rma_ce.cc:82 passes signalSlots for the same buffer. Outside this diff, so noting it as a follow-up rather than something to fix here.

Bottom line: Looks approval ready.

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

@prasanna-amd

Copy link
Copy Markdown
Contributor Author

Thanks — re-review on 78a696bca2 confirms the three follow-ups as resolved.

On the ncclCalloc finding: checked it, and it is real. ncclCallocDebug mallocs nelem * ncclSizeOfT<T>() (src/include/alloc.h:447), so it wants an element count. rma_proxy.cc:233 passes signalsBufSize, already signalSlots * sizeof(uint64_t) (:218), and cpuAccessSignalsHost is uint64_t* (rma/rma_proxy.h:166) — so the allocation is 8x the intent. Same shape at :164 for signalsHost. rma_ce.cc:82 passes signalSlots for the equivalent buffer, which is the correct form.

Agreed it is a follow-up and not for this PR: it is over-allocation only (no overflow, and free(ctx->cpuAccessSignalsHost) at :374 stays correct), it is inherited from upstream rather than introduced here, and this PR is test-only — adding a production change would put it outside the scope of AICOMRCCL-1851 and outside what the host microtest can validate. Will raise it separately.

@prasanna-amd

Copy link
Copy Markdown
Contributor Author

Note on the build check (RCCL Perf Regression Gate), so it is not read as a result from this change.

Its true state is CANCELLED, not a failure. The Build reference + candidate librccl step submits a job to the gate cluster with sbatch --wait and then produces no further output until the job hits timeout-minutes: 60 and the runner kills the orphan sbatch:

  • attempt 1: SLURM job 21911, 22:40:17 -> 23:40:33 (60m16s)
  • attempt 2 (rerun): SLURM job 21912, 23:56:20 -> 00:56:35 (60m15s)

Neither log contains a compiler diagnostic, a link error or any test output — the build never got far enough to emit one.

This is not specific to this PR. The last ten runs of rccl_perf_regression.yml, across four different authors' branches, are all cancelled. Not rerunning again, since each attempt costs an hour and ends the same way; flagging it for whoever owns the gate cluster, with 21911/21912 as the handles.

For what it is worth, this PR adds host-only test sources plus a CMakeLists entry and a test-categories yaml — nothing that the perf gate measures. Host unit tests (CPU-only), which does run the new suite, is green.

@prasanna-amd
prasanna-amd force-pushed the users/prasanna-amd/aicomrccl-1851 branch from 78a696b to 0bdd4eb Compare October 7, 2026 16:03
@prasanna-amd

Copy link
Copy Markdown
Contributor Author

Rebased onto current develop (was 422 commits behind; the range includes the nccl/v2.32.3-1 sync, 5e4b885). New head: 0bdd4eb68b.

Two conflicts, both additive list entries resolved by keeping both sides:

  • test/host/run_host_tests.sh — binary/XML list, now carries both rccl-UnitTestsMicroDiagnostics and rccl-UnitTestsMicroRmaProxy.
  • test/host/MICROTEST_README.md — standalone target list and the example invocation block.

No test-source changes were needed. The fix under test survives the 2.32 sync unchanged at src/rma/rma_proxy.cc:228, and the ncclRmaProxyCtx fields the fixture touches (cpuAccessSignals, cpuAccessSignalsDev, cpuAccessSignalsGdrHandle, cpuAccessSignalsHost, flushBufDev) kept their names.

Revalidated on a compute node against the rebased tree: refreshed the hipified sources (hipify_all), asserted the fix line is present in hipify/src/rma/rma_proxy.cc, then a clean Debug build (the configuration CI uses) of rccl-UnitTestsMicroRmaProxy, ldd confirming it links neither librccl nor the HIP/HSA runtime, and 3 repeats of the suite: 6 tests each iteration, rc=0 tests=6.

@prasanna-amd

Copy link
Copy Markdown
Contributor Author

The three checks that went red after the rebase (Ruby / ruby64-rccl-pr-smoke, OCI / oci-rccl-pr-smoke, and the RCCL PR gate aggregator on run 37649063114) are not caused by this branch. They are a coco-side configuration break affecting every RCCL-touching PR in the repo right now.

Root cause. coco's console log — which is uploaded as an artifact rather than printed in the job log, which is why the job log shows only a bare exit code 1 four to six seconds after launch — contains a single line on both clusters:

Error: "--baseline-stack ['rocm-10.1-latest_rccl-develop-perf'] is not among the runtimes this job runs:
['rocm-10.1-ga_rccl-develop', 'rocm-10.1-ga_rccl-develop-backtrace', 'rocm-10.1-ga_rccl-develop-debug',
 'rocm-10.1-ga_rccl-develop-perf', 'rocm-10.2-latest_rccl-develop', 'rocm-10.2-latest_rccl-develop-backtrace',
 'rocm-10.2-latest_rccl-develop-debug', 'rocm-10.2-latest_rccl-develop-perf', 'rocm-7.0.2_rccl-develop']."

.github/workflows/rccl-coco-pr.yml:125 pins baseline_stack: rocm-10.1-latest_rccl-develop-perf. The runtime set on the coco side has since been renamed to rocm-10.1-ga_* with rocm-10.2-latest_* added, so that name no longer resolves and coco exits before it builds anything.

Evidence that it is not the rebase. The invocation is byte-identical to the last green run on this branch; the only thing that changed is the resolved coco ref:

run date coco ref --baseline-stack result
37220626857 Oct 4 17:28Z 0a5a9dca66 rocm-10.1-latest_rccl-develop-perf success
37649063114 Oct 7 16:03Z 6fc5ded983 rocm-10.1-latest_rccl-develop-perf failure

And it is repo-wide — every RCCL PR whose coco cluster jobs actually ran today after ~15:24Z fails both clusters the same way, e.g. runs 37643636626 (PR #13030), 37643848856, 37645593861, 37648852799. I confirmed the artifact for 37643636626 carries the identical error string.

Nothing to fix on this branch, and rerunning will not help until either the workflow's baseline_stack is updated to rocm-10.1-ga_rccl-develop-perf or the coco-side runtime name is restored. Not burning reruns.

The host microtest itself was revalidated against the rebased tree on a compute node (refreshed hipify, Debug build, 3 repeats, rc=0 tests=6) — see the previous comment.

@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: LGTM.

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

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

Can you tidy up the cmake and remove the assertion of the fake behvaiour?

Comment thread projects/rccl/test/host/CMakeLists.txt Resolved
Comment thread projects/rccl/test/host/CMakeLists.txt Resolved
Comment thread projects/rccl/test/host/CMakeLists.txt Resolved
@prasanna-amd

Copy link
Copy Markdown
Contributor Author

@mch — done in 5eb14f3.

Removed assertions on fake behaviour:

  • EXPECT_EQ(handle->kind, want) inside FakeRma::Rma — asserted on the fake's own handle tagging. Handle::Kind went with it; the ctx/collComm handles stay distinct objects.
  • the four hostAddrs_.count(...) checks — fixture bookkeeping. The cpuAccessSignalsGdrHandle premise checks already pin which allocator arm ran.
  • EXPECT_TRUE(rmaNet_.regs.empty()) in the reject-everything test — restated how the fake was configured.
  • EXPECT_FALSE(reg->viaDmaBuf) — its own comment said "not a property of the fix". The unread viaDmaBuf plumbing came out too.
  • the EXPECT_ wrappers around the cleanup calls in FreeGraph() — plain calls now.

Kept, deliberately:

  • hostAddrs_ itself — it is the input to strictMemType, i.e. the mechanism that makes StrictPluginRejectsWrongMemoryType_AllocGraphStillSucceeds reproduce the actual defect rather than assert on an argument.
  • EXPECT_EQ(0, rmaNet_.destroyCtxCalls) in TearDown — that is production behaviour (AllocGraph must not tear the context down), not fake behaviour; it was added at argus's request.

CMake: source-list preamble collapsed to one line, inline comments dropped from the target block, now matching the rccl-UnitTestsMicroDiagnostics style.

Revalidated on a compute node, Debug, 3 repeats: 6/6 pass. Negative control with rma_proxy.cc:229 reverted to the pre-fix NCCL_PTR_CUDA literal still fails exactly GdrCopyOff_RegistersCpuAccessSignalsAsHost and StrictPluginRejectsWrongMemoryType_AllocGraphStillSucceeds, 4 pass — the regression anchors survive the trim.

Your review carried no inline anchors, so if anything else reads as fixture-asserting-fixture, point at it and I will take it out.

@prasanna-amd
prasanna-amd requested a review from mch October 8, 2026 17:34
@prasanna-amd

Copy link
Copy Markdown
Contributor Author

Correction to my previous comment: your review did carry inline anchors — eight of them — and I had read a stale enumeration when I said otherwise. All eight are now addressed and resolved, with a per-thread reply.

Summary across 5eb14f3 and 5115f8d:

  • CMake source list trimmed to the eight entries you listed; archinfo.cc and the six unneeded fakes are gone, per-entry annotations replaced by the one-line README pointer.
  • Context lifecycle now goes through ncclRmaProxyCreateContext / ncclRmaProxyDestroyContext. The hand-written FreeGraph() is deleted.
  • Fake-behaviour assertions removed (handle tag, hostAddrs_ counts, regs.empty(), viaDmaBuf, the EXPECT_ wrappers on cleanup calls).
  • Comments: param enumeration dropped, file:line citations replaced with file-and-symbol, trailing include comments deleted, the own-binary rationale de-duplicated into MICROTEST_README.md.

Validation on a compute node, Debug (what CI builds), 3 repeats: 6/6 pass. Negative control with rma_proxy.cc:229 reverted to the pre-fix NCCL_PTR_CUDA literal still fails exactly GdrCopyOff_RegistersCpuAccessSignalsAsHost and StrictPluginRejectsWrongMemoryType_AllocGraphStillSucceeds, 4 pass. Clean under ASan with detect_leaks=1.

@mch ready for another look.

@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: LGTM.

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

@prasanna-amd

Copy link
Copy Markdown
Contributor Author

OCI / oci-rccl-pr-smoke went red (run 37818519921). Not caused by this PR — it is a 4-node SLURM launch fault that hits the develop baseline identically.

The baseline_stack name mismatch I reported earlier is fixed, so coco now actually builds and runs. Results from the uploaded console artifact:

stack passed errored skipped
pr-12756_rccl-debug_rocm-10.1-ga 201 0 6
pr-12756_rccl-perf_rocm-10.1-ga 10 5 3
pr-12756_rccl-perf_rocm-10.2-latest 10 5 3
rocm-10.1-ga_rccl-develop-perf (baseline, no PR changes) 10 5 3

Two things settle it:

  1. The baseline stack — plain develop, none of this branch's commits — errors on exactly the same 5 cases with exactly the same counts.
  2. Every one of the 15 errored rows across the three perf stacks is the 4n_8ppn topology. No 1n or 2n case errored anywhere. The gtest stack (rccl-debug, 201 tests) is completely green.

The underlying failure is a job-step launch fault, not an RCCL one:

nodes: useocpm2m-097-[015,028,030,038]
srun: error: Task launch for StepId=462711.0 failed on node useocpm2m-097-030: Header lengths are longer than data received
srun: error: Application launch failed: Header lengths are longer than data received
srun: error: useocpm2m-097-028: task 1: Killed
srun: error: useocpm2m-097-038: task 3: Killed
container reaper: fan-out could not launch (rc=139), reaping this node only

The test binary never starts — the PMI/daemon fan-out dies before main. For the record, this PR adds only a host-only microtest and its CMake/README entries; it changes no production source, so there is no mechanism by which it could affect a 4-node perf run.

Not rerunning, for the same reason as before: a rerun would land on the same cluster state and cost cycles without new information. Happy to rerun if a CI owner wants it once the OCI nodes are healthy.

@prasanna-amd

Copy link
Copy Markdown
Contributor Author

Follow-up on the other two red checks, now that Ruby / ruby64-rccl-pr-smoke has finished (run 37818519921):

Ruby / ruby64-rccl-pr-smoke — CANCELLED, not a PR failure. The job hit the workflow's wall-clock cap at test 103/115 (06:02:45Z → 07:46:56Z). Of the 103 that started: 100 PASSED, 2 TIMEOUT (exit 124), 1 still running at cancellation. The two timeouts are the same test on the same topology:

stack test time
rocm-10.1-ga_rccl-develop-perf (baseline, no PR changes) 4n_8ppn_..._regression-bf16-sum_all_reduce_perf_1 934 s
pr-12756_rccl-perf_rocm-10.1-ga 4n_8ppn_..._regression-bf16-sum_all_reduce_perf_1 933 s

Both ran the complete size sweep to 2 GiB with #wrong = 0 at every size, then tripped the per-test timeout during teardown. The numbers are indistinguishable between the PR and the develop baseline, e.g. at 2147483648 B: 215609 us / 9.96 / 19.30 (PR) vs 215590 us / 9.96 / 19.30 (baseline). So this is the harness's per-test budget being too tight for 4-node bf16 all_reduce, and it is too tight on develop as well.

Same shape as the OCI failure reported above: errors confined to the 4-node topology, with the develop baseline affected identically. No 1n or 2n case failed on either cluster.

RCCL PR gate — FAILURE is a pure rollup. Its only step is "Require every cluster to have passed"; it read GATE_RESULT: failure and exited 1 because OCI failed and Ruby was cancelled. It carries no independent signal.

This PR adds test-only files under test/host/; it changes no production source and no build input that any of these runs consume.

@prasanna-amd
prasanna-amd force-pushed the users/prasanna-amd/aicomrccl-1851 branch from 5115f8d to 053d6bc Compare October 13, 2026 03:55
@prasanna-amd

Copy link
Copy Markdown
Contributor Author

@mch — rebased onto current develop and revalidated; this branch is no longer conflicting. New head 053d6bccdf (was 5115f8d7e1).

Rebase. The branch was 257 commits behind. Two conflicts, both the same additive-list shape as the last rebase, both resolved by keeping both sides:

  • test/host/CMakeLists.txt — upstream's new TEST_MICRO_CE_SOURCE_FILES block landed at the same spot as TEST_MICRO_RMA_PROXY_SOURCE_FILES. Both blocks kept, each with its own main_altrsmi.cpp / PARENT_SCOPE) terminator.
  • test/host/MICROTEST_README.md — upstream added the rccl-UnitTestsMicroGinHost bullet and added that name to the standalone-binary list sentence. Kept both bullets; re-flowed the one sentence so both names appear.

No test changes were needed. The fix still sits unchanged at src/rma/rma_proxy.cc:228, and every ncclRmaProxyCtx field the fixture touches kept its name. Our contributed hunks are byte-identical to pre-rebase in rma-proxy-test.cc, test_categories_micro_rma_proxy.yaml, fakes/hip_fakes.{cc,h}, run_host_tests.sh and CMakeLists.txt; the only delta anywhere is the README sentence re-flow above.

Revalidated on a compute node (job 71037, cv350-rck-g03-c12-08, glibc 2.34 — the compute image, not the login node):

  • hipified sources were stale after the rebase, so the job rebuilds hipify_all first and asserts the fix line is actually present in hipify/src/rma/rma_proxy.cc before trusting the build — it is, at line 229.
  • clean Debug build (what run_host_tests.sh uses).
  • ldd confirms no librccl / libamdhip / libhsa linkage.
  • 3 repeats: 6 tests from RmaProxyAllocGraphTest, [ PASSED ] 6 tests each, rc=0.
  • the categories yaml pattern RmaProxyAllocGraphTest.* selects all 6 — checked explicitly, since gtest's * does not cross a literal . and a wrong pattern would build fine and silently run zero tests.

Review state. All eight of your inline anchors were addressed across 5eb14f376b and 5115f8d7e1 (cmake source list trimmed to the eight entries you listed, context lifecycle moved onto ncclRmaProxyCreateContext / ncclRmaProxyDestroyContext with the hand-written FreeGraph() deleted, fake-behaviour assertions removed), each with a per-thread reply, and all threads are resolved — 0 unresolved. argus re-reviewed and returned LGTM with no inline comments. Your CHANGES_REQUESTED from Oct 8 is the only thing still blocking; whenever you have a moment, could you take another look?

One thing I did not touch, to keep the diff tight: line 799 of MICROTEST_README.md has a pre-existing upstream typo — `rccl-UnitTestsMicroGinHost, is missing its closing backtick. It came in with the GinHost commit, not this branch. Happy to fix it here if you'd prefer.

@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: LGTM.

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

@prasanna-amd
prasanna-amd force-pushed the users/prasanna-amd/aicomrccl-1851 branch from 053d6bc to bc276c0 Compare October 14, 2026 16:30

@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: LGTM.

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

Add host-only microtests for the MR-registration-type fix in
ncclRmaProxyCtxAllocGraph (src/rma/rma_proxy.cc).

When GDRCopy is disabled -- the default on ROCm, since NCCL_GDRCOPY_ENABLE
defaults to 0 -- allocMemCPUAccessible hands back host-NUMA pinned memory
rather than device memory. The pre-fix code unconditionally registered
cpuAccessSignalsDev as NCCL_PTR_CUDA, so the net plugin rejected the MR.
Upstream fixed this in NCCL 2.30.7 (NVIDIA/nccl PR #2187) by deriving the
type from the GDR handle: non-NULL means GDRCopy-mapped device memory
(NCCL_PTR_CUDA), NULL means host memory (NCCL_PTR_HOST). The line was
previously uncovered, and because the host path is the default path on AMD,
a regression would silently break every RMA-proxy run without GDRCopy.

The tests pivot the real allocMemCPUAccessible on the extern global
ncclGdrCopy rather than mocking the allocator, so the GDR handle the
production ternary branches on is the one production actually produced. A
FakeRma vtable records every (addr, size, type, mrFlags) registration; in
the strict-plugin test it rejects NCCL_PTR_CUDA for any pointer that the
hipHostMalloc seam really returned, so the failure mode mirrors the defect
instead of restating the assertion.

Five cases: both GDR arms of the cpuAccessSignals registration, a strict
plugin that refuses a mistyped MR, flushBufDev staying NCCL_PTR_CUDA on
both arms, and NCCL_NET_MR_FLAG_FORCE_SO preserved on both arms.

This lands as its own binary, rccl-UnitTestsMicroRmaProxy, rather than
joining rccl-UnitTestsMicro: that target already resolves
ncclRmaProxyConnectOnce, ncclRmaProxyRegister and ncclRmaProxyDeregister
from fakes/dev_runtime_micro_fakes.cc, and rma_proxy.cc defines all three.

Also upgrades the fail-loud hipMemset stub in fakes/hip_fakes.cc to a
g_hipMemset seam whose default really memsets, so a buffer production zeroes
reads back as zero. No existing host test referenced hipMemset.
…ture teardown

RmaProxyAllocGraphTest only destructed comm_->memPermanent, which releases the
persistent/in-progress queues but none of the heap allocations
ncclRmaProxyCtxAllocGraph makes: cpuAccessSignals (allocMemCPUAccessible),
cpuAccessSignalsHost (ncclCalloc) and flushBufDev (hipExtMallocWithFlags).
Deleting ctx_ does not free its raw-pointer members. The two arm-looping tests
additionally overwrote those pointers on their second AllocGraph() call.

Add FreeGraph(), which undoes the allocations in reverse order, each step
null-guarded so a partially completed AllocGraph is still cleaned up. It
deregisters the recorded MRs and pairs the real allocator with the real
deallocator -- freeMemCPUAccessible, selected by the same GDR handle the unit
under test branches on -- then drops the freed pointer from the hipHostMalloc
provenance set so a recycled address cannot make the next arm's "not host
memory" check pass or fail for the wrong reason. Called from TearDown (so it
also runs after an early return from a failed assertion) and at the top of each
loop iteration in FlushBufferStaysCudaOnBothGdrArms and
ForceStrongOrderingPreservedOnBothGdrArms.

ncclRmaProxyDestroyContext is deliberately not used: it ends in free(rmaProxyCtx),
which is incompatible with the fixture's unique_ptr ownership.

The GDR arm's free path reaches ncclCudaFree, which queries the allocation range
before freeing, so SetUp now opens the g_hipMemGetAddressRange seam alongside the
other GDRCopy-on gates.

Verified on a compute node, Debug (what run_host_tests.sh builds):
  - 5/5 tests, --gtest_repeat=3, rc=0
  - -fsanitize=address with ASAN_OPTIONS=detect_leaks=1, --gtest_repeat=3:
    5/5, rc=0, no LeakSanitizer report
  - negative control, same ASan build of the previous revision:
    "SUMMARY: AddressSanitizer: 397397 byte(s) leaked in 24 allocation(s)"
…review nits

Review feedback on the rma_proxy cpuAccessSignals MR-type microtests.

Add PluginRefusesEveryRegistration_AllocGraphFails. The three tests that assert
ncclRmaProxyCtxAllocGraph returns ncclSuccess are only evidence if a refused
registration can still make it fail; nothing demonstrated that the NCCLCHECK
around the cpuAccessSignals registration propagates. A rejectAll flag on FakeRma
refuses every registration and the new test asserts AllocGraph does not succeed.

Assert the registered size on the GDRCopy-on arm too. ncclGdrCudaCalloc rounds
its allocation up to GPU_PAGE_SIZE, so that is the one arm where a registration
sized from the padded block instead of signalsBufSize would go unnoticed.

Correct the props.ptrSupport comment. It claimed the NCCL_PTR_DMABUF bit shows
the registrations are steered by memory type, but ncclRmaProxyRegMrSym tests
ncclParamDmaBufEnable() first and the fixture pins that to 0, so the bit is
never read. Note the same gate on the EXPECT_FALSE(viaDmaBuf) assertion, which
checks the gate held rather than any property of the fix.

Also assert the host-memory provenance in the strict-plugin test and name the
assertion in ForceStrongOrderingPreservedOnBothGdrArms.

Verified on a compute node, Debug, --gtest_repeat=3: 6/6, rc=0; and under
-fsanitize=address with ASAN_OPTIONS=detect_leaks=1: 6/6, rc=0, no
LeakSanitizer report.
…to a helper

Review follow-ups on the rma_proxy cpuAccessSignals MR-type microtest:

- FlushBufferStaysCudaOnBothGdrArms and
  ForceStrongOrderingPreservedOnBothGdrArms carried a byte-identical
  set-gdr / FreeGraph / AllocGraph preamble. Moved it into the fixture as
  ReAllocGraphForArm, called under ASSERT_NO_FATAL_FAILURE so a failure
  inside the helper still stops the test.

- The destroyContext vtable slot was installed but never checked. TearDown
  now asserts destroyCtxCalls == 0, which is the property the function's
  own comment states: ncclRmaProxyCtxAllocGraph leaves failure cleanup to
  the caller's ncclRmaProxyDestroyContext and must not destroy the context
  itself.

Validated on a compute node, Debug and ASan/LSan, 3 repeats each: 6/6, rc=0,
no sanitizer report.
… cmake

Review feedback: the microtest asserted on its own test doubles in several
places, which tests the fixture rather than the unit under test.

Removed:
  - the EXPECT_EQ on the handle tag inside FakeRma::Rma, and with it the
    now-vestigial Handle::Kind tag;
  - the hostAddrs_ provenance checks in four tests -- the
    cpuAccessSignalsGdrHandle premise checks already pin which allocator arm
    ran;
  - EXPECT_TRUE(rmaNet_.regs.empty()) in the reject-everything test, which
    only restated how the fake was configured;
  - EXPECT_FALSE(reg->viaDmaBuf), self-described as "not a property of the
    fix", and with it the unread viaDmaBuf plumbing;
  - the EXPECT_ wrappers around the cleanup calls in FreeGraph().

hostAddrs_ itself stays: it is the input to strictMemType, the mechanism
behind StrictPluginRejectsWrongMemoryType_AllocGraphStillSucceeds.
EXPECT_EQ(0, rmaNet_.destroyCtxCalls) in TearDown stays: it asserts
production behaviour, that AllocGraph must not tear the context down.

CMakeLists: collapsed the source-list preamble to one line and dropped the
inline comments on the target block, matching the rccl-UnitTestsMicroDiagnostics
house style.

Revalidated on a compute node, Debug: 6/6 pass; with rma_proxy.cc:229 reverted
to the pre-fix NCCL_PTR_CUDA literal, exactly GdrCopyOff_RegistersCpuAccess
SignalsAsHost and StrictPluginRejectsWrongMemoryType_AllocGraphStillSucceeds
fail and the other 4 pass -- the regression anchors survive the trim.
…cycle

Review feedback, inline threads on the previous head.

Lifecycle: the fixture no longer hand-builds an ncclRmaProxyCtx and calls the
file-static ncclRmaProxyCtxAllocGraph directly, with a hand-written FreeGraph()
mirroring ncclRmaProxyDestroyContext. It now goes through the entry points a
production client uses -- ncclRmaProxyCreateContext (which runs CtxAlloc then
CtxAllocGraph) and ncclRmaProxyDestroyContext -- so production owns the context
and its cleanup, and the cleanup no longer has to be kept in step by hand. The
vtable gains a createContext trampoline and the comm carries
rmaState.rmaProxyState.ncclRma.

PluginRefusesEveryRegistration_AllocGraphFails becomes
PluginRefusesCpuAccessSignalsRegistration_CreateContextFails: rejectAll is
replaced by rejectAfterNReg, set to 1, which lets the signalsDev registration
from CtxAlloc through and refuses the cpuAccessSignals one specifically, so the
negative control still pins the NCCLCHECK under test rather than an earlier one.

CMakeLists: trimmed the source list to what the link needs -- env_fakes,
comm_fakes, mem_manager_fakes, recorder_fakes, strongstream_stubs,
bootstrap_stubs and archinfo.cc are gone -- and replaced the per-entry
annotations with the one-line pointer to the README map that the Init and
Enqueue lists use.

Comments: dropped the enumeration of rma_proxy.cc's params (already drifted),
replaced the file:line citations with file-and-symbol, deleted the trailing
explanations on three includes, and reduced the own-binary rationale to a
pointer at the MICROTEST_README entry that carries it in full.

Validated on a compute node: Debug, 3 repeats, 6/6 pass. With rma_proxy.cc:229
reverted to the pre-fix NCCL_PTR_CUDA literal, exactly
GdrCopyOff_RegistersCpuAccessSignalsAsHost and
StrictPluginRejectsWrongMemoryType_AllocGraphStillSucceeds fail. Clean under
ASan with detect_leaks=1.
@prasanna-amd
prasanna-amd force-pushed the users/prasanna-amd/aicomrccl-1851 branch from bc276c0 to f335478 Compare October 15, 2026 17:32
@prasanna-amd
prasanna-amd merged commit be40d1e into develop Oct 16, 2026
69 of 72 checks passed
@prasanna-amd
prasanna-amd deleted the users/prasanna-amd/aicomrccl-1851 branch October 16, 2026 15:48
mch added a commit that referenced this pull request Oct 16, 2026
…proxy-test

Merging develop brought in #12756, which defines a local ncclSetThreadName
stub in rma-proxy-test.cc. This branch had already moved that symbol onto its
owning fakes file (fakes/nccl_fakes.cc), which rccl-UnitTestsMicroRmaProxy
also links, so the two definitions collided at link time:

  ld.lld: error: duplicate symbol: ncclSetThreadName(std::thread&, char const*, ...)

Remove the local stub and note in the surrounding comment that symbols with an
owning fakes file must not be redefined in this TU.

Co-authored-by: Pi Agent
@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.

5 participants