
Scan along a named dim, preserving it. Barrier over over.
ScanNode.RdCreated by scan_over(). The IR shape between MapNode and
ReduceNode: carry state sequentially along one non-spatial axis
while emitting a same-length series (Kalman smoothers, EWMA, IIR
filters, cumulative ops). The output grid is the parent grid
unchanged (the scanned axis survives), optionally with a dtype
override.
Arguments
- id
Integer node id (assigned by
graph_add()).- parents
Integer ids of parent nodes.
- grid
Output
GridSpecof this node.- role
Optional semantic role tag (e.g. "mask", set by
mask()). Pure metadata: never read by the planner or executors; surfaced bydraw()andplan_view().- over
Single dim name to scan along (
"t"or"band").- direction
One of
"forward","backward","bidir".- fn
Length-1 list holding the scan body
fn(xs, margin).- dtype
Length-0 (parent's dtype) or length-1 dtype override.
Details
The body kernel is fn(xs, margin) -> y: xs is the LIST of parent
chunk values (length >= 1; multi-parent scans read several cubes in
lockstep), margin is the 1-based position of the scanned axis in
the chunk's dimension order (outer dims first, then y, x), and y
has the same shape as xs[[1]]. Inside, the body uses
g_scan() to carry state along margin; everything else in the
chunk (the spatial axes) is batched through the carry. Like a custom
reducer, a scan cannot be decomposed across spatial chunks, so it is
supported over t/band only (each spatial chunk holds the full
axis).
direction is declarative metadata (drawn, hashed into the kernel
signature): "bidir" bodies run a forward and a reverse g_scan()
internally as ONE fused kernel, so forward state never crosses a node
boundary.