TorchLean

8.3. Autograd and Execution🔗

The runtime has a dynamic tape for eager execution and a typed SSA builder for typed graph execution. Both sit below the layer API. A separate bridge executes NN.IR.Graph through a forward-only graph; its correctness theorem names its single remaining side condition.

Definition8.3.1
Group: Programs, tapes, and typed graph execution. (6)
Group member previews
Preview
Definition 8.3.2
Loading preview
Group member preview content is loaded from the rendered-fragment cache.
Statement uses 2
Statement dependency previews
Preview
Definition 8.1.1
Loading preview
Statement dependency preview content is loaded from the rendered-fragment cache.
Used by 2
Reverse dependency previews
Preview
Definition 8.3.7
Loading preview
Reverse dependency preview content is loaded from the rendered-fragment cache.
L∃∀N

The operation interface describes programs over shape-indexed tensors and scalar operations without choosing eager or typed graph execution at the call site.

Lean code for Definition8.3.11 definition
  • complete
    abbrev Runtime.Autograd.Model.Program (α : Type) [TorchLean.Storage α]
      [Context α] (ss : List Spec.Shape) (τ : Spec.Shape) : Type 1
    abbrev Runtime.Autograd.Model.Program (α : Type)
      [TorchLean.Storage α] [Context α]
      (ss : List Spec.Shape)
      (τ : Spec.Shape) : Type 1
    An execution-polymorphic differentiable tensor program. 
Definition8.3.2
Group: Programs, tapes, and typed graph execution. (6)
Group member previews
Preview
Definition 8.3.1
Loading preview
Group member preview content is loaded from the rendered-fragment cache.
uses 0
Used by 6
Reverse dependency previews
Preview
Definition 8.3.3
Loading preview
Reverse dependency preview content is loaded from the rendered-fragment cache.
L∃∀N

The CPU tape is a dynamic computation DAG. It stores shape-erased values and accumulates reverse-mode gradients by node index.

Shape erasure lets one array hold a vector input, a matrix intermediate, and a scalar loss. Typed graph lowering must preserve which index names each value. During reverse accumulation, multiple uses of an intermediate contribute to the same stored cotangent, so index alignment matters for both reading forward values and adding backward contributions.

Lean code for Definition8.3.21 definition
  • structure(1 field)defined in NN/Runtime/Autograd/Engine/Core/Base.lean
    complete
    structure Runtime.Autograd.Tape (α : Type) [TorchLean.Storage α] : Type
    structure Runtime.Autograd.Tape (α : Type)
      [TorchLean.Storage α] : Type
    Autograd tape: a grow-only array of nodes.
    
    Node ids are array indices (`Nat`). All ops append exactly one node and return its id.
    This makes it easy to implement reverse-mode by traversing ids in reverse order.
    
    nodes : Array (Runtime.Autograd.Node α)
    Tape nodes in evaluation order.
    
    Node ids are array indices (`Nat`). Each tape op appends exactly one node and returns its id.
    
Definition8.3.3
Group: Programs, tapes, and typed graph execution. (6)
Group member previews
Preview
Definition 8.3.1
Loading preview
Group member preview content is loaded from the rendered-fragment cache.
uses 1used by 1L∃∀N

lowerToTape takes executable typed graph data and its input context, then returns a runtime tape together with the typed list of inputs and intermediate values.

Lean code for Definition8.3.31 definition
  • def Runtime.Autograd.TypedGraph.lowerToTape {α : Type} [TorchLean.Storage α]
      {Γ ss : List Spec.Shape}
      (g : Runtime.Autograd.TypedGraph.GraphData α Γ ss)
      (x : TorchLean.TensorPack α Γ) :
      Runtime.Autograd.Tape α × TorchLean.TensorPack α (Γ ++ ss)
    def Runtime.Autograd.TypedGraph.lowerToTape
      {α : Type} [TorchLean.Storage α]
      {Γ ss : List Spec.Shape}
      (g :
        Runtime.Autograd.TypedGraph.GraphData
          α Γ ss)
      (x : TorchLean.TensorPack α Γ) :
      Runtime.Autograd.Tape α ×
        TorchLean.TensorPack α (Γ ++ ss)
    Lower an executable `GraphData` into a runtime tape.
    
    This is the bridge from the shape-indexed SSA representation to the runtime tape engine:
    `Graph.lowerGraphDataToTape` emits a `Runtime.Autograd.Tape` whose nodes replay the graph and whose
    backward closures implement the graph's VJP rules.
    
    The graph remains the persistent artifact; the tape contains the runtime closures needed for one
    execution and reverse pass.
    
Theorem8.3.4
Group: Programs, tapes, and typed graph execution. (6)
Group member previews
Preview
Definition 8.3.1
Loading preview
Group member preview content is loaded from the rendered-fragment cache.
uses 1used by 1L∃∀N

For executable typed graph data over a commutative semiring, dense reverse accumulation on the lowered tape equals proof-level graph backpropagation after both contexts are converted to the tape's value array.

This is agreement with the graph's stored executable backward rules. It shows that lowering and accumulation preserve those rules; it does not establish their derivative formulas. Local derivative laws are a separate obligation. The commutative-semiring hypotheses also matter: they support the algebra used to combine contributions and cannot be assumed for arbitrary rounded arithmetic.

Lean code for Theorem8.3.41 theorem
  • theorem Proofs.Autograd.Algebra.Graph.backwardDenseFrom_lowerGraphDataToTape_eq_backpropAllCtx
      {α Δ : Type} [TorchLean.Storage α] [Add α] {Γ ss : List Spec.Shape}
      (g : Proofs.Autograd.Algebra.GraphData α Δ Γ ss)
      (x : TorchLean.TensorPack α Γ) (d0 : Δ)
      (seed : TorchLean.TensorPack α (Γ ++ ss)) :
      (Proofs.Autograd.Algebra.Graph.lowerGraphDataToTape g x
                d0).1.backwardDenseFrom
          seed.toShapeErasedArray =
        Except.ok (g.backpropAllCtx x d0 seed).toShapeErasedArray
    theorem Proofs.Autograd.Algebra.Graph.backwardDenseFrom_lowerGraphDataToTape_eq_backpropAllCtx
      {α Δ : Type} [TorchLean.Storage α]
      [Add α] {Γ ss : List Spec.Shape}
      (g :
        Proofs.Autograd.Algebra.GraphData α Δ
          Γ ss)
      (x : TorchLean.TensorPack α Γ) (d0 : Δ)
      (seed :
        TorchLean.TensorPack α (Γ ++ ss)) :
      (Proofs.Autograd.Algebra.Graph.lowerGraphDataToTape
                g x d0).1.backwardDenseFrom
          seed.toShapeErasedArray =
        Except.ok
          (g.backpropAllCtx x d0
              seed).toShapeErasedArray
    Variant of `backwardDenseFrom_lowerGraphToTape_eq_backpropAllCtx` for the `GraphData` interface.
    
    This is useful when a graph carries extra payload `Δ` (e.g. parameters/config) through forward and
    backward closures.
    
Proof for Theorem 8.3.4
uses 0

Induction over the typed graph keeps the forward context and tape indices aligned while the reverse loop accumulates each node's contribution.

Theorem8.3.5
Group: Programs, tapes, and typed graph execution. (6)
Group member previews
Preview
Definition 8.3.1
Loading preview
Group member preview content is loaded from the rendered-fragment cache.
uses 0used by 0L∃∀N

For any typed output reference, including an input or intermediate node, lowering to the runtime tape and running reverse mode agrees with seeding that same output in executable graph backpropagation.

Lean code for Theorem8.3.51 theorem
  • complete
    theorem Runtime.Autograd.TypedGraph.backwardDenseAllFrom_lowerToTape_eq_backpropAllCtx
      {α : Type} [CommSemiring α] {Γ ss : List Spec.Shape} {τ : Spec.Shape}
      (g : Runtime.Autograd.TypedGraph.GraphData α Γ ss)
      (x : TorchLean.TensorPack α Γ) (output : Proofs.Idx (Γ ++ ss) τ)
      (seed : TorchLean.Tensor α τ) :
      Runtime.Autograd.TypedGraph.backwardDenseAllFrom
          (Runtime.Autograd.TypedGraph.lowerToTape g x).1 output seed =
        Except.ok
          (Proofs.Autograd.Algebra.GraphData.backpropAllCtx g x ()
              (Proofs.Autograd.Algebra.TensorPack.single output
                seed)).toShapeErasedArray
    theorem Runtime.Autograd.TypedGraph.backwardDenseAllFrom_lowerToTape_eq_backpropAllCtx
      {α : Type} [CommSemiring α]
      {Γ ss : List Spec.Shape}
      {τ : Spec.Shape}
      (g :
        Runtime.Autograd.TypedGraph.GraphData
          α Γ ss)
      (x : TorchLean.TensorPack α Γ)
      (output : Proofs.Idx (Γ ++ ss) τ)
      (seed : TorchLean.Tensor α τ) :
      Runtime.Autograd.TypedGraph.backwardDenseAllFrom
          (Runtime.Autograd.TypedGraph.lowerToTape
              g x).1
          output seed =
        Except.ok
          (Proofs.Autograd.Algebra.GraphData.backpropAllCtx
              g x ()
              (Proofs.Autograd.Algebra.TensorPack.single
                output
                seed)).toShapeErasedArray
    Lowering a typed graph to the runtime tape preserves reverse mode from any typed output reference.
    
    The result covers outputs that are inputs or intermediate nodes, not only the final recorded node.
    It states fidelity to the executable VJP stored in `GraphData`; derivative correctness requires the
    separate local laws carried by `Proofs.Autograd.Algebra.Node`.
    
Proof for Theorem 8.3.5
uses 0

The general graph-data lowering theorem is instantiated with a seed context containing the supplied cotangent at exactly the selected output reference.

Selecting an intermediate asks for the sensitivity of that intermediate, rather than of the last node in the graph. Selecting an input is meaningful too. The seed identifies both the value being differentiated and the cotangent applied there, so both routes must seed the same reference.

Lean code for Theorem8.3.61 theorem
  • theorem Runtime.Autograd.Torch.Internal.TypedGraphSession.backwardDenseFrom_lowerGraphDataToTape_eq_backpropAllCtx
      {α : Type} [TorchLean.Storage α] [CommSemiring α]
      (st : Runtime.Autograd.Torch.Internal.TypedGraphSessionState α)
      (seed : TorchLean.TensorPack α (st.Γ ++ st.ss)) :
      (Proofs.Autograd.Algebra.Graph.lowerGraphDataToTape st.g st.x
                st.nat).1.backwardDenseFrom
          seed.toShapeErasedArray =
        Except.ok (st.g.backpropAllCtx st.x st.nat seed).toShapeErasedArray
    theorem Runtime.Autograd.Torch.Internal.TypedGraphSession.backwardDenseFrom_lowerGraphDataToTape_eq_backpropAllCtx
      {α : Type} [TorchLean.Storage α]
      [CommSemiring α]
      (st :
        Runtime.Autograd.Torch.Internal.TypedGraphSessionState
          α)
      (seed :
        TorchLean.TensorPack α
          (st.Γ ++ st.ss)) :
      (Proofs.Autograd.Algebra.Graph.lowerGraphDataToTape
                st.g st.x
                st.nat).1.backwardDenseFrom
          seed.toShapeErasedArray =
        Except.ok
          (st.g.backpropAllCtx st.x st.nat
              seed).toShapeErasedArray
    Running the runtime reverse-mode loop on the lowered tape equals `GraphData` backpropagation.
    
    `lowerGraphDataToTape` produces a tape, and `Tape.backwardDenseFrom` is equal to
    `GraphData.backpropAllCtx` up to the `TorchLean.TensorPack.toShapeErasedArray` representation
    change. This theorem proves the lowering faithful to the stored VJP program. It does not prove that
    the VJP is the derivative of the stored forward function; that stronger statement requires
    proof-carrying `Node`s.
    
Definition8.3.7
Group: Programs, tapes, and typed graph execution. (6)
Group member previews
Preview
Definition 8.3.1
Loading preview
Group member preview content is loaded from the rendered-fragment cache.
uses 1used by 0L∃∀N

Layer definitions carry parameter and buffer initialization, training or evaluation mode, and shape-checked sequential composition. They build their computations through the runtime operation interface.

Lean code for Definition8.3.71 definition
  • inductive(2 constructors, 2 parameters)defined in NN/Runtime/Autograd/Model/Layers/Seq.lean
    complete
    inductive Runtime.Autograd.Model.Layers.Seq : Spec.Shape  Spec.Shape  Type 1
    inductive Runtime.Autograd.Model.Layers.Seq :
      Spec.Shape  Spec.Shape  Type 1
    Sequential composition of `Layer`s, indexed by input/output shape.
    
    This is the builder-layer analogue of `torch.nn.Sequential`: a `Seq σ τ` represents a model that
    takes an input of shape `σ` and produces an output of shape `τ` by running layers left-to-right.
    
    `Seq` lives in `Type 1`, and no lower. Each `Layer` stores its forward pass as an
    execution-polymorphic `Program`, which quantifies over the scalar type `α : Type` and the
    interpreter monad `m : Type → Type`, so `Layer σ τ : Type 1` and any type that stores a `Layer`
    is at least `Type 1`. Consequently `IO (Seq σ τ)` is ill-typed; build models purely with
    `nn.build seed builder`, draw a seed in `IO` with `nn.buildIO`, or pass the model to a
    continuation with `nn.withModel`.
    
    Runtime.Autograd.Model.Layers.Seq.id (s : Spec.Shape) :
      Runtime.Autograd.Model.Layers.Seq s s
    The empty sequence, which leaves a tensor unchanged. 
    Runtime.Autograd.Model.Layers.Seq.cons
      {σ τ υ : Spec.Shape} :
      Runtime.Autograd.Model.Layers.Layer σ τ 
        Runtime.Autograd.Model.Layers.Seq τ υ 
          Runtime.Autograd.Model.Layers.Seq σ υ
    Run one layer, then the remaining sequence. 
Definition8.3.8
groupuses 1used by 1L∃∀N

After structural validation, the supported shared IR operations are lowered to a shape-indexed ForwardGraph for forward evaluation. Its ForwardData contains only forward closures: there are no JVP or VJP fields to call. It is distinct from the reusable autograd Torch.TypedGraph.

The correctness claim below consequently concerns forward values. It compares this lowered reference execution with the IR evaluator using the same inputs and payload. It does not certify native CPU or CUDA kernels, and this forward-only bridge provides no backward implementation to which the tape-agreement theorem could be applied.

Lean code for Definition8.3.81 definition
  • complete
    def Runtime.Autograd.IRExec.lowerToForwardGraph {α : Type}
      [TorchLean.Storage α] [Context α] (g : NN.IR.Graph)
      (payload : NN.IR.Payload α) :
      Except String (Runtime.Autograd.IRExec.ForwardGraph α)
    def Runtime.Autograd.IRExec.lowerToForwardGraph
      {α : Type} [TorchLean.Storage α]
      [Context α] (g : NN.IR.Graph)
      (payload : NN.IR.Payload α) :
      Except String
        (Runtime.Autograd.IRExec.ForwardGraph
          α)
    Lower an op-tagged IR graph into an executable `ForwardGraph`.
    
    Requirements:
    - Node id 0 must be `.input`.
    - The graph must satisfy `Graph.checkWellFormed`.
    - The external payload must contain entries for every `.const`/`.linear`/`.conv` node id.
    
    This returns a `ForwardGraph` whose `eval` computes all node values in topological order. The
    artifact is intentionally forward-only; it is distinct from the differentiable `Torch.TypedGraph`
    used by the autograd lowering path.
    
    This is the main API consumed by runtime callers that want executable evaluation while remaining
    aligned with the shared `NN.IR.Graph` semantics.
    
Theorem8.3.9
group
Statement uses 2
Statement dependency previews
Preview
Definition 8.1.23
Loading preview
Statement dependency preview content is loaded from the rendered-fragment cache.
used by 0L∃∀N

Successful lowering agrees with IR denotation on every input, provided NoRawLog excludes all raw log nodes. This restriction matters because the IR evaluator rejects nonpositive inputs to raw log, while the lowered closure applies the total spec logarithm. A theorem that admitted raw log would need per-node positivity hypotheses; this theorem instead excludes that operation. Every other operation kind is covered, including mseLoss, concat along any axis, matmul with any shared leading shape, and batched linear layers.

Lean code for Theorem8.3.91 theorem
  • theorem Runtime.Autograd.IRExec.denoteAll_eq_of_lowerToForwardGraph {α : Type}
      [TorchLean.Storage α] [Context α] (g : NN.IR.Graph)
      (payload : NN.IR.Payload α)
      (exec : Runtime.Autograd.IRExec.ForwardGraph α)
      (hNoRawLog : Runtime.Autograd.IRExec.NoRawLog g)
      (h :
        Runtime.Autograd.IRExec.lowerToForwardGraph g payload =
          Except.ok exec)
      (x : TorchLean.Tensor α exec.inShape) :
      g.denoteAll payload { shape := exec.inShape, tensor := x } =
        Except.ok (exec.denoteAll x)
    theorem Runtime.Autograd.IRExec.denoteAll_eq_of_lowerToForwardGraph
      {α : Type} [TorchLean.Storage α]
      [Context α] (g : NN.IR.Graph)
      (payload : NN.IR.Payload α)
      (exec :
        Runtime.Autograd.IRExec.ForwardGraph
          α)
      (hNoRawLog :
        Runtime.Autograd.IRExec.NoRawLog g)
      (h :
        Runtime.Autograd.IRExec.lowerToForwardGraph
            g payload =
          Except.ok exec)
      (x : TorchLean.Tensor α exec.inShape) :
      g.denoteAll payload
          { shape := exec.inShape,
            tensor := x } =
        Except.ok (exec.denoteAll x)
    End-to-end semantic equivalence for successful IR lowering.
    
    If `lowerToForwardGraph` returns an executable graph, evaluating that executable graph on any input
    matches the denotational semantics of the original IR graph.
    
    One side condition remains. `NoRawLog` excludes raw `.log`: the IR evaluator rejects nonpositive
    inputs while the lowered closure applies `Tensor.logSpec` to every input, so the two can only be
    compared under a positivity precondition the theorem does not carry.
    
    Every other operation kind is covered, including `.mseLoss` and `.concat` along any axis. The
    lowering accepts exactly the shapes the IR semantics accepts for `.matmul` and `.linear` (any shared
    leading shape, so rank at least four matmul and batched linear are covered); shapes rejected by the
    lowering never reach this theorem because `lowerToForwardGraph` returns an error for them.
    
Proof for Theorem 8.3.9
Proof uses 3
Proof dependency previews
Preview
Definition 8.1.21
Loading preview
Proof dependency preview content is loaded from the rendered-fragment cache.

After unfolding IR lowering, the proof peels off the structural check and input node. The recursive lowering invariant then matches each forward-graph value with the corresponding denotational value.