TorchLean API

NN.Proofs.RuntimeApprox.NF.BackwardOps.Backend

NF Backward Approximation Backend #

Core approximation lemmas for the rounded NF backend: constants, sparse context writes, and the context-addition bound used when reverse-mode contributions have to be accumulated.

theorem Proofs.RuntimeApprox.NFBackend.idx_shape_eq_of_i_eq {Γ : List Spec.Shape} {s₁ s₂ : Spec.Shape} (a : Idx Γ s₁) (b : Idx Γ s₂) (h : a.i = b.i) :
s₁ = s₂

Two context indices pointing at the same position must have the same shape.

An Idx Γ s bundles a position with a proof that Γ holds shape s there, so equal positions force equal shapes. This is what makes the disjointness lemmas below usable: a proof that two indices differ can be given by comparing positions only, with no shape reasoning.

def Proofs.RuntimeApprox.NFBackend.tensorCastOfIdxEq {α : Type} [TorchLean.Storage α] {Γ : List Spec.Shape} {s₁ s₂ : Spec.Shape} (a : Idx Γ s₁) (b : Idx Γ s₂) (h : a.i = b.i) :

Cast a tensor across a shape equality induced by equal Idx positions.

Given a : Idx Γ s₁, b : Idx Γ s₂, and h : a.i = b.i, this produces a function Tensor α s₂ → Tensor α s₁ that casts along the implied equality s₁ = s₂.

Instances For

    Approximation is stable under transporting both tensors along the same shape equality.

    The all-zero context approximates the all-zero context, at zero error.

    This is the base case of every backward-pass bound: gradient accumulation starts from zeros on both the spec and the runtime side, and zero is exactly representable, so nothing is lost yet.

    Writing one approximate tensor into an otherwise-zero context keeps the context approximate, with the error recorded at that slot alone.

    theorem Proofs.RuntimeApprox.NFBackend.approxCtx_set2Idx_ne {β : FloatLib.Numerics.Radix} {fexp : } [FloatLib.Floats.Formats.Flocq.ValidExp fexp] {rnd : } [FloatLib.Floats.Formats.Flocq.ValidRndToNearest rnd] {Γ : List Spec.Shape} {s₁ s₂ : Spec.Shape} (a : Idx Γ s₁) (b : Idx Γ s₂) {t₁S : Spec.SpecTensor s₁} {t₁R : TorchLean.Tensor (FloatLib.Floats.Formats.Flocq.NF β fexp rnd) s₁} {eps₁ : } {t₂S : Spec.SpecTensor s₂} {t₂R : TorchLean.Tensor (FloatLib.Floats.Formats.Flocq.NF β fexp rnd) s₂} {eps₂ : } (h₁ : approxTensor toSpec t₁S t₁R eps₁) (h₂ : approxTensor toSpec t₂S t₂R eps₂) (hne : a.i b.i) :
    approxCtx toSpec (SparseContext.set2Idx a t₁S b t₂S) (SparseContext.set2Idx a t₁R b t₂R) (EList.set2Idx a eps₁ b eps₂ 0)

    Two writes at distinct positions do not interfere: each slot carries its own error bound.

    Distinctness is essential. If the indices coincided the two contributions would have to be added, and the sum would carry the sum of the errors rather than either one.

    theorem Proofs.RuntimeApprox.NFBackend.approxCtx_set3Idx_ne {β : FloatLib.Numerics.Radix} {fexp : } [FloatLib.Floats.Formats.Flocq.ValidExp fexp] {rnd : } [FloatLib.Floats.Formats.Flocq.ValidRndToNearest rnd] {Γ : List Spec.Shape} {s₁ s₂ s₃ : Spec.Shape} (a : Idx Γ s₁) (b : Idx Γ s₂) (c : Idx Γ s₃) {t₁S : Spec.SpecTensor s₁} {t₁R : TorchLean.Tensor (FloatLib.Floats.Formats.Flocq.NF β fexp rnd) s₁} {eps₁ : } {t₂S : Spec.SpecTensor s₂} {t₂R : TorchLean.Tensor (FloatLib.Floats.Formats.Flocq.NF β fexp rnd) s₂} {eps₂ : } {t₃S : Spec.SpecTensor s₃} {t₃R : TorchLean.Tensor (FloatLib.Floats.Formats.Flocq.NF β fexp rnd) s₃} {eps₃ : } (h₁ : approxTensor toSpec t₁S t₁R eps₁) (h₂ : approxTensor toSpec t₂S t₂R eps₂) (h₃ : approxTensor toSpec t₃S t₃R eps₃) (hab : a.i b.i) (hac : a.i c.i) (hbc : b.i c.i) :
    approxCtx toSpec (SparseContext.set3IdxNe a t₁S b t₂S c t₃S hab hac hbc) (SparseContext.set3IdxNe a t₁R b t₂R c t₃R hab hac hbc) (EList.set3IdxNe a eps₁ b eps₂ c eps₃ hab hac hbc)

    Same again for three pairwise-distinct writes, which is what a ternary node's backward pass needs.

    Context-wise addition bound (NF runtime vs spec).

    This produces an EList of linfNorm bounds for adding two contexts elementwise, and is used when reverse-mode accumulation must combine contributions from multiple consumers.

    Instances For

      Soundness of context-wise addition under approxCtx.

      If xS ~ xR ± epsx and yS ~ yR ± epsy, then (xS + yS) ~ (xR + yR) with error bounded by ctxAddBound epsx epsy xR yR.