Per-tensor autograd metadata — gradient buffer, backward edge, and version counter for in-place safety.
requires_grad controls whether operations involving this tensor
build an autograd graph. is_leaf is true for parameters
created by the user (model weights) and false for intermediate
tensors produced by ops. Leaf tensors accumulate gradients into
grad; non-leaf tensors do not accumulate unless the engine
later honours a retain_grad opt-in (tracked in the sibling
core::AutogradMeta, not yet exposed in this struct).
grad_fn points to the backward Node that produced this
tensor. It is nullptr for leaf tensors (which use
AccumulateGrad installed lazily by ensure_grad_fn) and
for tensors detached from the graph via detach.
See Also
AutogradNode — backward node type referenced by
grad_fn.
AccumulateGrad — terminal node that writes into
grad for leaf tensors.
Attributes
requires_gradbooltrue, downstream ops emit an AutogradNode and link it into grad_fn of their outputs.is_leafbooltrue for user-created parameters (no producing op); false for op outputs. Leaves install AccumulateGrad as their grad_fn on first backward and write into grad.versionstd::int64_tTensorImpl::bump_version on every in-place op or optimizer step. Saved tensors snapshot this value at capture time and compare it during backward.grad_fnNodePtrnullptr for leaves and detached tensors.gradstd::optional<Storage>backward call. Lazily allocated by AccumulateGrad on first invocation; cleared by zero_grad.grad_implstd::shared_ptr<TensorImpl>TensorImpl view of the gradient — populated instead of (or in addition to) grad when backward(create_graph=true) is used. Allows the gradient itself to participate in further autograd operations (second-order derivatives, MAML, Hessian-vector products, …).Notes
Invariants enforced by the autograd layer:
is_leaf == true⇒grad_fn == nullptr.is_leaf == false⇒grad_fn != nullptr.versionis monotonically non-decreasing for the lifetime of the owningTensorImpl.
Lifecycle: created at first parameter use (when requires_grad is
set), persists through forward() / backward() cycles, and
grad is cleared by optimizer.zero_grad() between
iterations.