TorchLean API

NN.Tensor.Internal.Representation.Storage

Physical Tensor Storage #

Storage α selects the physical buffer used by tensors with scalar type α. Arbitrary scalar types retain ordinary Array α storage. Float uses Lean's unboxed FloatArray runtime representation, while UInt8 uses ByteArray.

The toArray laws are the proof boundary: the kernel reasons about an ordinary array observation, while compiled code calls the specialized buffer operations directly. Selected pointwise, slice, and transpose operations also have proof-visible Lean definitions with native compiled replacements. The Lean theorems describe those definitions; agreement of the external C bodies is a native runtime boundary documented in docs/TRUST_BOUNDARIES.md.

@[irreducible, specialize #[]]
def TorchLean.Tensor.Internal.Elab.Impl.nativeFinFoldlLoop {α : Type u} (length : ) (step : α(index : USize) → index.toNat < lengthα) (bound : USize) (hBound : bound.toNat = length) (index : USize) (value : α) :
α

Run the tail-recursive engine used by nativeFinFoldl.

hBound and the callback's index proof are erased. The executable loop therefore carries only an unboxed bound, counter, and accumulator.

Instances For
    @[inline]
    def TorchLean.Tensor.Internal.Elab.Impl.nativeFinFoldl {α : Type u} (length : ) (bound : USize) (hBound : bound.toNat = length) (step : α(index : USize) → index.toNat < lengthα) (initial : α) :
    α

    Fold over Fin length with a platform-native loop counter.

    The caller supplies a native bound together with an erased proof that it represents the semantic length.

    Instances For
      theorem TorchLean.Tensor.Internal.Elab.Impl.nativeFinFoldl_eq_fin_foldl {α : Type u} (length : ) (bound : USize) (hBound : bound.toNat = length) (step : αFin lengthα) (initial : α) :
      nativeFinFoldl length bound hBound (fun (value : α) (index : USize) (hIndex : index.toNat < length) => step value index.toNat, hIndex) initial = Fin.foldl length step initial

      nativeFinFoldl computes exactly Fin.foldl.

      Generated kernels can execute with an unboxed counter while proofs continue to reason about the standard finite enumeration.

      theorem TorchLean.Tensor.Internal.Elab.Impl.nativeFinFoldl_eq_fin_foldl_of_eq {α : Type u} (length : ) (bound : USize) (hBound : bound.toNat = length) (nativeStep : α(index : USize) → index.toNat < lengthα) (step : αFin lengthα) (initial : α) (hStep : ∀ (value : α) (index : USize) (hIndex : index.toNat < length), nativeStep value index hIndex = step value index.toNat, hIndex) :
      nativeFinFoldl length bound hBound nativeStep initial = Fin.foldl length step initial

      A native callback computes the semantic finite fold when it agrees with the semantic callback at every represented index.

      class TorchLean.Storage (α : Type u) :
      Type (u + 1)

      Physical tensor storage for one scalar type.

      The buffer operations are used by generated native kernels. toArray is their proof-facing observation and may allocate when explicitly evaluated; optimized code therefore stays on Buffer, get, uget, push, and appendSlice.

      • Buffer : Type u

        Physical row-major scalar buffer.

      • emptyWithCapacity : Buffer α

        Allocate an empty buffer with room for the requested number of scalars.

      • push : Buffer ααBuffer α

        Append one scalar.

      • appendSlice : Buffer αBuffer αBuffer α

        Append a contiguous half-open source interval to an output buffer.

      • foldl {β : Type u} : (βαβ)βBuffer αβ

        Traverse the physical buffer in row-major order.

      • size : Buffer α

        Number of scalar entries in the buffer.

      • copyAt (source : Buffer α) (index : USize) : index.toNat < size sourceBuffer αBuffer α

        Copy one physical entry from a source buffer into an output buffer.

        Unlike push output (uget source index ...), this primitive does not expose the scalar at the caller boundary. Generic arrays can therefore transfer an existing boxed object directly, while scalar arrays read and write their unboxed representation.

      • gather (source : Buffer α) (length : ) (bound : USize) : bound.toNat = length(sourceIndices : (index : USize) → index.toNat < lengthUSize) → (∀ (index : USize) (hIndex : index.toNat < length), (sourceIndices index hIndex).toNat < size source)Buffer α

        Build a buffer by gathering physical entries from one source buffer.

        The storage implementation owns the complete loop so backend selection happens once per tensor rather than once per copied scalar.

      • gather_eq_nativeFinFoldl (source : Buffer α) (length : ) (bound : USize) (hBound : bound.toNat = length) (sourceIndices : (index : USize) → index.toNat < lengthUSize) (hSourceIndices : ∀ (index : USize) (hIndex : index.toNat < length), (sourceIndices index hIndex).toNat < size source) : gather source length bound hBound sourceIndices hSourceIndices = Tensor.Internal.Elab.Impl.nativeFinFoldl length bound hBound (fun (output : Buffer α) (index : USize) (hIndex : index.toNat < length) => copyAt source (sourceIndices index hIndex) output) (emptyWithCapacity length)

        Physical gathering is the storage-specific native finite loop.

      • get (buffer : Buffer α) (index : ) : index < size bufferα

        Read one scalar using a natural-number index.

      • uget (buffer : Buffer α) (index : USize) : index.toNat < size bufferα

        Read one scalar using a platform-native index.

      • toArray : Buffer αArray α

        Observe the physical buffer as an ordinary logical array.

      • ofArray : Array αBuffer α

        Construct physical storage from an ordinary array.

      • toArray_size (buffer : Buffer α) : (toArray buffer).size = size buffer

        Buffer observation preserves size.

      • toArray_get (buffer : Buffer α) (index : ) (hBuffer : index < size buffer) (hArray : index < (toArray buffer).size) : (toArray buffer)[index] = get buffer index hBuffer

        Buffer observation preserves natural-number reads.

      • toArray_uget (buffer : Buffer α) (index : USize) (hBuffer : index.toNat < size buffer) (hArray : index.toNat < (toArray buffer).size) : (toArray buffer).uget index hArray = uget buffer index hBuffer

        Buffer observation preserves platform-native reads.

      • toArray_emptyWithCapacity (capacity : ) : toArray (emptyWithCapacity capacity) = Array.emptyWithCapacity capacity

        An empty physical buffer observes as an empty ordinary array.

      • toArray_push (buffer : Buffer α) (value : α) : toArray (push buffer value) = (toArray buffer).push value

        Appending one scalar commutes with buffer observation.

      • toArray_copyAt (source : Buffer α) (index : USize) (hBuffer : index.toNat < size source) (output : Buffer α) (hArray : index.toNat < (toArray source).size) : toArray (copyAt source index hBuffer output) = (toArray output).push ((toArray source).uget index hArray)

        Copying one physical entry commutes with buffer observation.

      • toArray_appendSlice (source : Buffer α) (start stop : ) (output : Buffer α) : toArray (appendSlice source start stop output) = toArray output ++ (toArray source).extract start stop

        Appending a source interval commutes with buffer observation.

      • toArray_foldl {β : Type u} (step : βαβ) (initial : β) (buffer : Buffer α) : foldl step initial buffer = Array.foldl step initial (toArray buffer)

        Row-major traversal agrees with folding the ordinary array observation.

      • toArray_ofArray (values : Array α) : toArray (ofArray values) = values

        Converting from an ordinary array is inverse to observation.

      • toArray_injective : Function.Injective toArray

        The ordinary array observation uniquely determines physical storage.

      Instances
        class TorchLean.Storage.Update (α : Type u) [storage : Storage α] :

        Copy-on-write replacement of one physical scalar.

        Every Storage receives the ordinary-array fallback below, so defining a custom scalar storage does not require implementing this capability. Packed backends can override it to retain their native representation.

        • set (buffer : Buffer α) (index : ) : index < size bufferαBuffer α

          Replace one in-bounds physical entry.

        • toArray_set (buffer : Buffer α) (index : ) (hBuffer : index < size buffer) (value : α) : toArray (set buffer index hBuffer value) = (toArray buffer).set index value

          Physical replacement agrees with ordinary-array replacement.

        Instances
          @[instance_reducible, instance 100]
          instance TorchLean.Storage.instUpdate (α : Type u) [storage : Storage α] :

          Universal update support for any storage.

          This fallback round-trips through the logical array observation. Specialized packed storage overrides it below with native copy-on-write replacement.

          theorem TorchLean.Storage.copyAt_eq_push_of_uget_eq {α : Type u} [storage : Storage α] (source : Buffer α) (index : USize) (hSource : index.toNat < size source) (output : Buffer α) (value : α) (hValue : uget source index hSource = value) :
          copyAt source index hSource output = push output value

          Copying a physical entry is the same buffer update as pushing its observed scalar value.

          Generated movement kernels use this theorem to reason about copyAt without exposing the scalar at the executable callback boundary.

          def TorchLean.Storage.ofFn {α : Type u} [storage : Storage α] {length : } (values : Fin lengthα) :

          Construct a physical buffer from a finite scalar function.

          Instances For
            theorem TorchLean.Storage.fin_foldl_push_eq_array_ofFn {α : Type u} (length : ) (values : Fin lengthα) :
            Fin.foldl length (fun (output : Array α) (index : Fin length) => output.push (values index)) (Array.emptyWithCapacity length) = Array.ofFn values

            Pushing finite-indexed values in order constructs Array.ofFn.

            theorem TorchLean.Storage.toArray_finFoldl_push_eq_array_ofFn {α : Type u} [storage : Storage α] {length : } (capacity : ) (values : Fin lengthα) :
            toArray (Fin.foldl length (fun (output : Buffer α) (index : Fin length) => push output (values index)) (emptyWithCapacity capacity)) = Array.ofFn values

            Observing finite pushes from any reserved capacity gives the corresponding ordinary function array.

            theorem TorchLean.Storage.toArray_ofFn {α : Type u} [storage : Storage α] {length : } (values : Fin lengthα) :
            toArray (ofFn values) = Array.ofFn values

            Finite construction observes as the corresponding ordinary array.

            theorem TorchLean.Storage.size_ofFn {α : Type u} [storage : Storage α] {length : } (values : Fin lengthα) :
            size (ofFn values) = length

            Finite construction creates exactly the requested number of scalars.

            theorem TorchLean.Storage.size_eq_of_toArray_eq_ofFn {α : Type u} [storage : Storage α] {length : } (buffer : Buffer α) (values : Fin lengthα) (hData : toArray buffer = Array.ofFn values) :
            size buffer = length

            An Array.ofFn observation determines the physical buffer size.

            theorem TorchLean.Storage.size_emptyWithCapacity {α : Type u} [storage : Storage α] (capacity : ) :
            size (emptyWithCapacity capacity) = 0

            Empty physical storage contains no scalar entries.

            theorem TorchLean.Storage.size_push {α : Type u} [storage : Storage α] (buffer : Buffer α) (value : α) :
            size (push buffer value) = size buffer + 1

            Appending one scalar increases physical storage length by one.

            theorem TorchLean.Storage.size_ofArray {α : Type u} [storage : Storage α] (values : Array α) :
            size (ofArray values) = values.size

            Constructing physical storage from an array preserves its length.

            @[inline]
            def TorchLean.appendArraySlice {α : Type u} (source : Array α) (start stop : ) (output : Array α) :

            Append one contiguous ordinary-array interval to an output array.

            Instances For
              theorem TorchLean.appendArraySlice_eq_append_extract {α : Type u} (source : Array α) (start stop : ) (output : Array α) :
              appendArraySlice source start stop output = output ++ source.extract start stop

              Ordinary-array slice traversal is extraction followed by append.

              @[inline, specialize #[]]
              def TorchLean.copyArrayAt {α : Type u} (source : Array α) (index : USize) (hIndex : index.toNat < source.size) (output : Array α) :

              Copy one ordinary-array entry without exposing its scalar at the caller boundary.

              Specializing a scalar-valued callback can unbox and immediately rebox values such as Float32. Keeping the transfer inside this polymorphic primitive lets Lean's runtime retain and move the existing lean_object* instead.

              Instances For
                @[specialize #[]]
                def TorchLean.gatherArray {α : Type u} (source : Array α) (length : ) (bound : USize) (hBound : bound.toNat = length) (sourceIndices : (index : USize) → index.toNat < lengthUSize) (hSourceIndices : ∀ (index : USize) (hIndex : index.toNat < length), (sourceIndices index hIndex).toNat < source.size) :

                Gather ordinary-array entries without exposing their scalar values.

                Instances For
                  @[instance_reducible, inline, instance 100]

                  Ordinary polymorphic arrays are the universal tensor-storage fallback.

                  @[implemented_by ByteArray.emptyWithCapacity]

                  Proof-visible model of the native empty ByteArray allocator.

                  Compiled code calls Lean's built-in scalar-array runtime primitive.

                  Instances For
                    @[implemented_by ByteArray.push]

                    Proof-visible model of native ByteArray.push.

                    Instances For
                      @[implemented_by ByteArray.size]

                      Proof-visible model of native ByteArray.size.

                      Instances For
                        @[inline]
                        unsafe def TorchLean.Storage.Internal.byteBufferCopyAtFast (source : ByteArray) (index : USize) (_hIndex : index.toNat < byteBufferSize source) (output : ByteArray) :

                        Fast native transfer between byte buffers.

                        Instances For
                          @[implemented_by TorchLean.Storage.Internal.byteBufferCopyAtFast]
                          def TorchLean.Storage.Internal.byteBufferCopyAt (source : ByteArray) (index : USize) (hIndex : index.toNat < byteBufferSize source) (output : ByteArray) :

                          Proof-visible model of one native byte-buffer transfer.

                          Instances For
                            @[inline]
                            unsafe def TorchLean.Storage.Internal.byteBufferGetFast (buffer : ByteArray) (index : ) (_hIndex : index < byteBufferSize buffer) :

                            Runtime adapter from the proof-visible byte-buffer bound to ByteArray.get.

                            Instances For
                              @[implemented_by TorchLean.Storage.Internal.byteBufferGetFast]
                              def TorchLean.Storage.Internal.byteBufferGet (buffer : ByteArray) (index : ) :
                              index < byteBufferSize bufferUInt8

                              Proof-visible model of native natural-number ByteArray lookup.

                              Instances For
                                @[inline]
                                unsafe def TorchLean.Storage.Internal.byteBufferSetFast (buffer : ByteArray) (index : ) (_hIndex : index < byteBufferSize buffer) (value : UInt8) :

                                Fast native replacement in a packed byte buffer.

                                Instances For
                                  @[implemented_by TorchLean.Storage.Internal.byteBufferSetFast]
                                  def TorchLean.Storage.Internal.byteBufferSet (buffer : ByteArray) (index : ) (hIndex : index < byteBufferSize buffer) (value : UInt8) :

                                  Proof-visible model of native byte-buffer replacement.

                                  Instances For
                                    @[inline]
                                    unsafe def TorchLean.Storage.Internal.byteBufferUGetFast (buffer : ByteArray) (index : USize) (_hIndex : index.toNat < byteBufferSize buffer) :

                                    Runtime adapter from the proof-visible byte-buffer bound to ByteArray.uget.

                                    Instances For
                                      @[implemented_by TorchLean.Storage.Internal.byteBufferUGetFast]

                                      Proof-visible model of native USize ByteArray lookup.

                                      Instances For
                                        @[inline]
                                        def TorchLean.Storage.Internal.byteBufferGather (source : ByteArray) (length : ) (bound : USize) (hBound : bound.toNat = length) (sourceIndices : (index : USize) → index.toNat < lengthUSize) (hSourceIndices : ∀ (index : USize) (hIndex : index.toNat < length), (sourceIndices index hIndex).toNat < byteBufferSize source) :

                                        Gather native byte-buffer entries in one storage-specific loop.

                                        Instances For
                                          @[inline]

                                          Fast native implementation of contiguous byte-buffer copying.

                                          Clamp before calling ByteArray.copySlice: its native allocator may reserve the requested length before clipping the source interval. The model follows Array.extract, including huge naturals.

                                          Instances For
                                            @[implemented_by TorchLean.Storage.Internal.byteBufferAppendSliceFast]

                                            Proof-visible model of contiguous native ByteArray traversal.

                                            The logical body exposes ordinary array extraction. Native code delegates the whole interval to Lean's built-in ByteArray.copySlice runtime primitive.

                                            Instances For
                                              @[inline]
                                              def TorchLean.Storage.Internal.byteBufferFoldlFast {β : Type u} (step : βUInt8β) (initial : β) (buffer : ByteArray) :
                                              β

                                              Fast native traversal of an unboxed byte buffer.

                                              Instances For
                                                @[implemented_by TorchLean.Storage.Internal.byteBufferFoldlFast]
                                                def TorchLean.Storage.Internal.byteBufferFoldl {β : Type u} (step : βUInt8β) (initial : β) (buffer : ByteArray) :
                                                β

                                                Proof-visible model of native ByteArray traversal.

                                                The logical body exposes the ordinary array fold. Native code traverses the unboxed byte buffer directly.

                                                Instances For
                                                  @[irreducible, implemented_by FloatArray.emptyWithCapacity]

                                                  Proof-visible model of the native empty FloatArray allocator.

                                                  Compiled code calls Lean's built-in scalar-array runtime primitive.

                                                  Instances For
                                                    @[irreducible, implemented_by FloatArray.push]

                                                    Proof-visible model of native FloatArray.push.

                                                    Instances For
                                                      @[irreducible, implemented_by FloatArray.size]

                                                      Proof-visible model of native FloatArray.size.

                                                      Instances For
                                                        @[inline]
                                                        unsafe def TorchLean.Storage.Internal.floatBufferCopyAtFast (source : FloatArray) (index : USize) (_hIndex : index.toNat < floatBufferSize source) (output : FloatArray) :

                                                        Fast native transfer between floating-point buffers.

                                                        Instances For
                                                          @[implemented_by TorchLean.Storage.Internal.floatBufferCopyAtFast]
                                                          def TorchLean.Storage.Internal.floatBufferCopyAt (source : FloatArray) (index : USize) (hIndex : index.toNat < floatBufferSize source) (output : FloatArray) :

                                                          Proof-visible model of one native floating-point-buffer transfer.

                                                          Instances For
                                                            @[inline]
                                                            unsafe def TorchLean.Storage.Internal.floatBufferGetFast (buffer : FloatArray) (index : ) (_hIndex : index < floatBufferSize buffer) :

                                                            Runtime adapter from the proof-visible float-buffer bound to FloatArray.get.

                                                            Instances For
                                                              @[irreducible, implemented_by TorchLean.Storage.Internal.floatBufferGetFast]

                                                              Proof-visible model of native natural-number FloatArray lookup.

                                                              Instances For
                                                                @[inline]
                                                                unsafe def TorchLean.Storage.Internal.floatBufferUGetFast (buffer : FloatArray) (index : USize) (_hIndex : index.toNat < floatBufferSize buffer) :

                                                                Runtime adapter from the proof-visible float-buffer bound to FloatArray.uget.

                                                                Instances For
                                                                  @[irreducible, implemented_by TorchLean.Storage.Internal.floatBufferUGetFast]

                                                                  Proof-visible model of native USize FloatArray lookup.

                                                                  Instances For
                                                                    @[inline]
                                                                    def TorchLean.Storage.Internal.floatBufferGather (source : FloatArray) (length : ) (bound : USize) (hBound : bound.toNat = length) (sourceIndices : (index : USize) → index.toNat < lengthUSize) (hSourceIndices : ∀ (index : USize) (hIndex : index.toNat < length), (sourceIndices index hIndex).toNat < floatBufferSize source) :

                                                                    Gather native floating-point-buffer entries in one storage-specific loop.

                                                                    Instances For

                                                                      Proof-visible model of contiguous native FloatArray traversal.

                                                                      The logical body exposes ordinary array extraction.

                                                                      Instances For
                                                                        @[extern torchlean_float_array_append_slice]

                                                                        Native implementation of contiguous packed floating-point copying.

                                                                        The body calls the reference rather than restating it, so the rfl below cannot drift; compiled code replaces the whole thing with torchlean_float_array_append_slice.

                                                                        Instances For
                                                                          @[csimp]

                                                                          Compile packed floating-point slice appends to one native bulk-copy call.

                                                                          Lean evaluation and proofs continue to unfold floatBufferAppendSlice; only generated code uses the external implementation.

                                                                          @[inline]
                                                                          def TorchLean.Storage.Internal.floatBufferFoldlFast {β : Type u} (step : βFloatβ) (initial : β) (buffer : FloatArray) :
                                                                          β

                                                                          Fast native traversal of an unboxed floating-point buffer.

                                                                          Instances For
                                                                            @[implemented_by TorchLean.Storage.Internal.floatBufferFoldlFast]
                                                                            def TorchLean.Storage.Internal.floatBufferFoldl {β : Type u} (step : βFloatβ) (initial : β) (buffer : FloatArray) :
                                                                            β

                                                                            Proof-visible model of native FloatArray traversal.

                                                                            The logical body exposes the ordinary array fold. Native code traverses the unboxed floating-point buffer directly.

                                                                            Instances For
                                                                              @[inline]
                                                                              unsafe def TorchLean.Storage.Internal.floatBufferSetFast (buffer : FloatArray) (index : ) (_hIndex : index < floatBufferSize buffer) (value : Float) :

                                                                              Fast native replacement in an unboxed floating-point buffer.

                                                                              Instances For
                                                                                @[irreducible, implemented_by TorchLean.Storage.Internal.floatBufferSetFast]
                                                                                def TorchLean.Storage.Internal.floatBufferSet (buffer : FloatArray) (index : ) (hIndex : index < floatBufferSize buffer) (value : Float) :

                                                                                Proof-visible model of native floating-point-buffer replacement.

                                                                                Instances For
                                                                                  @[instance_reducible]

                                                                                  UInt8 tensors use Lean's packed native byte-array representation.

                                                                                  @[instance_reducible]

                                                                                  Float tensors use Lean's unboxed native scalar-array representation.

                                                                                  @[instance_reducible]

                                                                                  Byte tensors replace entries directly in their packed native buffer.

                                                                                  @[instance_reducible]

                                                                                  Float tensors replace entries directly in their unboxed native buffer.