TorchLean API

NN.Runtime.Autograd.Model.Session.Eager

Session #

TorchLean unified imperative session.

Session state #

A Session α is TorchLean's runtime analogue of a PyTorch "training loop environment". It:

TorchLean exposes a single API with two execution modes selected at construction time:

Both modes use the same Session API; each operation dispatches through Session.state.

Typical Training Loop (PyTorch Analogy) #

Think of the following mapping (approximately):

TorchLean does not store mutable .grad fields on each tensor ref; instead, gradients are returned explicitly (see grad, vjp, and the backward*DenseAll functions).

Non-Differentiable State (NatRef) #

NatRef stores the seed and counter used by the explicit random stream. Non-differentiable tensor inputs use the element-polymorphic data-input channel rather than a second session tensor type.

Deterministic RNG (Session-Level) #

RngState provides explicit, deterministic RNG state (closer to JAX PRNG keys than a global RNG). freshSeedIO is a convenience for sampling an initial seed at the IO boundary, while the core semantics remains seed-threaded and replayable.

Connection To TorchLean IR / Graph Execution #

In .typedGraph execution, the session records executable GraphData while building the tape. Each call to resetTape starts a new recording phase. Callers that need one reusable artifact should use Runtime.Autograd.Torch.TypedGraph directly; the high-level scalar trainer uses that artifact and records its loss graph once.

The type-level context checks graph shapes. Correctness of a stored JVP or VJP is a separate claim, proved only for operations connected to the proof-carrying Proofs.Autograd.Algebra.Node layer.

Practical note: the current .typedGraph implementation expects all leaves (tensor inputs/parameters and NatRefs) to be created before any op nodes are recorded. For portability, allocate leaves and initialize/split RNG up-front, then build the typed graph.

PyTorch References #

AD References #

This code follows the classic "tape / Wengert list" view of reverse-mode AD:

Eager-only session wrapper.

This is the public eager-session record backed by the internal tape session Runtime.Autograd.Torch.Internal.EagerSession. Users normally interact with the unified Session API; this type exists to support execution-mode dispatch (SessionState.eager).

  • The internal tape session being wrapped. The extra layer exists so the execution-mode dispatch in SessionState has a public type to name.

Instances For

    Create a new eager (tape-backed) session.

    This corresponds to the .eager execution mode of Session.new.

    Instances For

      Reset the eager autograd tape and begin a fresh recording phase.

      Instances For
        def Runtime.Autograd.Model.EagerSession.param {α : Type} [TorchLean.Storage α] (s : EagerSession α) {sh : Spec.Shape} (init : TorchLean.Tensor α sh) (name : Option String := none) (requiresGrad : Option Bool := none) :
        IO (Torch.Param α sh)

        Create a learnable parameter owned by this session.

        PyTorch analogy: creating a torch.nn.Parameter during module initialization.

        Instances For

          Use a parameter in the current eager recording.

          PyTorch analogy: reading a parameter in forward (it becomes part of the autograd graph).

          Instances For

            Add a tensor input leaf to the current graph.

            requiresGrad controls whether this input is recorded as a differentiable leaf.

            Instances For

              Add a non-differentiable Nat leaf to the session.

              Used for labels/indices and gather-style ops.

              Instances For

                Read a NatRef value.

                Instances For

                  Mutate a NatRef value.

                  Instances For

                    Insert a constant tensor into the current graph.

                    PyTorch analogy: using a tensor literal/constant in the forward pass (as a leaf constant node).

                    Instances For

                      Read the concrete value for a tensor ref (for logging/debugging).

                      Instances For

                        Detach a tensor ref from the tape (stop gradient flow through it).

                        PyTorch analogy: x.detach().

                        Instances For

                          Elementwise addition on tensor refs (eager execution path).

                          Instances For

                            Elementwise subtraction on tensor refs (eager execution path).

                            Instances For

                              Elementwise multiplication on tensor refs (eager execution path).

                              Instances For

                                Elementwise scaling by a scalar constant c (eager execution path).

                                Instances For
                                  def Runtime.Autograd.Model.EagerSession.abs {α : Type} [TorchLean.Storage α] (s : EagerSession α) [Context α] [DecidableRel fun (x1 x2 : α) => x1 > x2] {sh : Spec.Shape} (x : Torch.TensorRef α sh) :

                                  Elementwise absolute value (eager execution path).

                                  Instances For
                                    def Runtime.Autograd.Model.EagerSession.sqrt {α : Type} [TorchLean.Storage α] (s : EagerSession α) [Context α] [DecidableRel fun (x1 x2 : α) => x1 > x2] {sh : Spec.Shape} (x : Torch.TensorRef α sh) :

                                    Elementwise square root (eager execution path).

                                    Instances For
                                      def Runtime.Autograd.Model.EagerSession.clamp {α : Type} [TorchLean.Storage α] (s : EagerSession α) [Context α] [DecidableRel fun (x1 x2 : α) => x1 > x2] [Torch.TensorTransfer α] {sh : Spec.Shape} (x : Torch.TensorRef α sh) (minVal maxVal : α) :

                                      Elementwise clamp to [minVal, maxVal] (eager execution path).

                                      Instances For
                                        def Runtime.Autograd.Model.EagerSession.max {α : Type} [TorchLean.Storage α] (s : EagerSession α) [Context α] [DecidableRel fun (x1 x2 : α) => x1 > x2] {sh : Spec.Shape} (a b : Torch.TensorRef α sh) :

                                        Elementwise maximum (eager execution path).

                                        Instances For
                                          def Runtime.Autograd.Model.EagerSession.min {α : Type} [TorchLean.Storage α] (s : EagerSession α) [Context α] [DecidableRel fun (x1 x2 : α) => x1 > x2] {sh : Spec.Shape} (a b : Torch.TensorRef α sh) :

                                          Elementwise minimum (eager execution path).

                                          Instances For
                                            def Runtime.Autograd.Model.EagerSession.matmul {α : Type} [TorchLean.Storage α] (s : EagerSession α) [Context α] {batchA batchB batch : Spec.Shape} {m n p : } [broadcastA : batchA.BroadcastTo batch] [broadcastB : batchB.BroadcastTo batch] (a : Torch.TensorRef α (batchA.concat [m, n])) (b : Torch.TensorRef α (batchB.concat [n, p])) :
                                            IO (Torch.TensorRef α (batch.concat [m, p]))

                                            Matrix multiplication with broadcasted batch prefixes (eager execution path).

                                            Instances For

                                              Concatenate along the outermost dimension (dimension 0) (eager execution path).

                                              PyTorch analogy: torch.cat([a, b], dim=0).

                                              Instances For
                                                def Runtime.Autograd.Model.EagerSession.sliceLeadingAxisRange {α : Type} [TorchLean.Storage α] (s : EagerSession α) [Zero α] {n : } {sh : Spec.Shape} (x : Torch.TensorRef α (Spec.Shape.dim n sh)) (start len : ) (h : start + len n) :

                                                Slice a contiguous [start, start+len) range from dimension 0 (eager execution path).

                                                PyTorch analogy: x[start:start+len] for the first dimension.

                                                Instances For
                                                  def Runtime.Autograd.Model.EagerSession.maxPool {α : Type} [TorchLean.Storage α] (s : EagerSession α) [Context α] {d channels : } {spatial kernel stride padding : TorchLean.Tensor [d]} (x : Torch.TensorRef α (Spec.Shape.ofList (channels :: spatial.to (List )))) :
                                                  IO (Torch.TensorRef α (Spec.Shape.ofList (channels :: (Spec.poolOutSpatialPad spatial kernel stride padding).to (List ))))

                                                  Apply max pooling over an arbitrary number of spatial axes.

                                                  Instances For
                                                    def Runtime.Autograd.Model.EagerSession.smoothMaxPool {α : Type} [TorchLean.Storage α] (s : EagerSession α) [Context α] [DecidableEq α] [Torch.TensorTransfer α] {d channels : } {spatial kernel stride padding : TorchLean.Tensor [d]} (x : Torch.TensorRef α (Spec.Shape.ofList (channels :: spatial.to (List )))) (beta : α) :
                                                    IO (Torch.TensorRef α (Spec.Shape.ofList (channels :: (Spec.poolOutSpatialPad spatial kernel stride padding).to (List ))))

                                                    Apply smooth max pooling over an arbitrary number of spatial axes.

                                                    Instances For
                                                      def Runtime.Autograd.Model.EagerSession.avgPool {α : Type} [TorchLean.Storage α] (s : EagerSession α) [Context α] {d channels : } {spatial kernel stride padding : TorchLean.Tensor [d]} (x : Torch.TensorRef α (Spec.Shape.ofList (channels :: spatial.to (List )))) :
                                                      IO (Torch.TensorRef α (Spec.Shape.ofList (channels :: (Spec.poolOutSpatialPad spatial kernel stride padding).to (List ))))

                                                      Apply average pooling over an arbitrary number of spatial axes.

                                                      Instances For
                                                        def Runtime.Autograd.Model.EagerSession.relu {α : Type} [TorchLean.Storage α] (s : EagerSession α) [Mul α] [Zero α] [Max α] [BEq α] [One α] [LT α] [DecidableRel fun (x1 x2 : α) => x1 > x2] {sh : Spec.Shape} (x : Torch.TensorRef α sh) :

                                                        Elementwise ReLU activation (eager execution path).

                                                        Instances For

                                                          Elementwise sigmoid activation (eager execution path).

                                                          Instances For

                                                            Elementwise tanh activation (eager execution path).

                                                            Instances For

                                                              Softmax along an explicitly selected tensor dimension (eager execution path).

                                                              Instances For

                                                                Stable log-softmax along an explicitly selected tensor dimension (eager execution path).

                                                                Instances For

                                                                  Elementwise softplus activation (eager execution path).

                                                                  Instances For

                                                                    Elementwise exponential (eager execution path).

                                                                    Instances For

                                                                      Elementwise sine of angles in radians, recorded on the eager session's tape.

                                                                      Instances For

                                                                        Elementwise cosine with the eager tape's -sin(x) * dLdy backward rule.

                                                                        Instances For

                                                                          Elementwise logarithm (eager execution path).

                                                                          Instances For

                                                                            Elementwise safeLog activation (log(softplus(x) + ε)) (eager execution path).

                                                                            Instances For

                                                                              Sum-reduce a tensor to a scalar (eager execution path).

                                                                              Instances For

                                                                                Flatten a tensor into a 1D vector (eager execution path).

                                                                                Instances For

                                                                                  Reshape a tensor, given a proof that the total number of elements is preserved (eager execution path).

                                                                                  PyTorch analogy: x.reshape(...) when the element count matches.

                                                                                  Instances For

                                                                                    Generic "swap adjacent axes" view operation (eager execution path).

                                                                                    This is a shape-driven permutation helper used in some attention/transformer code.

                                                                                    Instances For

                                                                                      Broadcast a tensor to a larger shape (eager execution path).

                                                                                      Instances For

                                                                                        Reduce-sum along an axis (eager execution path).

                                                                                        Instances For

                                                                                          Reduce-mean along an axis (eager execution path).

                                                                                          Instances For
                                                                                            def Runtime.Autograd.Model.EagerSession.select {α : Type} [TorchLean.Storage α] (s : EagerSession α) [Zero α] {shape : Spec.Shape} (axis : ) (x : Torch.TensorRef α shape) [Spec.Shape.AxisInBounds axis shape] (index : Fin (shape.axisSize axis)) :
                                                                                            IO (Torch.TensorRef α (shape.eraseAxis axis))

                                                                                            Select one bounded coordinate from an arbitrary tensor axis.

                                                                                            Instances For
                                                                                              def Runtime.Autograd.Model.EagerSession.indexSelect {α : Type} [TorchLean.Storage α] (s : EagerSession α) [Add α] [Zero α] {shape : Spec.Shape} (axis count : ) (x : Torch.TensorRef α shape) [Spec.Shape.AxisInBounds axis shape] (indices : TorchLean.Tensor (Fin (shape.axisSize axis)) [count]) :
                                                                                              IO (Torch.TensorRef α (shape.replaceAxis axis count))

                                                                                              Select several bounded coordinates from an arbitrary tensor axis.

                                                                                              Instances For
                                                                                                def Runtime.Autograd.Model.EagerSession.scatterAdd {α : Type} [TorchLean.Storage α] (s : EagerSession α) [Add α] [Zero α] {shape : Spec.Shape} (axis count : ) (base : Torch.TensorRef α shape) [Spec.Shape.AxisInBounds axis shape] (source : Torch.TensorRef α (shape.replaceAxis axis count)) (indices : TorchLean.Tensor (Fin (shape.axisSize axis)) [count]) :
                                                                                                IO (Torch.TensorRef α shape)

                                                                                                Add source slices into an arbitrary tensor axis at bounded coordinates.

                                                                                                Instances For
                                                                                                  def Runtime.Autograd.Model.EagerSession.linear {α : Type} [TorchLean.Storage α] (s : EagerSession α) [Inhabited α] [Add α] [Mul α] [Zero α] {inDim outDim : } (w : Torch.TensorRef α [outDim, inDim]) (b : Torch.TensorRef α [outDim]) (x : Torch.TensorRef α [inDim]) :
                                                                                                  IO (Torch.TensorRef α [outDim])

                                                                                                  Fully-connected (affine) layer on vectors: y = w·x + b (eager execution path).

                                                                                                  PyTorch analogue: torch.nn.functional.linear (with weight shape (outDim, inDim)).

                                                                                                  Instances For

                                                                                                    Mean squared error loss returning a scalar (eager execution path).

                                                                                                    PyTorch analogue: torch.nn.functional.mse_loss(..., reduction='mean').

                                                                                                    Instances For
                                                                                                      def Runtime.Autograd.Model.EagerSession.layerNorm {α : Type} [TorchLean.Storage α] (s : EagerSession α) [Context α] [Torch.TensorTransfer α] [DecidableRel fun (x1 x2 : α) => x1 > x2] {seqLen embedDim : } (h_seq_pos : seqLen > 0) (h_embed_pos : embedDim > 0) (x : Torch.TensorRef α [seqLen, embedDim]) (gamma beta : Torch.TensorRef α [embedDim]) (epsilon : α := TorchLean.normalizationEpsilon) :
                                                                                                      IO (Torch.TensorRef α [seqLen, embedDim])

                                                                                                      LayerNorm over a seqLen × embedDim tensor (eager execution path).

                                                                                                      PyTorch analogue: torch.nn.LayerNorm(embedDim) applied per token.

                                                                                                      Instances For
                                                                                                        def Runtime.Autograd.Model.EagerSession.batchNorm {α : Type} [TorchLean.Storage α] (s : EagerSession α) [Context α] [Torch.TensorTransfer α] [DecidableRel fun (x1 x2 : α) => x1 > x2] {channels : } {sSpatial : Spec.Shape} (hWellFormed : (Spec.Shape.dim channels sSpatial).wellFormed) (x : Torch.TensorRef α (Spec.Shape.dim channels sSpatial)) (gamma beta : Torch.TensorRef α [channels]) (epsilon : α := TorchLean.normalizationEpsilon) :
                                                                                                        IO (Torch.TensorRef α (Spec.Shape.dim channels sSpatial))

                                                                                                        Batch normalization over every spatial axis of a channel-first tensor.

                                                                                                        Instances For
                                                                                                          def Runtime.Autograd.Model.EagerSession.conv {α : Type} [TorchLean.Storage α] (s : EagerSession α) [Context α] {d inC outC : } {kernel stride padding inSpatial : TorchLean.Tensor [d]} (w : Torch.TensorRef α (Spec.Shape.ofList (outC :: inC :: kernel.to (List )))) (b : Torch.TensorRef α [outC]) (x : Torch.TensorRef α (Spec.Shape.ofList (inC :: inSpatial.to (List )))) :
                                                                                                          IO (Torch.TensorRef α (Spec.Shape.ofList (outC :: (Spec.convOutSpatial inSpatial kernel stride padding).to (List ))))

                                                                                                          N-D convolution over a channels-first tensor (inC, spatial...) (eager execution path).

                                                                                                          PyTorch analogue: torch.nn.functional.conv{d}d specialized to a single sample.

                                                                                                          Instances For
                                                                                                            def Runtime.Autograd.Model.EagerSession.convTranspose {α : Type} [TorchLean.Storage α] (s : EagerSession α) [Context α] {d inC outC : } {kernel stride padding inSpatial : TorchLean.Tensor [d]} (w : Torch.TensorRef α (Spec.Shape.ofList (inC :: outC :: kernel.to (List )))) (b : Torch.TensorRef α [outC]) (x : Torch.TensorRef α (Spec.Shape.ofList (inC :: inSpatial.to (List )))) :
                                                                                                            IO (Torch.TensorRef α (Spec.Shape.ofList (outC :: (Spec.convTransposeOutSpatial inSpatial kernel stride padding).to (List ))))

                                                                                                            N-D transpose convolution over a channels-first tensor (inC, spatial...) (eager execution path).

                                                                                                            PyTorch analogue: torch.nn.functional.conv_transpose{d}d specialized to a single sample.

                                                                                                            Instances For
                                                                                                              def Runtime.Autograd.Model.EagerSession.multiHeadAttention {α : Type} [TorchLean.Storage α] (s : EagerSession α) [Context α] [DecidableRel fun (x1 x2 : α) => x1 > x2] {n numHeads dModel headDim : } (h1 : n 0) (wq wk wv : Torch.TensorRef α [dModel, numHeads * headDim]) (wo : Torch.TensorRef α [numHeads * headDim, dModel]) (x : Torch.TensorRef α [n, dModel]) (mask : Option (TorchLean.Tensor Bool [n, n]) := none) :
                                                                                                              IO (Torch.TensorRef α [n, dModel])

                                                                                                              Multi-head self-attention (eager execution path).

                                                                                                              This is the eager implementation used by the transformer examples (approximately analogous to torch.nn.MultiheadAttention in self-attention mode).

                                                                                                              Instances For

                                                                                                                Run a backward pass and return dense gradients for all leaves (eager execution path).

                                                                                                                See the unified version Session.backwardDenseAll for the public API.

                                                                                                                Instances For

                                                                                                                  Backward pass specialized to scalar losses (seed is implicitly 1) (eager execution path).

                                                                                                                  Instances For

                                                                                                                    Apply an SGD step to all learnable parameters given a dense gradient array (eager execution path).

                                                                                                                    PyTorch analogy: optimizer.step() for an SGD optimizer, with gradients supplied explicitly.

                                                                                                                    Instances For