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§
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.