Abstract base class for every node in the backward computation graph.
A Node is the unit of work that Engine executes during
backward. Each concrete subclass saves whatever tensors and
scalars it needs at forward time (typically into its own member fields)
and implements apply to compute input gradients from the incoming
output gradient via the chain rule.
The reference framework's Function corresponds to a Python-side
lucid.autograd.Function; on the C++ side that role is split into
a forward op (free function or struct method) plus this Node
subclass. Subclassing Node directly is unusual — most engine-resident
ops inherit through AutogradNode / FuncOp, which add
fixed-size storage for saved inputs and version checking.
See Also
Edge — the directed link between nodes.
AutogradNode — CRTP base with saved-input slots and version
checking that most ops actually inherit from.
Attributes
sequence_nr_std::uint64_tnext_sequence_nr. The engine uses this to break topological ties so that nodes closer to the loss are executed first.next_edges_std::vector<Edge>saved_versions_std::vector<std::int64_t>validate_versions to catch in-place mutations that would silently corrupt gradients.Notes
Lifetime. Nodes are jointly owned by the TensorImpl that
produced them (via grad_fn) and by the Edge objects of consumer
nodes. Once backward completes and grad_fn is cleared on the
root, the chain of shared_ptr references collapses and all temporary
nodes are destroyed.
Thread safety. Node is not thread-safe. The engine runs the
backward graph on a single thread; concurrent backward invocations
on the same graph are undefined behaviour.
Constructors
1Destructor
1Virtual methods
2Accumulate an arriving gradient into this barrier's internal buffer.
Parameters
input_nrstd::uint32_tgradStorageRaises
:runtime_errorWhether this node is a barrier that batches gradients from many edges before executing. Regular ops return false; barrier nodes (e.g. AccumulateGrad) override to true.
Returns
booltrue if the engine should route incoming gradients through accumulate_barrier_grad / apply_barrier instead of apply.
Methods
4Compute input gradients from the upstream output gradient.
This is the core chain-rule contribution implemented by each concrete
backward node. The returned vector has one entry per outgoing edge —
i.e. per input to the corresponding forward op — and the engine
dispatches entry i along next_edges_[i].
Math
For a forward op , apply returns
where is the Jacobian of with respect to .
Parameters
grad_outStorageReturns
std::vector<Storage>One Storage per forward input. An empty / default Storage at position i signals that no gradient flows to that input.
Flush an accumulated barrier and produce the consolidated gradients.
Returns
std::vector<Storage>One Storage per outgoing edge (same contract as apply).
Raises
:runtime_errorGraph-recording variant of apply for higher-order autograd.
Invoked by the engine when create_graph=True: the backward
computation itself is performed through TensorImpl-based ops
so that the resulting gradient tensors carry their own grad_fn,
enabling differentiation of gradients (Hessians, double-backward).
Parameters
grad_outconst TensorImplPtr&TensorImpl, possibly with a grad_fn of its own.Returns
std::vector<TensorImplPtr>One TensorImpl per forward input, each possibly carrying autograd metadata.
Raises
:runtime_errornode_name.Return a short human-readable identifier for this node.
Returns
std::stringDefaults to "unknown"; concrete nodes override to expose their schema_v1.name (e.g. "matmul", "linear").
Notes
Used in error messages emitted by apply_for_graph and in
debugger / profiler output.