Summary
ExpandMixedKernel splits a mixed pl.split_aiv InCore function into AIC + AIV lanes and, via CollectGmCrossLaneSyncs, inserts a tpush/tpop fence for a GM tensor written on the cube lane and read on the vector lane (C2V). The reverse direction — a GM tensor written on the vector lane (AIV) and consumed on the cube lane (AIC), i.e. V2C — is intentionally left unfenced (CollectGmCrossLaneSyncs: if (store.side != CoreSide::AIC) continue;, src/ir/transforms/expand_mixed_kernel_pass.cpp ~line 616) because V2C transport needs V->C fractal adaptation.
Request: automatically synchronize the V2C direction too — either by emitting a V2C tpush/tpop fence (with the fractal adaptation), or by injecting a pl.system.syncall when a V2C cross-lane GM dependency has no established fence/barrier — so producer/consumer ordering is guaranteed by the compiler rather than by a hand-written barrier.
Motivation / Use Case
Follow-up to #1909, which fixed the PTO codegen crash where a GM tensor written inside a split_aiv region and consumed by a cube matmul left a dangling __FREE_VAR (the fix repoints the cross-half reference to the shared base parameter). That fix makes the V2C produce/consume pattern compile, but it does not add a happens-before edge for the V2C direction.
Consequently, a fenceless V2C GM read-after-write can let the cube lane read the GM scratch before the vector lane writes it → a silent wrong result rather than a loud failure. Today, correctness for these kernels (e.g. the in-kernel rope->attn fusion) relies on the author placing an explicit pl.system.syncall barrier between the producer and consumer phases. Auto-fencing would make the safe behavior automatic and prevent a future fenceless V2C kernel from compiling into a race.
An automated reviewer flagged this as P1 on #1909 (left as an open follow-up thread at src/ir/transforms/expand_mixed_kernel_pass.cpp:1243).
Proposed API / Behavior
Three candidate directions (to be decided during design):
- (a) Full fix — V2C fence. Extend
CollectGmCrossLaneSyncs to also handle store.side == AIV with the consumer on AIC, emitting the V2C tpush/tpop fence with the required V->C fractal adaptation (tile.move to NZ/ZN before tpush_to_aic, fractal-typed tpop_from_aiv).
- (b) Auto-barrier. When a V2C cross-lane GM dependency is detected and no fence/barrier is already established, auto-insert a
pl.system.syncall (or equivalent cross-core barrier) covering the producer->consumer ordering.
- (c) Safety net. Detect a genuinely fenceless V2C GM RAW and reject it with an actionable diagnostic (e.g. "insert
pl.system.syncall between the producing split_aiv region and the cube consumer"), instead of compiling a racy kernel.
Pointers:
Alternatives Considered
- Status quo: require the kernel author to place an explicit
pl.system.syncall barrier between the producing split_aiv region and the cube consumer. This works (and is what the shipped fusion kernels do), but it is easy to omit, and omission produces a silent race rather than a diagnostic.
Additional Context
Summary
ExpandMixedKernelsplits a mixedpl.split_aivInCore function into AIC + AIV lanes and, viaCollectGmCrossLaneSyncs, inserts atpush/tpopfence for a GM tensor written on the cube lane and read on the vector lane (C2V). The reverse direction — a GM tensor written on the vector lane (AIV) and consumed on the cube lane (AIC), i.e. V2C — is intentionally left unfenced (CollectGmCrossLaneSyncs:if (store.side != CoreSide::AIC) continue;,src/ir/transforms/expand_mixed_kernel_pass.cpp~line 616) because V2C transport needs V->C fractal adaptation.Request: automatically synchronize the V2C direction too — either by emitting a V2C
tpush/tpopfence (with the fractal adaptation), or by injecting apl.system.syncallwhen a V2C cross-lane GM dependency has no established fence/barrier — so producer/consumer ordering is guaranteed by the compiler rather than by a hand-written barrier.Motivation / Use Case
Follow-up to #1909, which fixed the PTO codegen crash where a GM tensor written inside a
split_aivregion and consumed by a cube matmul left a dangling__FREE_VAR(the fix repoints the cross-half reference to the shared base parameter). That fix makes the V2C produce/consume pattern compile, but it does not add a happens-before edge for the V2C direction.Consequently, a fenceless V2C GM read-after-write can let the cube lane read the GM scratch before the vector lane writes it → a silent wrong result rather than a loud failure. Today, correctness for these kernels (e.g. the in-kernel rope->attn fusion) relies on the author placing an explicit
pl.system.syncallbarrier between the producer and consumer phases. Auto-fencing would make the safe behavior automatic and prevent a future fenceless V2C kernel from compiling into a race.An automated reviewer flagged this as P1 on #1909 (left as an open follow-up thread at
src/ir/transforms/expand_mixed_kernel_pass.cpp:1243).Proposed API / Behavior
Three candidate directions (to be decided during design):
CollectGmCrossLaneSyncsto also handlestore.side == AIVwith the consumer on AIC, emitting the V2Ctpush/tpopfence with the required V->C fractal adaptation (tile.moveto NZ/ZN beforetpush_to_aic, fractal-typedtpop_from_aiv).pl.system.syncall(or equivalent cross-core barrier) covering the producer->consumer ordering.pl.system.syncallbetween the producingsplit_aivregion and the cube consumer"), instead of compiling a racy kernel.Pointers:
src/ir/transforms/expand_mixed_kernel_pass.cpp—CollectGmCrossLaneSyncs(C2V-only gate at ~line 616:if (store.side != CoreSide::AIC) continue;).BuildGmOriginMap/RemapDanglingGmRefsToParam) is what now makes V2C compile.Alternatives Considered
pl.system.syncallbarrier between the producingsplit_aivregion and the cube consumer. This works (and is what the shipped fusion kernels do), but it is easy to omit, and omission produces a silent race rather than a diagnostic.Additional Context
ExpandMixedKernel).SplitAivScopeStmt), [RFC] Explicit AIV split: pl.split_aiv + aiv_shard/aic_gather replacing SplitVectorKernel auto-analysis #1820 (explicit AIV-split DSL), [RFC] Define cross-platform semantics for split-axis reduction and GM-mediated extra capabilities in SplitVectorKernel #1034 (GM-mediated split-axis reduction).syncall-fenced kernels; the risk is a future fenceless V2C kernel compiling into a race.