Skip to main content

ExprGraph

Struct ExprGraph 

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

Arena-based expression graph with structural interning.

Identical subexpressions always return the same ExprId — this gives automatic common subexpression elimination (CSE) for free.

Implementations§

Source§

impl ExprGraph

Source

pub fn to_c_f64(&self, outputs: &[ExprId], n_inputs: usize) -> ComputeKernel

Generate a plain-C kernel in f64: void k0(const double* inputs, double* outputs, int count). Literals keep full precision.

Source

pub fn to_kernel( &self, outputs: &[ExprId], n_inputs: usize, dialect: Dialect, ) -> ComputeKernel

Generate a compute kernel for the given dialect.

Each work item reads n_inputs f32 values and writes outputs.len() f32 values. Shared subexpressions are computed once per thread.

Source§

impl ExprGraph

Source

pub fn compile(&self, expr: ExprId) -> CompiledExpr

Compile a single expression to a closure &[f64] -> f64.

Shared subexpressions (from interning) are computed once. Dead nodes (not reachable from output) are skipped.

Source

pub fn compile_many(&self, exprs: &[ExprId]) -> CompiledMany

Compile multiple output expressions to a single closure.

Writes results into the output slice.

Source

pub fn live_set(&self, outputs: &[ExprId]) -> HashSet<usize>

Find all node indices reachable from the given outputs.

Source§

impl ExprGraph

Source

pub fn diff(&mut self, expr: ExprId, var: u16) -> ExprId

Differentiate expr with respect to Var(var).

Returns a new ExprId in the same graph. Uses memoization to avoid recomputing derivatives of shared subexpressions.

Source§

impl ExprGraph

Source

pub fn fmt_expr(&self, expr: ExprId) -> String

Format an expression as a human-readable string.

Source§

impl ExprGraph

Source

pub fn eval<S: Scalar>(&self, expr: ExprId, inputs: &[S]) -> S

Evaluate an expression with concrete scalar inputs.

inputs[n] provides the value for Var(n). Walks the graph in topological order (which is just index order, since children are always created before parents).

Source

pub fn eval_many<S: Scalar>(&self, exprs: &[ExprId], inputs: &[S]) -> Vec<S>

Evaluate multiple output expressions, sharing intermediate values.

Source§

impl ExprGraph

Source

pub fn new() -> Self

Create a new graph pre-populated with ZERO, ONE, TWO.

Source

pub fn len(&self) -> usize

Total number of nodes in the graph.

Source

pub fn is_empty(&self) -> bool

Whether the graph is empty (it never is after construction).

Source

pub fn node(&self, id: ExprId) -> Node

Look up the node for an ExprId.

Source

pub fn nodes_slice(&self) -> &[Node]

Read-only access to the node arena for serialization.

Source

pub fn var(&mut self, n: u16) -> ExprId

Create a variable node.

Source

pub fn lit(&mut self, v: f64) -> ExprId

Create a literal node.

Source

pub fn add(&mut self, a: ExprId, b: ExprId) -> ExprId

Add two expressions.

Source

pub fn mul(&mut self, a: ExprId, b: ExprId) -> ExprId

Multiply two expressions.

Source

pub fn neg(&mut self, a: ExprId) -> ExprId

Negate an expression.

Source

pub fn recip(&mut self, a: ExprId) -> ExprId

Reciprocal (1/x).

Source

pub fn sqrt(&mut self, a: ExprId) -> ExprId

Square root.

Source

pub fn sin(&mut self, a: ExprId) -> ExprId

Sine.

Source

pub fn atan2(&mut self, y: ExprId, x: ExprId) -> ExprId

atan2(y, x).

Source

pub fn exp2(&mut self, a: ExprId) -> ExprId

Base-2 exponential.

Source

pub fn log2(&mut self, a: ExprId) -> ExprId

Base-2 logarithm.

Source

pub fn select(&mut self, cond: ExprId, a: ExprId, b: ExprId) -> ExprId

Branchless select: returns a if cond > 0, else b.

Source§

impl ExprGraph

Source

pub fn vjp( &mut self, outputs: &[ExprId], seeds: &[ExprId], n_vars: usize, ) -> Vec<ExprId>

The vector-Jacobian product seedᵀ ∂outputs/∂vars as new expressions in this graph: entry k is Σ_i seeds[i] ∂outputs[i]/∂Var(k) for k < n_vars. One reverse sweep over the live nodes, so the cost is a small multiple of evaluating outputs whatever n_vars is (forward diff is one sweep per variable). Seeds are expressions too (typically fresh Vars past the inputs), so one compiled graph serves every seed. Select passes gradient to the taken branch only, as diff does.

Source§

impl ExprGraph

Source

pub fn simplify(&mut self, expr: ExprId) -> ExprId

Simplify an expression by applying rewrite rules to fixpoint.

Bottom-up: simplify children first, then match parent. Iterates until no more changes occur.

Source§

impl ExprGraph

Source

pub fn deps(&self, expr: ExprId) -> u64

Compute a bitmask of which Var(n) indices appear in expr.

Bit n is set if Var(n) is reachable from expr. Supports up to 64 variables.

Source

pub fn jacobian_sparsity(&self, outputs: &[ExprId], n_vars: usize) -> Vec<u64>

Compute the Jacobian sparsity pattern.

Returns one u64 bitmask per output expression. Bit j of result[i] is set if outputs[i] depends on Var(j).

Source§

impl ExprGraph

Source

pub fn to_wgsl_split( &self, outputs: &[ExprId], n_inputs: usize, max_nodes: usize, ) -> SplitKernels

to_kernel for WGSL, cut into kernels of at most max_nodes evaluated nodes each (topological order); a value used outside the kernel that computes it goes through scratch.

Source

pub fn to_wgsl_split_f64( &self, outputs: &[ExprId], n_inputs: usize, max_nodes: usize, ) -> SplitKernels

to_wgsl_split in f64 (buffers, scratch and arithmetic), for a device with wgpu’s SHADER_F64. Vulkan has no f64 sin/exp2/log2/atan2, so those come from WGSL helpers accurate to a few ulp. A buffer of n values takes 2n f32 slots.

Source§

impl ExprGraph

Source

pub fn to_wgsl(&self, outputs: &[ExprId], n_inputs: usize) -> WgslKernel

Generate a WGSL compute shader that evaluates expressions in parallel.

Each work item reads n_inputs values and writes outputs.len() values. The generated shader uses f32 (GPU native). Shared subexpressions are computed once per thread.

The caller handles device/pipeline/dispatch (no wgpu dependency here).

Trait Implementations§

Source§

impl Clone for ExprGraph

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Default for ExprGraph

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

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<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
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> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
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.