Skip to main content

FiberBuilder

Struct FiberBuilder 

Source
pub struct FiberBuilder { /* private fields */ }
Expand description

Per-fiber op builder. Owns its own kernels. No locks, no synchronization, no contention.

Created via OpBuilder::create_fiber_builder() at fiber startup.

Every kernel here may be on any engine: the main kernel and the per-op kernels run on the fiber engine where an image is available (crate::fiber_engine) and on the interpreter otherwise. Each is paired with the interpreter program it runs or was imaged from, which shares its input and output indices: names resolve on the program once, and the kernel is driven by index.

Implementations§

Source§

impl FiberBuilder

Source

pub fn new(parent: &ScopeKernel) -> Self

Create a new fiber builder whose main kernel is the parent’s own image bound under the parent, on the parent’s engine.

Source

pub fn with_image( parent: &ScopeKernel, image: Option<Arc<dyn KernelProgram>>, ) -> Self

Create a new fiber builder whose main kernel runs image — the fiber engine’s image of parent’s program — bound under parent; the parent’s own image when image is None. Per-fiber state is fresh; cell handles are Arc-shared with the parent so writes propagate to the workload-root through the cascade.

Source

pub fn with_scope( parent: &ScopeKernel, image: Option<Arc<dyn KernelProgram>>, scope_values: Vec<(String, Value)>, ) -> Self

Self::with_image, binding scope_values into the main kernel as it is built, before its consts initialize, and remembering them for the stanza-boundary Self::reset_captures.

Source

pub fn attach_dispenser_kernels(&mut self, dispensers: &[Arc<dyn OpDispenser>])

SRD-68 Push 3 — populate this fiber’s per-op kernel slots from the activity’s dispenser registry. Walks each dispenser, calls dispenser.canonical_kernel() to get the dispenser-owned canonical kernel (when present), and binds a per-fiber kernel of its program under this fiber’s main kernel. Slot positions match the dispenser registry’s order so cycle-time dispatch can index by template_idx. Dispensers that return None (no GK needs) get a None slot — ExecCtx::wires falls back to the NullWireSource baseline for those cycles.

A per-op kernel is instantiated from its op-template module on the fiber engine when the fiber has one for the canonical’s program, carrying the module’s result: write-throughs; any other canonical program runs on the interpreter.

Called once per fiber, right after spawn, before any cycles run. Idempotent: re-attaching with the same registry is a no-op since canonical kernels are stable across phase activation.

Source

pub fn cycle_wires(&mut self, template_idx: usize) -> CycleWires<'_>

The cycle-time wire surface for the firing dispenser at template_idx: its per-fiber kernel, or this fiber’s main kernel when the dispenser exposes no canonical kernel (the flattened path).

Source

pub fn main_wires(&mut self) -> CycleWires<'_>

The cycle-time wire surface over this fiber’s main kernel.

Source

pub fn per_op_kernel(&self, template_idx: usize) -> Option<&dyn Kernel>

Get the per-fiber kernel for the firing dispenser at template_idx. Returns None when the dispenser exposes no canonical kernel (adapters with no Polydat needs); callers fall back to the NullWireSource baseline.

Source

pub fn main_kernel(&self) -> &dyn Kernel

This fiber’s main kernel.

Source

pub fn program(&self) -> &Arc<PolydatProgram> ⓘ

The interpreter program this fiber’s main kernel runs or was imaged from.

Source

pub fn set_inputs(&mut self, coords: &[u64])

Set coordinates and begin a new evaluation scope.

Bounded by each kernel’s coordinate count: the slice is truncated to the program’s declared coordinate count before being written. A phase kernel with no coordinates (e.g. all bindings are invariant within the stanza, only externs declared) has coord_count = 0, so this becomes a no-op rather than clobbering the extern slots that follow.

SRD-13d Phase 9: the same coordinates are also written to every per-op-template kernel that declares them as coords. Each kernel binds its own input slot for cycle (cascaded from parent) so per-cycle propagation is a per-kernel set_inputs, not a chain walk.

Source

pub fn set_source_item(&mut self, item: &SourceItem)

Feed a source item into the fiber’s kernels.

Sets the ordinal as the coordinate input and injects field projections into the appropriate input slots (e.g. base__ordinal, base__vector). The ordinal write is skipped by kernels whose programs declare no coordinates (only externs and stanza-invariant bindings) rather than clobbering an extern slot. Field projections always write by name, so they’re safe regardless of coordinate count.

SRD-13d Phase 9: ordinal + fields propagate to every op-template kernel that declares matching slots.

Source

pub fn reset_captures(&mut self)

Reset capture inputs to defaults. Called at stanza boundaries to prevent capture leakage across stanzas. Coordinates and cell-bound slots are not reset. Scope-bound iter-var inputs (set by OpBuilder::create_fiber_builder) are re-applied after the reset so the iteration’s bound values survive the boundary.

Source

pub fn invalidate_all(&mut self)

Invalidate all state: every step, a side channel included, runs again when next pulled. Provides “clean slate” semantics.

Source

pub fn capture(&mut self, name: &str, value: Value) -> bool

Store a captured value into the main kernel’s input slot name. Returns true when the slot exists and took the value, false when the program has no such input or the value could not be converted to its type (value dropped).

Source

pub fn write_op_template_input_for_idx( &mut self, template_idx: usize, name: &str, value: Value, ) -> bool

SRD-68 Push 5d: position-indexed write into the per-fiber op-template kernel slot. Used by the cycle dispatch’s post-execute capture flow to feed result-binding inputs (body / count / ok and any captures) into the kernel before Self::commit_op_template_write_throughs_for_idx fans the computed values up through parent shared cells.

No-op returning false when (a) the op didn’t materialise a kernel (flattened op-template), or (b) the kernel doesn’t declare an input slot for name (the closure-binding economy dropped it because the source doesn’t reference it), or (c) the value could not be converted to the slot’s type.

Source

pub fn commit_op_template_write_throughs_for_idx( &mut self, template_idx: usize, ) -> Result<(), String>

SRD-68 Push 5d: position-indexed Rule 2 write-through commit. Pulls every __write_<X> and stores its value through the cell-bound input slot for <X>, propagating each result- binding LHS value to the parent’s SharedCell (and from there to any sibling phase that imports the same name). No-op when the kernel carries no write-throughs (typical for ops without result:).

Errors when a write-through violates cell type stability (scope_model.md §“Type stability”) — surfaced by the fiber loop as a phase-stopping workload bug (it is deterministic: every subsequent cycle would repeat it).

Source

pub fn pull_all_op_template_outputs_for_idx(&mut self, template_idx: usize)

Per-cycle: pull the op-template kernel’s side-effecting outputs at template_idx so side-effecting nodes (log_info and friends) actually evaluate. Without this, captured wires whose only consumer is a write-through are pulled by commit_write_throughs, but captured wires that aren’t shared with a parent never get pulled — their compute chain (including any side-effecting nodes inside it) stays dormant, and the diagnostic the workload asked for never fires.

Only outputs whose cone contains a Purity::SideChannel node are pulled (the set is precomputed at attach time, PolydatProgram::outputs_with_side_effects). A side-effect-free output is not pulled here: re-evaluating it would do nothing, and for a volatile metric reader (a metricsql_* / metric objective binding) it would issue a live metrics query every cycle. Such values are evaluated only when actually consumed. No-op when the kernel has no side-effecting outputs.

Source

pub fn resolve_pulls(&mut self, plan: &PullPlan) -> ResolvedPulls

Materialize a PullPlan against this fiber’s main kernel. O(plan_len) on the hot path, no name hashing — the plan holds pre-resolved indices.

This is the cycle-time read path used by every wrapper that holds PullHandles registered into the corresponding ScopeFixture at init (SRD 31 §“Pull plan vs bind plan”, SRD 32 §“Init-Time Fixture and Consumer Self-Registration”).

Source

pub fn resolve_pulls_for_idx( &mut self, template_idx: usize, plan: &PullPlan, ) -> ResolvedPulls

SRD-68 Push 5d resolve path — picks the right kernel for the dispenser at template_idx and resolves the plan against it. When a per-fiber op-template kernel was instanced for that position (every adapter exposes canonical_kernel() so this is the typical case), it is used; otherwise the plan resolves against the fiber’s main kernel (the flattened op-template path). Either way the plan is checked against the interpreter program the kernel was imaged from, whose indices it holds.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
where F: FnOnce(&Self) -> bool,

Converts 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
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more