tensor_forge/lib.rs
1//! `tensor_forge` is a minimal compute graph runtime for tensor operations.
2//!
3//! The crate provides:
4//! - [`Graph`], a directed acyclic compute graph of tensor operations,
5//! - [`Executor`], a deterministic execution engine for evaluating graphs,
6//! - [`KernelRegistry`], a pluggable registry mapping [`OpKind`] values to kernels,
7//! - [`Tensor`], the runtime tensor value type used for inputs and outputs.
8//!
9//! Graphs are constructed by adding input and operation nodes, marking one or more
10//! nodes as outputs, and then executing the graph with runtime input bindings.
11//!
12//! # Core workflow
13//!
14//! A typical workflow is:
15//! 1. create a [`Graph`],
16//! 2. add input and operation nodes,
17//! 3. mark output nodes,
18//! 4. construct an [`Executor`] with a [`KernelRegistry`],
19//! 5. execute the graph with `(NodeId, Tensor)` input bindings.
20//!
21//! # Examples
22//!
23//! ```
24//! use tensor_forge::{Executor, Graph, KernelRegistry, Tensor};
25//!
26//! let mut g = Graph::new();
27//! let a = g.input_node(vec![2, 2]);
28//! let b = g.input_node(vec![2, 2]);
29//! let out = g.add(a, b).expect("Valid add operation should succeed");
30//! g.set_output_node(out)
31//! .expect("Setting output node should succeed");
32//!
33//! let a_tensor = Tensor::zeros(vec![2, 2]).expect("Tensor allocation should succeed");
34//! let b_tensor = Tensor::zeros(vec![2, 2]).expect("Tensor allocation should succeed");
35//! let expected = Tensor::from_vec(vec![2, 2], vec![0_f64, 0_f64, 0_f64, 0_f64]).expect("Tensor allocation should
36//! succeed");
37//!
38//! let exec = Executor::new(KernelRegistry::default()); // imports default kernel operation mappings
39//! let outputs = exec
40//! .execute(&g, vec![(a, a_tensor), (b, b_tensor)])
41//! .expect("Execution should succeed");
42//!
43//! // `outputs` now contains the resulting tensors of nodes marked as outputs
44//! assert!(outputs.contains_key(&out));
45//!
46//! let output_tensor: &Tensor = &outputs[&out];
47//! assert_eq!(output_tensor.shape(), expected.shape());
48//! assert_eq!(output_tensor.data().len(), expected.data().len());
49//! assert_eq!(output_tensor.data(), expected.data());
50//! ```
51//! See the `examples/` directory for larger runnable examples, including:
52//! - `add_graph.rs` # introductory example
53//! - `branching_graph.rs` # complex chain example with `Add`, `ReLU`, `MatMul`
54//! - `feedforward_neural_net.rs` # programmatic neural network generation
55//! - `custom_kernel.rs` # defining custom kernels
56//!
57//! # Module overview
58//!
59//! - [`executor`] contains graph execution and execution-time errors.
60//! - [`graph`] contains graph construction, validation, and topology utilities.
61//! - [`kernel`] defines the kernel trait and kernel-level errors.
62//! - [`node`] defines graph node identifiers and node metadata.
63//! - [`op`] defines supported operation kinds.
64//! - [`registry`] contains the kernel registry.
65//! - [`tensor`] defines the tensor value type.
66#![deny(clippy::all)]
67#![deny(clippy::pedantic)]
68#![deny(missing_docs)]
69
70pub mod executor;
71pub mod graph;
72pub mod kernel;
73pub mod node;
74pub mod op;
75pub mod registry;
76pub mod tensor;
77
78pub use executor::{ExecutionError, Executor};
79pub use graph::{Graph, GraphError};
80pub use kernel::{Kernel, KernelError};
81pub use node::{Node, NodeId};
82pub use op::OpKind;
83pub use registry::KernelRegistry;
84pub use tensor::Tensor;