Triggered Plans#
Experimental (iris.experimental.plan): may change between releases without deprecation.
Copy-engine transfers prepared once and released by kernels, every round. See Triggered Plans for the model and its ordering rules.
TriggeredPlan#
- class TriggeredPlan(ctx, buffer, schedule, timeout=30.0)[source]#
Bases:
objectSends regions of
bufferfrom the rank that writes them to every other rank, using copy engines that a kernel releases chunk by chunk.Each rank passes its own
schedule: the chunks it writes, in the order its producer completes them. Every chunk is copied to the same offsets in each peer’sbuffer. Chunk ids are global: rankr’s chunks come after those of ranks0..r-1(seechunk_id), andschedules[r]holds rankr’s schedule. A rank that writes nothing passes[]. No byte may be in two ranks’ schedules.Collective: every rank creates the plan for the same symmetric
buffer. Use it as a context manager, or callclose()on every rank when done.- Parameters:
ctx – Iris instance, created with
engines=("sdma",).buffer – Contiguous tensor on the symmetric heap.
schedule – This rank’s list of
Chunk, in the order it completes them.timeout – Seconds
wait()andclose()wait before raising.
- wait(timeout=None)[source]#
Wait until every chunk is delivered this round: own ones at every peer, others here.
- next_round()[source]#
Collective: prepare every chain for the next round. If any rank cannot, every rank raises.
Calling it declares that this rank is done reading the current round’s data: once it returns, a peer may start the next round, and its copies can overwrite
bufferat any time. Work queued before the call is covered (the barrier synchronizes the device first); anything issued after it must not readbufferuntil the nextwait().
- run(timeout=None)[source]#
Run one round with no producer kernel: send every own chunk as it stands, then wait.
- close(timeout=None)[source]#
Collective: wait until every rank is done with the plan, then free it.
Prepared copies cannot be withdrawn from the queue, so closing a plan whose round has not finished sends this rank’s chunks as they stand. A peer’s copies and polls may still touch this rank’s buffer and gates, so every rank must call close() before any of them is freed.
Plans may be closed in any order. If a plan prepared earlier on the same queues still has copies waiting, this plan’s copies are queued behind them and cannot run yet: close() then returns with the plan
CLOSING, and closing the earlier plan finishes this one too.
Schedules#
- class Region(offset_bytes, row_bytes, rows=1, stride_bytes=None)[source]#
Bases:
objectOne copy:
rowsrows ofrow_bytesbytes,stride_bytesapart (packed ifNone), startingoffset_bytesinto the plan’s buffer. The same bytes are written at the same offset in each peer’s buffer.- property row_stride#
Bytes between the starts of consecutive rows (
row_bytesif packed).
- property end#
Byte offset one past the last byte this region copies.
- class Chunk(regions, writers=1)[source]#
Bases:
objectRegions sent together once all
writershave marked the chunk ready, every round.- property is_2d#
True if any region has more than one row.
- whole(view, base=None, writers=1)[source]#
One chunk covering a contiguous
view, marked ready bywritersprograms per round.
- chunks(view, n, base=None, writers=1)[source]#
Split a contiguous
viewalong dim 0 intonchunks, in order. Suits producers that finish row blocks in order: row-block, streaming and elementwise kernels.
- tile_chunks(view, block_shape, tiles_per_chunk, order=None, base=None)[source]#
Group the tiles of a tiled producer into chunks of
tiles_per_chunk, in completion order.viewis a 2D tensor with unit column stride, split intoblock_shapetiles (edge tiles clipped; tile ids are row-major).ordergives the tile the producer makes at each stepi: a list of tile ids, or a function ofi. Chunkkholds the tiles of stepsk * tiles_per_chunkup to the next chunk, one region per tile, and is marked ready once per tile. The producer must mark the tile of stepiready as part of chunki // tiles_per_chunk, so pass the mapping the kernel itself uses: a@triton.jitmapping written with plain integer arithmetic runs on the host aslambda i: mapping.fn(i, ...).For a persistent kernel of
Pprograms where programptakes stepsp,p + P, …, usetiles_per_chunk=P: chunkkis every program’sk-th tile, so chunks complete in order.
TriggeredView (device)#
- class TriggeredView(view, gates, round, rank)[source]#
Bases:
objectDevice handle for one round of a triggered plan.
Usage:
@triton.jit def producer(out, handle, ...): cv = TriggeredView.initialize(handle) ... # write this program's part of chunk c cv.mark_ready(c) # whole CTA, after its writes @triton.jit def consumer(out, handle, ...): cv = TriggeredView.initialize(handle) cv.wait(c) # chunk c's data is now visible x = tl.load(out + ...)
- Parameters:
view (tensor)
gates (tensor)
round (tensor)
rank (tensor)
- mark_ready(chunk)[source]#
Declare this CTA’s writes to chunk
chunkdone; the last of its writers sends it.Call from the whole CTA, outside divergent branches, after the CTA’s writes to the chunk.
TriggeredView (Gluon device)#
- class TriggeredView(view, gates, round, rank)[source]#
Bases:
objectGluon device handle for one round of a triggered plan.
Usage:
@gluon.jit def producer(out, handle, ...): cv = TriggeredView.initialize(handle) ... # write this program's part of chunk c cv.mark_ready(c) # whole CTA, after its writes @gluon.jit def consumer(out, handle, ...): cv = TriggeredView.initialize(handle) cv.wait(c) # chunk c's data is now visible x = gl.load(out + ...)
- Parameters:
view (tensor)
gates (tensor)
round (tensor)
rank (tensor)
- mark_ready(chunk)[source]#
Declare this CTA’s writes to chunk
chunkdone; the last of its writers sends it.Call from the whole CTA, after the CTA’s writes to the chunk: outside divergent branches and outside
gl.warp_specializepartitions.