Repository navigation
Conversation
Only the atomic emitters had byte-level tests. Check COPY_LINEAR, POLL_REGMEM and NOP against the layouts in the Linux amdgpu SDMA 4.4 driver, writing into an ordinary buffer rather than a queue. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
The host pre-arms copy-engine chains that wait on gates; a kernel opens a gate once its data is written, and the copy engine copies it to every peer and signals its arrival there, without spending compute units. - TriggeredPlan arms epoch 1 when created, then runs begin_device_epoch / end_device_epoch / next_epoch per epoch, plus run, abort and destroy. Gates are 64-byte rows polled with >= on their low 32 bits and never reset. - Schedules list each rank's batches (ordered groups of 1D or 2D segments behind one gate) in the order its producer completes them. Builders: whole, chunks, waves. - Chains are armed through rocm-xio's host-initiated queue to each peer: POLL_REGMEM, one copy per segment, ATOMIC ADD_RTN_64 on the peer's arrival gate. All of these packets have run on gfx942/gfx950. - TriggeredView is the device side: publish (the last of a batch's contributors opens its gate), arrived, wait, reusable. - end_device_epoch checks completion with a kernel reading peers' arrival gates, since quiet() waits for everything on the queue. - Chains on one queue run in arming order, so plans sharing queues must begin and abort in arming order, and Iris.put/put_tile/ put_tiles/quiet raise while chains are armed on that peer's queue. - Plans need stable peer mappings: the torch allocator re-maps peer heaps on every allocation, so it is rejected; use vmem_chunked or vmem. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
A conceptual page on the model, the kernel author's ordering contract and the measured GPU-to-SDMA ordering, and an API reference page. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
Bandit flags SHA1 as a weak hash (B324, high severity), which fails the security scan. The digest only checks that every rank passed the same schedules, so any hash works. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
ariscript
marked this pull request as ready for review
October 8, 2026 15:15
ariscript
requested review from
BKP,
artulab,
mawad-amd and
neoblizz
as code owners
October 8, 2026 15:15
mawad-amd
reviewed
Oct 8, 2026
|
|
||
| ## Model | ||
|
|
||
| - A **segment** is one copy: a byte range, or a 2D sub-window (rows of a strided tensor). It is |
Collaborator
There was a problem hiding this comment.
We need to think a bit more about the naming/new concepts introduced here.
Member
Author
There was a problem hiding this comment.
Yes, this was mostly intended as a prototype to check if this is going in the right direction and pivot if necessary.
Each is a scalar atomic: it runs on one lane, and the compiler hands the result to the other waves through LDS behind a CTA barrier. A polling loop that exits on a per-wave condition, such as a clock read, makes the waves leave after different numbers of iterations. The barriers then no longer pair up, so waves read the result before it is written (and read data before it arrives) or deadlock. Seen on MI300X with a consumer bounded by s_memrealtime; bounding the loop by a poll count fixes it. Stated in the kernel author's contract and in TriggeredView.arrived. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
The vmem_chunked heap frees an allocation when its tensor is garbage collected, independently on each rank. Frees processed in a different order (its free lists are LIFO), or a reference cycle collected on one rank before another, leave the ranks with different free lists, and the same allocation then lands at different offsets. Every peer address a plan arms is then wrong, silently: copies land elsewhere in the peer's heap while arrivals still look correct if the gates happen to match. Check both offsets across ranks when the plan is created. Marked FIXME: it works around the allocator and goes once allocation is symmetric. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds a way for a running kernel to hand data to the copy engines (SDMA) without spending compute
units on the transfer. The host pre-arms copy-engine chains that wait on gates; a kernel opens a
gate once its data is written, and the copy engine copies that data to every peer and signals its
arrival there.
This is the plan layer only implemented with a Triton API so far. Gluon support and triggered collectives
can be added on top of this functionality.
API
the order its producer completes them. Builders:
whole,chunks,waves(one batch per wave ofa persistent tiled kernel). A batch can have several contributors; the last
publishopens it.TriggeredView):publish,arrived,wait,reusable.Design notes
POLL_REGMEM(func 5,>=), oneCOPY_LINEARor sub-window copy per segment, thenATOMIC ADD_RTN_64on the peer's arrival gate.the order they complete (a persistent kernel's waves complete in order by construction). We keep
one queue per peer, matching rocm-xio's design. Plans sharing queues must begin and abort in
arming order, and while chains are armed on a peer's queue,
Iris.put/put_tile/put_tiles/quietto that peer raise instead of queueing behind them.publishiss_waitcnt vmcnt(0)+ CTA barrier + a release atomic at systemscope; consumers use an acquire at system scope. Measured on MI300X and MI350X; see
docs/conceptual/triggered-sdma.md.end_device_epoch()checks completion with a small kernel that reads peers'arrival gates, rather than
quiet(), which waits for everything on the queue (including otherplans' parked chains).
ready,arrival,completion,error, contributor counter),polled with
>=on the low 32 bits and never reset; a plan is limited to 2³² − 1 epochs.allocator_type="vmem_chunked"(or"vmem"). The torch allocator re-importspeer heaps at new addresses on every symmetric allocation (
establish_peer_accessdestroys the oldimports), so a chain armed before an allocation would hold stale peer addresses. VMem keeps peer
addresses fixed, including as the chunked heap grows. The torch allocator is rejected.
Testing
On 8× MI300X (gfx942):
clipped edge tiles, 8 contributors releasing one 4 MiB gate over 10 epochs (stale-data check),
head-of-line ordering, misuse cases, heap growth while a plan is armed, a buffer spanning a heap
chunk boundary, and the host
put(wait_flag=, signal_flag=)path.