Skip to content

Add accumulate method for PortChannel - #784

Open
Changho Hwang (chhwang) wants to merge 2 commits into
mainfrom
chhwang/new-atomic-add
Open

Add accumulate method for PortChannel#784
Changho Hwang (chhwang) wants to merge 2 commits into
mainfrom
chhwang/new-atomic-add

Conversation

@chhwang

@chhwang Changho Hwang (chhwang) commented Apr 13, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds Connection::accumulate() and PortChannel::accumulate() for remote signed 64-bit addition. Unlike updateAndSync(), callers provide only their contribution, allowing concurrent writers to share a counter.

The operation uses the TriggerAccumulate FIFO opcode. Its operand occupies the trigger's first word. The implementation follows the latest FIFO protocol: readiness comes from lap-parity commit bits, so zero-valued operands are valid.

Transport support

Transport Support
IB NIC atomic fetch-and-add; rejected in no-atomic mode
Ethernet Receive-side read-modify-write, serialized across connections
CudaIpc on ROCm Atomic kernel on the connection stream
CudaIpc on CUDA Rejected; no safe, practical proxy-side RMW

Validation

Tests cover signed and zero operands, operation ordering, unsupported modes, and multi-rank fan-in across supported transports.

Validated on H200/CUDA 12.9 and MI300X/ROCm 7.2. CI build, lint, docs, CUDA comparison, and completed CodeQL jobs pass.

@chhwang Changho Hwang (chhwang) changed the title Add atomicAdd method for PortChannel Add accumulate method for PortChannel Aug 4, 2026
@chhwang
Changho Hwang (chhwang) marked this pull request as ready for review August 4, 2026 23:36
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
There may be pipelines that require an authorized user to comment /azp run to run.

@chhwang
Changho Hwang (chhwang) force-pushed the chhwang/new-atomic-add branch 3 times, most recently from ccfecde to 36ce485 Compare August 6, 2026 08:22
@chhwang
Changho Hwang (chhwang) changed the base branch from main to chhwang/enhanced-fifo August 7, 2026 19:07
Base automatically changed from chhwang/enhanced-fifo to main August 12, 2026 23:10
`TriggerData`, `TriggerFlag`, and `TriggerSync` were combinable bits, but the
device API only ever produced five of the seven combinations, and the proxy
tested them with three independent masks. Replace them with one opcode per
operation the API can express:

    TriggerNone = 0   TriggerPut = 1                TriggerSignal = 2
    TriggerFlush = 3  TriggerPutWithSignal = 4      TriggerPutWithSignalAndFlush = 5

Seven values fit the existing 3-bit field with one spare. `handleTrigger`
becomes a switch that names one operation per case and warns on anything
unknown, so a combination nothing emits is now unrepresentable, and a trigger
whose type field is unset is no longer a valid operation.

The old names are removed rather than redefined. Code that composed them with
`|`, or tested them with `&`, must fail to compile: `TriggerFlush` is 3, which
has the old `TriggerData` bit set, so a mask test would silently misbehave.

No behavior change. mp_unit_tests 29/29 and unit_tests 34/34 on H200.
Add `Connection::accumulate()` and `PortChannel::accumulate()`, which add a
64-bit signed value to remote memory. Unlike `updateAndSync()`, the caller
needs to know only its own contribution, not the destination's current value.

Carried by the `TriggerAccumulate` opcode, with the operand in the trigger's
first word. FIFO readiness now comes from the lap-parity commit bit, so a zero
operand traverses the proxy like any other trigger; transport tests interleave
zero and nonzero accumulates to cover that path.

The addition has to be a real read-modify-write at the destination, which not
every transport can do:

- IB: any number of writers, via RDMA fetch-and-add. Rejected in no-atomic
  mode, where the device has no RDMA atomics.
- Ethernet: any number of remote writers. The receiving process performs the
  update, and its connections are serialized against each other; without that
  a 7-writer fan-in loses ~74% of updates.
- CudaIpc on ROCm: any number of writers. The proxy runs a kernel on the
  connection's stream, which also orders it against a following signal. A
  kernel there runs even while the caller's kernel spins.
- CudaIpc on CUDA: not supported, throws InvalidUsage. The host cannot
  read-modify-write device memory, and a proxy-launched kernel either cannot
  be scheduled while the caller's kernel spins (same context) or costs 2391 us
  per operation (separate context), against 19 us for a plain remote store.

Tested on H200 (CUDA 12.9) and MI300X (ROCm 7.2), including an 8-rank fan-in
test with 7 concurrent writers into one address.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant