Skip to content

[Feature] Auto-fence AIV->AIC (V2C) cross-lane GM read-after-write in ExpandMixedKernel #1911

Description

@Hzfengsy

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    Status
    Backlog

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions