Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions execution_graph/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ nodes and re-executes only the nodes that are affected by changes.
- **Nodes** are `(VerifiedProgram, entry FuncId)` pairs.
- **Edges** represent data dependencies; they are recorded dynamically from each node run:
- reading an external input records `ResourceKey::Input(name)`
- reading another node's output records `ResourceKey::TapeOutput { node, output }`
- reading another node's output records `ResourceKey::NodeOutput { node, output }`
- host ops can record additional dependencies via `execution_tape::host::AccessSink`
- **Invalidation** is done by name: calling `invalidate_input("foo")` marks the input key
`ResourceKey::Input("foo")` dirty, which may trigger re-execution of transitive dependents.
Expand All @@ -24,6 +24,10 @@ Host state invalidation uses the same key space: if a host op records a
via `ExecutionGraph::invalidate_tape_key(...)` (or by constructing the corresponding owned
`execution_graph::ResourceKey` and calling `ExecutionGraph::invalidate(...)`).

Graph construction is checked at the public API boundary: `add_node`, `set_input_value`, and
`connect` return `GraphError` values for unknown entry functions, input arity mismatches, unknown
input names, and unknown output names.

## Execution behavior

`run_node` drains and executes only the dirty work within the dependency closure of the target
Expand All @@ -46,5 +50,5 @@ cargo run -p execution_graph_examples --bin tax

## Current limitations

- Error reporting is intentionally minimal (`GraphError::Trap` is opaque); richer error surfaces
are expected to be layered on in follow-up PRs.
- `execution_graph` intentionally stays close to the VM: traps expose `execution_tape::vm::TrapInfo`
rather than source-language diagnostics.
12 changes: 7 additions & 5 deletions execution_graph/src/dispatch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,8 +177,10 @@ mod tests {
let (const_prog, const_entry) = make_const_program("value", 7);

let mut g = ExecutionGraph::new(HostNoop, Limits::default());
let n_err = g.add_node(needs_input_prog, needs_input_entry, vec!["in".into()]);
let n_ok = g.add_node(const_prog, const_entry, vec![]);
let n_err = g
.add_node(needs_input_prog, needs_input_entry, vec!["in".into()])
.unwrap();
let n_ok = g.add_node(const_prog, const_entry, vec![]).unwrap();
let plan = RunPlan::all(vec![n_err, n_ok]);
let mut dispatcher = InlineDispatcher;

Expand All @@ -199,8 +201,8 @@ mod tests {
let (prog, entry) = make_const_program("value", 11);

let mut g = ExecutionGraph::new(HostNoop, Limits::default());
let n0 = g.add_node(prog.clone(), entry, vec![]);
let n1 = g.add_node(prog, entry, vec![]);
let n0 = g.add_node(prog.clone(), entry, vec![]).unwrap();
let n1 = g.add_node(prog, entry, vec![]).unwrap();

let r0 = NodeRunDetail {
node: n0,
Expand Down Expand Up @@ -233,7 +235,7 @@ mod tests {
fn inline_dispatcher_with_report_handles_short_trace_vectors() {
let (prog, entry) = make_const_program("value", 5);
let mut g = ExecutionGraph::new(HostNoop, Limits::default());
let node = g.add_node(prog, entry, vec![]);
let node = g.add_node(prog, entry, vec![]).unwrap();

// Empty trace payload: execution should still succeed and simply produce no traced rows.
let trace = RunPlanTrace::from_node_reports(vec![]);
Expand Down
Loading
Loading