Skip to main content

FusedOpEntry

Struct FusedOpEntry 

Source
pub struct FusedOpEntry {
    pub id: FusedOpId,
    pub name: &'static str,
    pub family: FusedOpFamily,
    pub pattern: SubgraphPattern,
    pub decompose: fn(&mut Graph, NodeId, &FusedOpParams) -> NodeId,
    pub backward: BackwardKind,
    pub shape_rule: fn(&[Shape], &FusedOpParams) -> Shape,
    pub dtype_rule: fn(&[DType], &FusedOpParams) -> DType,
    pub output_views: Option<fn(&[Shape], &[DType], &FusedOpParams) -> Vec<OutputViewSpec>>,
    pub destructive_input: Option<usize>,
}
Expand description

Per-fused-op metadata. Identity, pattern, decomposition, backward, shape/dtype rules. The kernel-side metadata (per-backend KernelRef + cost + PrecisionGuarantee + caps) lives in fuel-storage::fused and is joined to this entry by FusedOpEntry::id.

Fields§

§id: FusedOpId

Stable id for this fused op.

§name: &'static str

Stable human-readable name. Shows up in op_short_name, error messages, telemetry.

§family: FusedOpFamily

Categorical bucket. Used by telemetry and for cost-model defaults.

§pattern: SubgraphPattern

Canonical primitive subgraph this fused op represents. Used by fusion rules to recognize the pattern in a base map.

§decompose: fn(&mut Graph, NodeId, &FusedOpParams) -> NodeId

Decompose a fused-op node into its primitive subgraph. Used by lowering rules (and by autograd when Self::backward is BackwardKind::Decompose).

Contract: the function appends primitive nodes to graph and returns the NodeId of the new root that replaces the fused node identified by the second argument. The fused node itself remains in the arena; the driver rewrites consumer edges to point at the returned id.

§backward: BackwardKind

Backward identity for this fused op.

§shape_rule: fn(&[Shape], &FusedOpParams) -> Shape

Output shape rule, computed from input shapes and params. For a multi-output op, this must return slot 0’s shape (which is also the primary Node::shape of the producer).

§dtype_rule: fn(&[DType], &FusedOpParams) -> DType

Output dtype rule, computed from input dtypes and params. For a multi-output op, this must return slot 0’s dtype (which is also the primary Node::dtype of the producer).

§output_views: Option<fn(&[Shape], &[DType], &FusedOpParams) -> Vec<OutputViewSpec>>

Multi-output authoring contract (Option C, Session 2).

None for single-output ops (the default) — the op produces one logical output whose shape/dtype come from shape_rule and dtype_rule, and the realized storage is a plain non-bundled fuel_backend_contract::Storage.

Some(fn) for multi-output ops: returns the per-slot specs from input shapes + dtypes + params. The Graph and the realized storage allocator both consume the same Vec — set_output_views on Graph::push and allocate_bundled_storage at realization time — so the slot count and per-slot shapes/dtypes are a single source of truth.

Contract for multi-output ops:

  • output_views(...)[0].dtype MUST equal dtype_rule(...).
  • output_views(...)[0].shape MUST equal shape_rule(...).
  • The returned Vec must be non-empty; a “multi-output op” with one slot is just a single-output op (drop output_views).

Graph::push_fused (the multi-output-aware emit path that Session 2 introduces) checks these at graph-build time. The raw Graph::push + Graph::set_output_views route preserves the same invariants via set_output_views’s validation pass.

§destructive_input: Option<usize>

Which input index this fused op DESTROYS (mutates in place) on execution, or None if it is non-destructive (produces a fresh output, every input stays readable). Mandatory — declared here, beside decompose/ pattern, so a fused op cannot be registered without stating it (the recipe principle extended: a third required property of the same object). Op::destructive_input reads this via default_registry().entry(id) instead of a separate hand-maintained match, so the fact lives with the thing and cannot drift out of sync. A destructive op needs the scheduler to pin it after every non-destructive reader of the destroyed input (opt::derive_ordering); a wrong None here is a silent data race. There is deliberately no default: Option<usize> is the value (which input, or none), but the field itself must be set at every construction site. GAP-076.

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, 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> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

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