Skip to main content

Crate tang_expr

Crate tang_expr 

Source
Expand description

tang-expr — RISC expression graph for symbolic computation.

Builds computation graphs from generic Scalar code via a thread-local graph. Enables symbolic differentiation, sparsity detection, simplification, and multi-backend compilation (CPU closures, WGSL shaders).

§Quick start

use tang::Vec3;
use tang_expr::{trace, ExprId};

let (mut g, dot) = trace(|| {
    let a = Vec3::new(ExprId::var(0), ExprId::var(1), ExprId::var(2));
    let b = Vec3::new(ExprId::var(3), ExprId::var(4), ExprId::var(5));
    a.dot(b)
});

// Evaluate with concrete values
let result: f64 = g.eval(dot, &[1.0, 2.0, 3.0, 4.0, 5.0, 6.0]);
assert!((result - 32.0).abs() < 1e-10);

// Symbolic differentiation
let ddot_dx0 = g.diff(dot, 0);
let ddot_dx0 = g.simplify(ddot_dx0);

§Integer dialect

int::IntGraph is a separate, bit-exact 32-bit integer graph (i32/u32/bool, wrapping arithmetic, mul_wide, structured loops) with three lowerings that compute the same bits: the CPU interpreter (int::IntGraph::eval / int::Program), WGSL and Rust source.

use tang_expr::int::{IType, IntGraph};

// sum of i*i for i in 0..n
let mut g = IntGraph::new();
let n = g.param(0, IType::U32);
let zero = g.u32(0);
let s = g.for_range(n, &[zero], |g, i, s| {
    let sq = g.mul(i, i);
    vec![g.add(s[0], sq)]
});
assert_eq!(g.eval(&s, &[10], &[]), vec![285]);

let wgsl = g.to_wgsl_fn("sum_sq", &s);
assert!(wgsl.contains("fn sum_sq"));

Re-exports§

pub use graph::ExprGraph;
pub use node::ExprId;
pub use node::Node;

Modules§

codegen
Multi-dialect compute shader code generation.
compile
Compile expression graphs to optimized Rust closures.
diff
Symbolic differentiation.
display
Pretty-printing for expressions.
eval
Generic evaluation of expression graphs.
graph
Expression graph with structural interning (automatic CSE).
int
Integer dialect: exact 32-bit integer graphs with loop-carried state.
node
Expression node types and ExprId handle.
reverse
Reverse-mode differentiation: vector-Jacobian products as graphs.
simplify
Pattern-matched simplification rules.
sparsity
Sparsity analysis via dependency bitmasks.
split
One graph as several kernels, for graphs too large for one shader (a traced contact step’s adjoint is hundreds of thousands of nodes, which shader compilers take minutes and tens of GB to optimize, or reject).
wgsl
WGSL compute shader code generation.

Functions§

trace
Run a closure with a fresh graph, returning the graph and result.
with_graph
Access the thread-local graph.