pub struct Graph { /* private fields */ }Expand description
An executable computation graph. Implements Module for composability.
Built via FlowBuilder. Supports parallel execution of independent nodes,
observation of tagged outputs, profiling, and DOT/SVG visualization.
let g = FlowBuilder::from(Linear::new(4, 8)?)
.through(GELU)
.through(Linear::new(8, 2)?)
.build()?;
// Forward pass (graph implements Module)
let y = g.forward(&x)?;
// Observation
g.end_step();
g.end_epoch();
let loss_trend = g.trend("loss");
// Visualization
let dot = g.dot();
g.svg(Some("graph.svg"))?;Implementations§
Source§impl Graph
impl Graph
Sourcepub fn tagged(&self, tag: &str) -> Option<Variable>
pub fn tagged(&self, tag: &str) -> Option<Variable>
Get the output of a tagged node from the last forward pass.
Sourcepub fn collect(&self, tags: &[&str]) -> Result<()>
pub fn collect(&self, tags: &[&str]) -> Result<()>
Snapshot current scalar values of tagged nodes into the batch buffer. Returns an error if any tag has a non-scalar output — use collect_with() with an explicit reduction for non-scalar tags.
Sourcepub fn collect_with(&self, tags: &[&str], reduce: Reduce) -> Result<()>
pub fn collect_with(&self, tags: &[&str], reduce: Reduce) -> Result<()>
Snapshot tagged node values into the batch buffer using a reduction. Tag group names are automatically expanded to their members. Each tag’s output is reduced to a scalar and recorded individually.
Sourcepub fn record(&self, tag: &str, values: &[f64])
pub fn record(&self, tag: &str, values: &[f64])
Inject external scalar values into the batch buffer.
Recorded values accumulate per step and are averaged on
flush(). Use trend() to read epoch
history for training decisions (early stopping, LR scheduling).
For human-facing output (terminal, live dashboard), use
Monitor::log() instead.
Sourcepub fn record_scalar(&self, tag: &str, value: f64)
pub fn record_scalar(&self, tag: &str, value: f64)
Record a single scalar value. Convenience wrapper around record.
Sourcepub fn latest_metrics(&self) -> Vec<(String, f64)>
pub fn latest_metrics(&self) -> Vec<(String, f64)>
Return the latest epoch value for every tag in the epoch history.
Tree-aware: automatically collects from labeled child subgraphs
with dotted prefixes (e.g. a child labeled "subscan" with tag "ce"
appears as "subscan.ce"). Parent metrics come first, then children
in registration order.
Useful for bridging graph observation into
Monitor::log(). Returns an empty
vec if no epochs have been flushed yet.
Use latest_metrics_local() if you
only want this graph’s own metrics.
Sourcepub fn latest_metrics_local(&self) -> Vec<(String, f64)>
pub fn latest_metrics_local(&self) -> Vec<(String, f64)>
Return latest epoch values for this graph only, without child metrics.
Use this when you need only the local metrics (e.g. when children
report on a different cadence). See latest_metrics()
for the tree-recursive version.
Sourcepub fn collected(&self, tag: &str) -> Vec<f64>
pub fn collected(&self, tag: &str) -> Vec<f64>
Read raw batch buffer for a tag (all values since last flush).
Sourcepub fn flush(&self, tags: &[&str])
pub fn flush(&self, tags: &[&str])
Compute batch means, append to epoch history, clear batch buffer. Call once per epoch. If tags is empty, flushes all buffered tags.
Tree-aware: automatically recurses into labeled child subgraphs,
so a single parent.flush(&[]) flushes the entire tree. Child buffers
that are already empty (e.g. flushed separately) are skipped safely.
If you need different flush cadences per subgraph (e.g. flushing a
child every 10 parent epochs), use flush_local()
on both the parent and the child to manage them independently:
// Every epoch: flush parent only
parent.flush_local(&[]);
// Every 10 epochs: flush the child
if epoch % 10 == 0 {
parent.child_graph("slow_child").unwrap().flush_local(&[]);
}Sourcepub fn flush_local(&self, tags: &[&str])
pub fn flush_local(&self, tags: &[&str])
Flush only this graph’s own batch buffer, without recursing into children.
Use this when you need independent flush cadences per subgraph.
See flush() for the tree-recursive version.
Sourcepub fn flush_count(&self) -> usize
pub fn flush_count(&self) -> usize
Number of flush calls that produced data.
Sourcepub fn trends(&self, tags: &[&str]) -> TrendGroup
pub fn trends(&self, tags: &[&str]) -> TrendGroup
Get trends for multiple tags. Tag group names are automatically expanded to their member tags.
Sourcepub fn reset_trend(&self, tags: &[&str])
pub fn reset_trend(&self, tags: &[&str])
Clear epoch history. If tags is empty, clears all. Tag group names are automatically expanded.
Sourcepub fn traces(&self, tag: &str) -> Option<Vec<Variable>>
pub fn traces(&self, tag: &str) -> Option<Vec<Variable>>
Get per-iteration trace outputs from loop nodes. Returns the trace buffer for the loop node associated with the given tag. The tag should be set on a node after the loop (the loop output flows to it). Returns None if no loop node with a trace buffer is found.
Sourcepub fn traces_by_node(&self, node_id: &str) -> Option<Vec<Variable>>
pub fn traces_by_node(&self, node_id: &str) -> Option<Vec<Variable>>
Get trace buffer directly from a loop node by node ID.
Sourcepub fn last_trace(&self, tag: &str) -> Option<Variable>
pub fn last_trace(&self, tag: &str) -> Option<Variable>
Get the last trace output from the most recent loop iteration.
Convenience wrapper around traces() that returns only
the final iteration’s trace. Useful for chaining loops where the last
output of one (e.g. scan) feeds into the next (e.g. read).
Returns None if the tag has no associated loop or the body produced
no traces.
Source§impl Graph
impl Graph
Sourcepub fn enable_profiling(&self)
pub fn enable_profiling(&self)
Turn on per-node and per-level timing for subsequent forward calls.
Sourcepub fn disable_profiling(&self)
pub fn disable_profiling(&self)
Turn off timing. Subsequent forward calls have zero profiling overhead.
Sourcepub fn profile(&self) -> Option<Profile>
pub fn profile(&self) -> Option<Profile>
Timing data from the most recent forward call, or None.
Sourcepub fn timing(&self, tag: &str) -> Duration
pub fn timing(&self, tag: &str) -> Duration
Duration of a tagged node from the most recent forward call.
Sourcepub fn collect_timings(&self, tags: &[&str])
pub fn collect_timings(&self, tags: &[&str])
Snapshot tagged node durations into the timing batch buffer. If tags is empty, all tagged nodes with timing data are collected.
Sourcepub fn flush_timings(&self, tags: &[&str])
pub fn flush_timings(&self, tags: &[&str])
Compute batch mean, append to timing epoch history, clear buffer. If tags is empty, flushes all buffered tags.
Sourcepub fn timing_trend(&self, tag: &str) -> Trend
pub fn timing_trend(&self, tag: &str) -> Trend
Epoch-level trend over the timing history of a tagged node. Values are mean execution times in seconds.
Sourcepub fn timing_trends(&self, tags: &[&str]) -> TrendGroup
pub fn timing_trends(&self, tags: &[&str]) -> TrendGroup
TrendGroup for timing trends of the given tags (expands groups).
Sourcepub fn reset_timing_trend(&self, tags: &[&str])
pub fn reset_timing_trend(&self, tags: &[&str])
Clear timing epoch history. If tags is empty, clears all.
Source§impl Graph
impl Graph
Sourcepub fn dot(&self) -> String
pub fn dot(&self) -> String
Graphviz DOT representation of the graph structure.
Nodes are grouped by execution level, shaped by type (input/output/activation/norm),
and annotated with parameter counts. Render with:
dot -Tsvg graph.dot -o graph.svg
std::fs::write("graph.dot", g.dot()).unwrap();Sourcepub fn dot_with_profile(&self) -> String
pub fn dot_with_profile(&self) -> String
Timing-annotated DOT using the most recent Profile.
Nodes are color-coded green → yellow → red by relative execution time,
with per-node microsecond timings and per-level wall clock + parallelism.
Source§impl Graph
impl Graph
Sourcepub fn plot_html(&self, path: &str, tags: &[&str]) -> Result<()>
pub fn plot_html(&self, path: &str, tags: &[&str]) -> Result<()>
Generate a self-contained HTML file with training curves from epoch history.
This plots data accumulated via record() /
flush() — the graph’s observation system for metrics
that feed back into training decisions.
For a full dashboard with resource graphs, epoch log, and graph SVG,
use Monitor::save_html() instead.
Tag group names are expanded. If tags is empty, all epoch history is plotted. Uses inline Canvas JS — no external dependencies.
Sourcepub fn plot_timings_html(&self, path: &str, tags: &[&str]) -> Result<()>
pub fn plot_timings_html(&self, path: &str, tags: &[&str]) -> Result<()>
Generate a self-contained HTML file with per-node timing trend curves.
Requires prior collect_timings/flush_timings calls. Tag groups are expanded.
If tags is empty, all timing history is plotted.
Sourcepub fn export_trends(&self, path: &str, tags: &[&str]) -> Result<()>
pub fn export_trends(&self, path: &str, tags: &[&str]) -> Result<()>
Export epoch history to CSV (one column per tag, one row per epoch).
Tag groups are expanded. If tags is empty, all epoch history is exported.
Source§impl Graph
impl Graph
Sourcepub fn snapshot_cpu(&self) -> Result<ModelSnapshot>
pub fn snapshot_cpu(&self) -> Result<ModelSnapshot>
Snapshot the graph’s current state onto CPU.
Parameters are detached from autograd so no grad metadata crosses the thread boundary. Buffers have no grad and are copied as-is.
let snap = graph.snapshot_cpu()?;
worker.submit(move || {
snap.save_file("epoch_10.fdl.gz").unwrap();
});Source§impl Graph
impl Graph
Sourcepub fn tree_children(&self) -> HashMap<&str, &Graph>
pub fn tree_children(&self) -> HashMap<&str, &Graph>
Direct children: label -> child graph.
Sourcepub fn child_graph(&self, label: &str) -> Option<&Graph>
pub fn child_graph(&self, label: &str) -> Option<&Graph>
Get a direct child graph by label (one level only).
Sourcepub fn is_composed(&self) -> bool
pub fn is_composed(&self) -> bool
Whether this graph has been composed into a parent graph.
Tags marked as internal (hidden from parent resolution).
Sourcepub fn validate_path(&self, path: &str) -> Result<PathKind>
pub fn validate_path(&self, path: &str) -> Result<PathKind>
Validate that a path resolves, returning what it resolves to.
Sourcepub fn parameters_at(&self, path: &str) -> Result<Vec<Parameter>>
pub fn parameters_at(&self, path: &str) -> Result<Vec<Parameter>>
All parameters at a label path.
Sourcepub fn named_parameters_at(
&self,
path: &str,
) -> Result<Vec<(String, Parameter)>>
pub fn named_parameters_at( &self, path: &str, ) -> Result<Vec<(String, Parameter)>>
Named parameters at a label path, using the target’s own namespace.
For subgraphs: delegates to the child graph’s named_parameters().
For tags: qualifies with the tag name as prefix.
Sourcepub fn named_buffers_at(&self, path: &str) -> Result<Vec<(String, Buffer)>>
pub fn named_buffers_at(&self, path: &str) -> Result<Vec<(String, Buffer)>>
Named buffers at a label path, using the target’s own namespace.
Sourcepub fn thaw(&self, path: &str) -> Result<()>
pub fn thaw(&self, path: &str) -> Result<()>
Thaw (unfreeze) all parameters at the given label path.
Sourcepub fn is_frozen(&self, path: &str) -> Result<bool>
pub fn is_frozen(&self, path: &str) -> Result<bool>
Check if all parameters at the path are frozen. Returns true only if there are parameters and ALL are frozen.
Sourcepub fn load_subgraph_checkpoint(
&self,
path: &str,
file: &str,
) -> Result<LoadReport>
pub fn load_subgraph_checkpoint( &self, path: &str, file: &str, ) -> Result<LoadReport>
Load a checkpoint into a specific subgraph.
The checkpoint’s structural hash is validated against the target subgraph’s hash. Named parameters/buffers are matched within the subgraph’s own namespace.
Sourcepub fn set_training_at(&self, path: &str, training: bool) -> Result<()>
pub fn set_training_at(&self, path: &str, training: bool) -> Result<()>
Set training mode on a specific subgraph or tagged module.
Sourcepub fn tagged_at(&self, path: &str) -> Result<Option<Variable>>
pub fn tagged_at(&self, path: &str) -> Result<Option<Variable>>
Get a tagged output by label path.
Returns Err if the path doesn’t exist (null – wiring bug).
Returns Ok(None) if the path exists but hasn’t been computed yet (nil).
Returns Ok(Some(v)) if the value is available.
Sourcepub fn collect_at(&self, paths: &[&str]) -> Result<()>
pub fn collect_at(&self, paths: &[&str]) -> Result<()>
Collect metrics from label paths into observation buffers. Each path must resolve to a tag (not a subgraph). Metrics are stored in the target graph’s batch buffer.
Source§impl Graph
impl Graph
Sourcepub fn tree_summary(&self) -> String
pub fn tree_summary(&self) -> String
Generate a tree summary showing subgraph structure, tags, and parameter counts.
Sourcepub fn param_summary(&self) -> String
pub fn param_summary(&self) -> String
Per-subgraph parameter count breakdown.
Source§impl Graph
impl Graph
Sourcepub fn reset_state(&self)
pub fn reset_state(&self)
Clear all forward-reference state buffers to None. Call when starting inference on a new sequence.
Sourcepub fn detach_state(&self)
pub fn detach_state(&self)
Break gradient chain on forward-reference state buffers and module state. Call between training steps to prevent unbounded graph growth.
Sourcepub fn end_step(&self)
pub fn end_step(&self)
End-of-step housekeeping: detach state (cut gradient chain but preserve values for the next forward), collect timings, increment step counter.
For recurrent models this implements truncated BPTT — state carries
over between steps but gradients don’t flow across step boundaries.
Call end_sequence to fully wipe state
when starting a new independent sequence.
for token in sequence {
let y = graph.forward(&token)?;
// ... backward, optimize ...
graph.end_step(); // keep state, cut gradients
}
graph.end_sequence(); // wipe state for next sequenceSourcepub fn end_sequence(&self)
pub fn end_sequence(&self)
End-of-sequence housekeeping: fully reset state buffers to None. Call between independent sequences so the model starts fresh.
For non-recurrent graphs (no forward refs) this is a no-op.
Sourcepub fn end_epoch(&self)
pub fn end_epoch(&self)
End-of-epoch housekeeping: flush all observation and timing buffers, increment epoch counter.
Sourcepub fn step_count(&self) -> usize
pub fn step_count(&self) -> usize
Number of completed training steps.
Sourcepub fn epoch_count(&self) -> usize
pub fn epoch_count(&self) -> usize
Number of completed training epochs.
Sourcepub fn tag_group(&self, name: &str) -> Option<&[String]>
pub fn tag_group(&self, name: &str) -> Option<&[String]>
Get member tags of a tag group, or None if not registered.
Sourcepub fn forward_multi(&self, inputs: &[Variable]) -> Result<Variable>
pub fn forward_multi(&self, inputs: &[Variable]) -> Result<Variable>
Forward with multiple inputs (for graphs with Input ports). Inputs are in declaration order: From entry first, then each Input.
Sourcepub fn set_device(&self, device: Device)
pub fn set_device(&self, device: Device)
Move all parameters, state buffers, and module buffers to a device.
Sourcepub fn named_parameters(&self) -> Vec<(String, Parameter)>
pub fn named_parameters(&self) -> Vec<(String, Parameter)>
Return parameters with qualified names: "prefix/param_name".
The prefix is the tag name if the node is tagged, otherwise the node ID
(e.g. "linear_1"). When a node has multiple parameters with the same
name, suffixes _0, _1, … are appended to disambiguate.
Sourcepub fn named_buffers(&self) -> Vec<(String, Buffer)>
pub fn named_buffers(&self) -> Vec<(String, Buffer)>
Return buffers with qualified names, using the same prefix logic
as named_parameters().
Sourcepub fn structural_hash(&self) -> &str
pub fn structural_hash(&self) -> &str
Full 64-character hex structural hash (computed lazily, cached).
Sourcepub fn short_hash(&self) -> &str
pub fn short_hash(&self) -> &str
First 8 characters of the structural hash.
Sourcepub fn save_checkpoint(&self, path: &str) -> Result<()>
pub fn save_checkpoint(&self, path: &str) -> Result<()>
Save all parameters and buffers to a checkpoint file.
Embeds the structural hash for architecture validation on load.
Supports .gz extension for gzip compression.
Sourcepub fn load_checkpoint(&self, path: &str) -> Result<LoadReport>
pub fn load_checkpoint(&self, path: &str) -> Result<LoadReport>
Load parameters and buffers from a checkpoint file.
Validates the structural hash against this graph’s architecture.
Returns a LoadReport describing what was
loaded, skipped, or missing.
Trait Implementations§
Source§impl Module for Graph
impl Module for Graph
Source§fn name(&self) -> &str
fn name(&self) -> &str
Source§fn as_graph(&self) -> Option<&Graph>
fn as_graph(&self) -> Option<&Graph>
Graph for hierarchical tree composition.
Override in Graph to enable subgraph nesting with label-path addressing.Source§fn structural_hash(&self) -> Option<String>
fn structural_hash(&self) -> Option<String>
Source§fn forward(&self, input: &Variable) -> Result<Variable>
fn forward(&self, input: &Variable) -> Result<Variable>
input and return the result.Source§fn parameters(&self) -> Vec<Parameter>
fn parameters(&self) -> Vec<Parameter>
sub_modules() with pointer dedup.
Leaf modules should override to return their own parameters.Source§fn set_training(&self, training: bool)
fn set_training(&self, training: bool)
Source§fn move_to_device(&self, device: Device)
fn move_to_device(&self, device: Device)
Source§fn buffers(&self) -> Vec<Buffer>
fn buffers(&self) -> Vec<Buffer>
sub_modules() with pointer dedup.
Leaf modules should override to return their own buffers.Source§fn sub_modules(&self) -> Vec<Rc<dyn Module>>
fn sub_modules(&self) -> Vec<Rc<dyn Module>>
Source§fn trace(&self) -> Option<Variable>
fn trace(&self) -> Option<Variable>
None by default.
When Some, the loop executor collects traces accessible via
Graph::traces().Source§fn as_named_input(&self) -> Option<&dyn NamedInputModule>
fn as_named_input(&self) -> Option<&dyn NamedInputModule>
NamedInputModule for multi-input graphs.
Override in types that implement NamedInputModule to enable
receiving additional named inputs via graph using().