Two alignment gaps in the ring allreduce kernel template that the mesh allreduce kernel already handles but the ring kernel currently does not.
1. dcci flush loop misses the chunk tail
File: python/pypto/runtime/builtins/collectives/allreduce_ring/templates/kernel.cpp.in
The dcci flush loop in both the Reduce-Scatter and AllGather phases steps by 16 elements (i += 16), which only covers the full chunk when chunk_elems % 16 == 0. Compile-time validation only guarantees numel % NR == 0, so a tail cache-line spanning the chunk end goes unflushed.
Counter-example: numel = 18, NR = 2 → chunk_elems = 9 (36 bytes). Chunk 1 starts at byte 36 and spans two cache lines; the 16-element stride misses the second one.
2. 32-byte transfer alignment is missing
The mesh allreduce kernel explicitly rounds ragged spans up to kTransferAlignmentBytes = 32 bytes (in collectives/allreduce/templates/kernel.cpp.in), aligning tile_elems to avoid partial-vector load/store. The ring kernel feeds tile_elems raw into ShapeDyn / StrideDyn with no such rounding.
3. kRecvTileDebugValue rename
The constant name at the top of the kernel reads like leftover debug scaffolding. The TASSIGN call is legitimate (it binds recv_tile to its buffer as a placeholder, overwritten by the subsequent TLOAD), but the constant should be renamed to something like kRecvTileInitFill with a one-line comment.
Suggested approach
- Extract a shared alignment helper used by both mesh and ring kernel templates.
- For the dcci flush: step by 16 elements but emit one additional flush for the final partial cache-line.
- Add an ST case where
chunk_elems % 16 != 0 (e.g. numel=18, NR=2).
- Rename
kRecvTileDebugValue → kRecvTileInitFill.
Context
Raised in review of PR #2094 by @YunjiQin.
Two alignment gaps in the ring allreduce kernel template that the mesh allreduce kernel already handles but the ring kernel currently does not.
1. dcci flush loop misses the chunk tail
File:
python/pypto/runtime/builtins/collectives/allreduce_ring/templates/kernel.cpp.inThe dcci flush loop in both the Reduce-Scatter and AllGather phases steps by 16 elements (
i += 16), which only covers the full chunk whenchunk_elems % 16 == 0. Compile-time validation only guaranteesnumel % NR == 0, so a tail cache-line spanning the chunk end goes unflushed.Counter-example:
numel = 18, NR = 2→chunk_elems = 9(36 bytes). Chunk 1 starts at byte 36 and spans two cache lines; the 16-element stride misses the second one.2. 32-byte transfer alignment is missing
The mesh allreduce kernel explicitly rounds ragged spans up to
kTransferAlignmentBytes= 32 bytes (incollectives/allreduce/templates/kernel.cpp.in), aligningtile_elemsto avoid partial-vector load/store. The ring kernel feedstile_elemsraw intoShapeDyn/StrideDynwith no such rounding.3.
kRecvTileDebugValuerenameThe constant name at the top of the kernel reads like leftover debug scaffolding. The
TASSIGNcall is legitimate (it bindsrecv_tileto its buffer as a placeholder, overwritten by the subsequentTLOAD), but the constant should be renamed to something likekRecvTileInitFillwith a one-line comment.Suggested approach
chunk_elems % 16 != 0(e.g.numel=18, NR=2).kRecvTileDebugValue→kRecvTileInitFill.Context
Raised in review of PR #2094 by @YunjiQin.