#[non_exhaustive]pub enum Node {
Show 20 variants
Let {
name: Ident,
value: Expr,
},
Assign {
name: Ident,
value: Expr,
},
Store {
buffer: Ident,
index: Expr,
value: Expr,
},
If {
cond: Expr,
then: Vec<Node>,
otherwise: Vec<Node>,
},
Loop {
var: Ident,
from: Expr,
to: Expr,
body: Vec<Node>,
},
IndirectDispatch {
count_buffer: Ident,
count_offset: u64,
},
AsyncLoad {
source: Ident,
destination: Ident,
offset: Box<Expr>,
size: Box<Expr>,
tag: Ident,
},
AsyncStore {
source: Ident,
destination: Ident,
offset: Box<Expr>,
size: Box<Expr>,
tag: Ident,
},
AsyncWait {
tag: Ident,
},
Trap {
address: Box<Expr>,
tag: Ident,
},
Resume {
tag: Ident,
},
AllReduce {
buffer: Ident,
op: CollectiveOp,
group: CommGroup,
},
AllGather {
input: Ident,
output: Ident,
group: CommGroup,
},
ReduceScatter {
input: Ident,
output: Ident,
op: CollectiveOp,
group: CommGroup,
},
Broadcast {
buffer: Ident,
root: u32,
group: CommGroup,
},
Return,
Barrier {
ordering: MemoryOrdering,
},
Block(Vec<Node>),
Region {
generator: Ident,
source_region: Option<GeneratorRef>,
body: Arc<Vec<Node>>,
},
Opaque(Arc<dyn NodeExtension>),
}Expand description
Statement nodes - execute effects.
Variants (Non-exhaustive)§
This enum is marked as non-exhaustive
Let
Assign
Store
If
Loop
IndirectDispatch
AsyncLoad
AsyncStore
AsyncWait
Trap
Resume
AllReduce
AllGather
ReduceScatter
Broadcast
Return
Barrier
Fields
ordering: MemoryOrderingBlock(Vec<Node>)
Region
Opaque(Arc<dyn NodeExtension>)
Implementations§
Source§impl Node
impl Node
Sourcepub fn store(buffer: impl Into<Ident>, index: Expr, value: Expr) -> Self
pub fn store(buffer: impl Into<Ident>, index: Expr, value: Expr) -> Self
buffer[index] = value;
§Examples
use vyre::ir::{Expr, Node};
let _ = Node::store("out", Expr::u32(0), Expr::u32(1));Sourcepub fn if_then_else(cond: Expr, then: Vec<Self>, otherwise: Vec<Self>) -> Self
pub fn if_then_else(cond: Expr, then: Vec<Self>, otherwise: Vec<Self>) -> Self
if cond { then } else { otherwise }
§Examples
use vyre::ir::{Expr, Node};
let _ = Node::if_then_else(Expr::bool(true), vec![Node::Return], vec![]);Sourcepub fn if_then(cond: Expr, then: Vec<Self>) -> Self
pub fn if_then(cond: Expr, then: Vec<Self>) -> Self
if cond { then }
§Examples
use vyre::ir::{Expr, Node};
let _ = Node::if_then(Expr::bool(true), vec![Node::Return]);Sourcepub fn loop_for(
var: impl Into<Ident>,
from: Expr,
to: Expr,
body: Vec<Self>,
) -> Self
pub fn loop_for( var: impl Into<Ident>, from: Expr, to: Expr, body: Vec<Self>, ) -> Self
for var in from..to { body }
§Examples
use vyre::ir::{Expr, Node};
let _ = Node::loop_for("i", Expr::u32(0), Expr::u32(4), vec![]);Sourcepub fn loop_(
var: impl Into<Ident>,
from: Expr,
to: Expr,
body: Vec<Self>,
) -> Self
pub fn loop_( var: impl Into<Ident>, from: Expr, to: Expr, body: Vec<Self>, ) -> Self
for var in from..to { body }
§Examples
use vyre::ir::{Expr, Node};
let node = Node::loop_("i", Expr::u32(0), Expr::u32(4), vec![Node::Return]);
assert!(matches!(node, Node::Loop { .. }));Sourcepub fn forever(body: Vec<Self>) -> Self
pub fn forever(body: Vec<Self>) -> Self
Effectively-infinite loop used by persistent kernels (megakernel,
event loops, streaming). Lowers to Node::Loop with
from: 0, to: u32::MAX. At 1 µs per iteration u32::MAX is ~68
years - for all practical purposes infinite. The inner body
drives termination via Node::Return or by observing an
atomic shutdown flag the host sets.
Linus principle: one enum variant (Node::Loop) handles both
bounded and persistent cases. No cascade of match arms through
every pass; no new wire-format tag. An optimizer pass
that wants to distinguish “truly unbounded” from “large bound”
inspects the to expression.
§Examples
use vyre::ir::Node;
let persistent = Node::forever(vec![Node::Return]);
assert!(matches!(persistent, Node::Loop { .. }));Sourcepub fn block(nodes: Vec<Self>) -> Self
pub fn block(nodes: Vec<Self>) -> Self
Sequence of statements.
§Examples
use vyre::ir::Node;
assert!(matches!(Node::block(vec![Node::Return]), Node::Block(_)));Sourcepub const fn return_() -> Self
pub const fn return_() -> Self
Early return from the entry point.
§Examples
use vyre::ir::Node;
assert!(matches!(Node::return_(), Node::Return));Sourcepub const fn barrier() -> Self
pub const fn barrier() -> Self
Workgroup barrier statement.
§Examples
use vyre::ir::Node;
assert!(matches!(Node::barrier(), Node::Barrier { .. }));Sourcepub const fn barrier_with_ordering(ordering: MemoryOrdering) -> Self
pub const fn barrier_with_ordering(ordering: MemoryOrdering) -> Self
Workgroup barrier statement with explicit memory ordering.
Sourcepub fn call(op_id: impl Into<Ident>, args: Vec<Expr>) -> Self
pub fn call(op_id: impl Into<Ident>, args: Vec<Expr>) -> Self
Statement-level invocation of another registered op by stable op id.
Represented as a named Node::Region whose generator is
the callee’s op id and whose body is an internal sequence of
Node::Let { name: "arg{i}", value: <arg_expr> } bindings.
Every backend already handles Node::Region - the op-registry
inliner walks the arg binds, substitutes them into the callee’s
fragment, and splices the result in place. No new IR variant
is introduced, and the arg values remain fully visible to CSE,
DCE, and constant folding through the let-chain.
Sourcepub fn indirect_dispatch(
count_buffer: impl Into<Ident>,
count_offset: u64,
) -> Self
pub fn indirect_dispatch( count_buffer: impl Into<Ident>, count_offset: u64, ) -> Self
Command-level indirect dispatch metadata.
§Examples
use vyre::ir::Node;
let node = Node::indirect_dispatch("counts", 0);
assert!(matches!(node, Node::IndirectDispatch { .. }));Sourcepub fn async_load_gpu_driven(
source: impl Into<Ident>,
destination: impl Into<Ident>,
offset: Expr,
size: Expr,
tag: impl Into<Ident>,
) -> Self
pub fn async_load_gpu_driven( source: impl Into<Ident>, destination: impl Into<Ident>, offset: Expr, size: Expr, tag: impl Into<Ident>, ) -> Self
Begin an asynchronous transfer stream region that names its own operands, so the GPU drives the transfer.
§Examples
use vyre::ir::{Node, Expr};
let node = Node::async_load_gpu_driven("ssd", "vram", Expr::u32(0), Expr::u32(1024), "tag-0");
assert!(matches!(node, Node::AsyncLoad { .. }));Sourcepub fn async_load(tag: impl Into<Ident>) -> Self
pub fn async_load(tag: impl Into<Ident>) -> Self
Begin an asynchronous transfer stream region carrying only a tag.
The host drives the transfer and knows the buffers out of band, so the
node records placeholder operands. Emit
Node::async_load_gpu_driven when the source, destination, offset,
and size are known in the IR.
Sourcepub fn async_store(
source: impl Into<Ident>,
destination: impl Into<Ident>,
offset: Expr,
size: Expr,
tag: impl Into<Ident>,
) -> Self
pub fn async_store( source: impl Into<Ident>, destination: impl Into<Ident>, offset: Expr, size: Expr, tag: impl Into<Ident>, ) -> Self
Begin an asynchronous store transfer stream region (GPU-driven).
Sourcepub fn async_wait(tag: impl Into<Ident>) -> Self
pub fn async_wait(tag: impl Into<Ident>) -> Self
Wait for an asynchronous transfer stream region.
§Examples
use vyre::ir::Node;
let node = Node::async_wait("stage-a");
assert!(matches!(node, Node::AsyncWait { .. }));Sourcepub fn trap(address: Expr, tag: impl Into<Ident>) -> Self
pub fn trap(address: Expr, tag: impl Into<Ident>) -> Self
Trap the current execution lane (GPU-initiated page fault).
Sourcepub fn opaque(node: impl NodeExtension) -> Self
pub fn opaque(node: impl NodeExtension) -> Self
Wrap a downstream extension statement node.
Sourcepub fn opaque_arc(node: Arc<dyn NodeExtension>) -> Self
pub fn opaque_arc(node: Arc<dyn NodeExtension>) -> Self
Wrap a shared downstream extension statement node.