pub struct CFGContext {
pub edges: HashMap<UOpKey, Arc<UOp>>,
}Expand description
Control flow graph context for linearization.
Tracks ordering edges between sibling RANGE operations to ensure proper linearization order when loops are at the same nesting level.
Based on Tinygrad’s CFGContext which tracks three relationships between ranges:
- nested: END y is a dependency of END x AND RANGE x is a dependency of END y
- dependent: END y is a dependency of END x AND RANGE x is NOT a dependency of END y
- independent: END y is NOT a dependency of END x
§Control Flow Edges
When multiple ENDs exist at the same nesting level (siblings), they need to be ordered consistently. CFGContext computes edges where:
- Each RANGE points to its predecessor (either the parent’s RANGE or another END)
- Edges ensure sequential execution of sibling loops
§Example
RANGE(i) → ... → END(i) // first loop
RANGE(j) → ... → END(j) // second loop (sibling)
RANGE(k) → ... → END(k) // third loop (sibling)
CFGContext edges:
RANGE(j) → END(i) // j's RANGE depends on i's END
RANGE(k) → END(j) // k's RANGE depends on j's ENDFields§
§edges: HashMap<UOpKey, Arc<UOp>>Maps RANGE → predecessor (previous sibling END or parent’s RANGE).
The predecessor is the operation that must complete before this RANGE can begin execution.
Implementations§
Source§impl CFGContext
impl CFGContext
Sourcepub fn new(sink: &Arc<UOp>) -> Self
pub fn new(sink: &Arc<UOp>) -> Self
Build a control flow context from a kernel AST.
Analyzes the graph to find sibling ENDs at the same nesting level and creates ordering edges between their RANGEs.
§Algorithm (from Tinygrad linearizer.py:59-91)
- Build transitive deps map (RANGE/END add themselves to deps)
- Build nesting map: which END/SINK nests each END
- Group siblings by parent
- Order siblings by dependency count (fewer deps = earlier)
- Create edges: RANGE of later sibling → predecessor (END or parent’s RANGE)
Sourcepub fn get_predecessor(&self, range: &Arc<UOp>) -> Option<&Arc<UOp>>
pub fn get_predecessor(&self, range: &Arc<UOp>) -> Option<&Arc<UOp>>
Get the predecessor for a given RANGE operation.
Returns Some(predecessor) if this RANGE has a sibling that must
execute before it, None if this is the first RANGE at its level.
Sourcepub fn has_edges(&self) -> bool
pub fn has_edges(&self) -> bool
Check if this context has any control flow edges.
Returns true if there are sibling RANGEs that require ordering.
Sourcepub fn edge_count(&self) -> usize
pub fn edge_count(&self) -> usize
Get the number of control flow edges.
Trait Implementations§
Source§impl Debug for CFGContext
impl Debug for CFGContext
Source§impl Default for CFGContext
impl Default for CFGContext
Source§fn default() -> CFGContext
fn default() -> CFGContext
Auto Trait Implementations§
impl Freeze for CFGContext
impl !RefUnwindSafe for CFGContext
impl Send for CFGContext
impl Sync for CFGContext
impl Unpin for CFGContext
impl UnsafeUnpin for CFGContext
impl !UnwindSafe for CFGContext
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more