Algebraic tape soundness #
Tape-style (SSA/DAG) reverse-mode soundness (algebraic, backend-generic).
This is a backend-generic analogue of the tensor-tape soundness layer: it proves the global reverse-mode accumulation algorithm is sound assuming only commutative semiring laws.
This file lives under NN/Proofs/Autograd/Tape/Algebra/ because it is reused by both proof-only
and runtime-link developments that target exact backends (e.g. ℚ).
PyTorch correspondence / citations #
This corresponds to the high-level structure of PyTorch’s reverse-mode engine, but stated over an arbitrary commutative semiring so we can reuse it for exact backends. https://pytorch.org/docs/stable/autograd.html
Dot product over contexts: sum of per-entry tensor dots.
This is the algebraic analogue of Spec.dotList: it uses TensorAlgebra.dot for the backend α.
Instances For
dotList commutes with casting the left context along a shape-list equality.
dotList is linear in its right argument with respect to TorchLean.TensorPack.add.
Dot respects appending: dot of two snoced contexts splits into prefix + last entry.
Dotting with the all-zero context on the right yields 0.
Sparse context with a single nonzero entry at idx (all other tensors are 0).
Instances For
single is adjoint to getIdx with respect to dotList.
Informally: ⟪dx, single idx v⟫ = ⟪getIdx dx idx, v⟫.
A single-parent dense VJP agrees with one exception to the uniform zero reader.
One parent contribution, including the original zero entries at every other position.
Instances For
The original programs of a node after saving its inputs for one execution.
- value : Unit → TorchLean.Tensor α τ
Compute the primal tensor after domain validation has succeeded.
- vjp : TorchLean.Tensor α τ → TorchLean.TensorPack α Γ
The stored VJP with its primal inputs already captured.
Domain validation performed before recording the node.
Instances For
Saved node programs with an optional certified compact backward implementation.
- value : Unit → TorchLean.Tensor α τ
- vjp : TorchLean.Tensor α τ → TorchLean.TensorPack α Γ
- compact? : Option { run : TorchLean.Tensor α τ → Contributions α Γ // ∀ (seed : TorchLean.Tensor α τ), (run seed).dense () = self.vjp seed }
A compact VJP preserves the complete dense contribution, at every parent position.
Instances For
Executable node payload (no derivative-correctness proof).
Δ is an extra non-differentiable environment threaded through evaluation (e.g. parameters,
auxiliary data). The VJP returns gradients only for the differentiable context Γ.
- forward : TorchLean.TensorPack α Γ → Δ → TorchLean.Tensor α τ
Evaluate the node from the current differentiable context and auxiliary data.
- jvp : TorchLean.TensorPack α Γ → TorchLean.TensorPack α Γ → Δ → TorchLean.Tensor α τ
Propagate one tangent context through the node.
- vjp : TorchLean.TensorPack α Γ → Δ → TorchLean.Tensor α τ → TorchLean.TensorPack α Γ
Pull an output cotangent back to the node's differentiable input context.
- validate : TorchLean.TensorPack α Γ → Δ → Except String Unit
Optional runtime precondition, enforced by checked execution before evaluating this node.
- prepare? : Option { prepare : TensorLookup α Γ → Δ → PreparedNode α Γ τ // ∀ (ctx : TorchLean.TensorPack α Γ) (d : Δ), (prepare (TensorLookup.ofPack ctx) d).toPreparedPrograms = { value := fun (x : Unit) => self.forward ctx d, vjp := self.vjp ctx d, validate := fun (x : Unit) => self.validate ctx d } }
An optional preparation program that saves only the node's own inputs. Its certificate preserves the complete dense VJP, including zero entries and the order of scalar operations.
Instances For
Build a node whose runtime preparation captures a fixed collection of tensors. The same scalar programs define the pack interface and the prepared interface, so their agreement is definitional.
Instances For
Local scalar programs with a compact VJP whose dense adapter remains the public VJP.
Instances For
Prepare a node from array storage, using the pack adapter for arbitrary custom closures.
Instances For
Preparation preserves the original forward, validation, and dense backward programs.
Proof-carrying node: NodeData plus the local adjointness law.
The field correct is the algebraic version of the standard JVP/VJP inner-product law.
- forward : TorchLean.TensorPack α Γ → Δ → TorchLean.Tensor α τ
- jvp : TorchLean.TensorPack α Γ → TorchLean.TensorPack α Γ → Δ → TorchLean.Tensor α τ
- vjp : TorchLean.TensorPack α Γ → Δ → TorchLean.Tensor α τ → TorchLean.TensorPack α Γ
- validate : TorchLean.TensorPack α Γ → Δ → Except String Unit
- prepare? : Option { prepare : TensorLookup α Γ → Δ → PreparedNode α Γ τ // ∀ (ctx : TorchLean.TensorPack α Γ) (d : Δ), (prepare (TensorLookup.ofPack ctx) d).toPreparedPrograms = { value := fun (x : Unit) => self.forward ctx d, vjp := self.vjp ctx d, validate := fun (x : Unit) => self.validate ctx d } }
- correct (x dx : TorchLean.TensorPack α Γ) (d : Δ) (δ : TorchLean.Tensor α τ) : TensorAlgebra.dot (self.jvp x dx d) δ = TensorPack.dotList dx (self.vjp x d δ)
The node's JVP and VJP satisfy the local dot-product adjoint identity.
Instances For
Executable-only graph: a snoc-list of NodeData.
- nil
{α : Type}
[TorchLean.Storage α]
{Δ : Type}
{Γ : List Spec.Shape}
: GraphData α Δ Γ []
A graph with no computed nodes; its context consists only of the inputs
Γ. - snoc
{α : Type}
[TorchLean.Storage α]
{Δ : Type}
{Γ ss : List Spec.Shape}
{τ : Spec.Shape}
: GraphData α Δ Γ ss → NodeData α Δ (Γ ++ ss) τ → GraphData α Δ Γ (ss ++ [τ])
Append one node whose inputs may use the original and previously computed values.
Instances For
Evaluate a GraphData on an input context x, producing the full context Γ ++ ss.
Instances For
Evaluate using indexed storage and save only each node's local input tensors.
Instances For
Indexed forward execution computes the original full typed context.
Public typed forward result, decoded once after array execution.
Instances For
Compile the public evaluator to the proved array execution path.
Compute the JVP of eval, producing a tangent context of shape Γ ++ ss.
Instances For
Reverse-mode accumulation on contexts (VJP), given a seed cotangent for Γ ++ ss.
Instances For
A proof-carrying tape/SSA graph.
Nodes are appended in topological order and may reference any previously computed value (fan-out and sharing are allowed). This mirrors the structure of PyTorch’s dynamic autograd graph, but with shape-typed contexts.
- nil
{α : Type}
[TorchLean.Storage α]
[CommSemiring α]
{Δ : Type}
{Γ : List Spec.Shape}
: Graph Δ Γ []
A graph with no computed nodes; its context consists only of the inputs
Γ. - snoc
{α : Type}
[TorchLean.Storage α]
[CommSemiring α]
{Δ : Type}
{Γ ss : List Spec.Shape}
{τ : Spec.Shape}
: Graph Δ Γ ss → Node Δ (Γ ++ ss) τ → Graph Δ Γ (ss ++ [τ])
Append one locally correct node that may use the inputs and all preceding results.
Instances For
Forget local correctness proofs, yielding an executable GraphData.
Instances For
Evaluate a proof-carrying graph through its executable representation.
Instances For
Propagate tangents with the same evaluator used by the executable graph.
Instances For
Accumulate cotangents with the executable graph's reverse pass.
Instances For
Global tape soundness (algebraic form).
Assuming each node satisfies its local adjointness law, backpropCtx is the adjoint of jvpCtx
with respect to TensorPack.dotList.