TorchLean API

NN.Tensor.Internal.Representation.Promotion

Element conversion and mixed-type tensor arithmetic #

TorchLean tensors remain homogeneous: every individual tensor has one element type and one corresponding physical storage representation. This module provides explicit element conversion and an extensible promotion relation for operations whose inputs have different element types.

The built-in promotion order is

UInt8 < Nat < Int < Rat < Float32 < Float

Moving from exact values to an IEEE type rounds to nearest with ties to even. Rational conversion rounds the exact quotient, avoiding intermediate numerator or denominator overflow. User-defined element types can participate by providing ElementCast and ElementPromotion instances.

class TorchLean.ElementCast (α : Type u) (β : Type v) :
Type (max u v)

An explicit element conversion used by Tensor.cast.

Instances need not be lossless. In particular, conversions to Float32 or Float use Lean's ordinary IEEE rounding behavior.

  • cast : αβ

    Convert one source element to the target element type.

Instances

    The common element type and two conversions selected for a mixed operation.

    The result is an outParam, so typeclass search determines it from the ordered input pair before looking for arithmetic or storage instances. Library instances are symmetric; custom instances should normally provide both operand orders.

    • left : αγ

      Convert the left element to the common type.

    • right : βγ

      Convert the right element to the common type.

    Instances
      @[inline]
      def TorchLean.ElementCast.apply {α : Type u} {β : Type v} [conversion : ElementCast α β] (value : α) :
      β

      Apply the registered element conversion.

      Instances For
        @[instance_reducible]
        def TorchLean.ElementPromotion.ofCasts (α β γ : Type) [leftCast : ElementCast α γ] [rightCast : ElementCast β γ] :

        Build a promotion from two explicit conversions to one result type.

        Instances For
          @[instance_reducible]
          instance TorchLean.instElementCast {α : Type u} :

          Every element type converts to itself.

          Round an exact rational through Lean's quotient and residual-bit model.

          Instances For

            Convert an exact rational to binary32, rounding once to nearest with ties to even.

            Small exactly representable integers use native division. Larger values use Lean's float model before packing, so a finite ratio near one does not become ∞ / ∞.

            Instances For

              Convert an exact rational to binary64, rounding once to nearest with ties to even.

              Instances For
                @[instance_reducible]

                Explicit binary64-to-binary32 conversion using Lean's IEEE rounding.

                @[instance_reducible]

                Execution strategy for pointwise tensor addition.

                The low-priority instance preserves the fully generic mixed-type operation. Packed element types can provide a higher-priority implementation while proving the same coordinate semantics.

                • scalar : αβγ

                  Scalar operation implemented by this tensor kernel.

                • apply {shape : Shape} : Rep α shapeRep β shapeRep γ shape

                  Build the pointwise sum.

                • apply_at {shape : Shape} (left : Rep α shape) (right : Rep β shape) (coordinate : Coord shape) : (apply left right).get coordinate = scalar (left.get coordinate) (right.get coordinate)

                  The tensor implementation agrees with its scalar operation.

                Instances
                  @[inline]
                  def TorchLean.Tensor.Internal.PointwiseAdd.run {α β γ : Type} [Storage α] [Storage β] [Storage γ] [operation : PointwiseAdd α β γ] {shape : Shape} (left : Rep α shape) (right : Rep β shape) :
                  Rep γ shape

                  Use the selected pointwise addition strategy.

                  Instances For

                    Execution strategy for pointwise tensor subtraction.

                    • scalar : αβγ

                      Scalar operation implemented by this tensor kernel.

                    • apply {shape : Shape} : Rep α shapeRep β shapeRep γ shape

                      Build the pointwise difference.

                    • apply_at {shape : Shape} (left : Rep α shape) (right : Rep β shape) (coordinate : Coord shape) : (apply left right).get coordinate = scalar (left.get coordinate) (right.get coordinate)

                      The tensor implementation agrees with its scalar operation.

                    Instances
                      @[inline]
                      def TorchLean.Tensor.Internal.PointwiseSub.run {α β γ : Type} [Storage α] [Storage β] [Storage γ] [operation : PointwiseSub α β γ] {shape : Shape} (left : Rep α shape) (right : Rep β shape) :
                      Rep γ shape

                      Use the selected pointwise subtraction strategy.

                      Instances For

                        Execution strategy for pointwise tensor multiplication.

                        • scalar : αβγ

                          Scalar operation implemented by this tensor kernel.

                        • apply {shape : Shape} : Rep α shapeRep β shapeRep γ shape

                          Build the pointwise product.

                        • apply_at {shape : Shape} (left : Rep α shape) (right : Rep β shape) (coordinate : Coord shape) : (apply left right).get coordinate = scalar (left.get coordinate) (right.get coordinate)

                          The tensor implementation agrees with its scalar operation.

                        Instances
                          @[inline]
                          def TorchLean.Tensor.Internal.PointwiseMul.run {α β γ : Type} [Storage α] [Storage β] [Storage γ] [operation : PointwiseMul α β γ] {shape : Shape} (left : Rep α shape) (right : Rep β shape) :
                          Rep γ shape

                          Use the selected pointwise multiplication strategy.

                          Instances For

                            Execution strategy for pointwise tensor division.

                            • scalar : αβγ

                              Scalar operation implemented by this tensor kernel.

                            • apply {shape : Shape} : Rep α shapeRep β shapeRep γ shape

                              Build the pointwise quotient.

                            • apply_at {shape : Shape} (left : Rep α shape) (right : Rep β shape) (coordinate : Coord shape) : (apply left right).get coordinate = scalar (left.get coordinate) (right.get coordinate)

                              The tensor implementation agrees with its scalar operation.

                            Instances
                              @[inline]
                              def TorchLean.Tensor.Internal.PointwiseDiv.run {α β γ : Type} [Storage α] [Storage β] [Storage γ] [operation : PointwiseDiv α β γ] {shape : Shape} (left : Rep α shape) (right : Rep β shape) :
                              Rep γ shape

                              Use the selected pointwise division strategy.

                              Instances For
                                @[instance_reducible, instance 100]

                                Generic one-pass fallback for every supported scalar promotion.

                                @[instance_reducible]

                                Packed Float addition uses one exact-size native output loop.

                                @[instance_reducible]

                                Packed byte-to-float promotion is fused with packed Float addition.

                                @[instance_reducible]

                                Packed Float addition is fused with packed byte-to-float promotion.

                                @[instance_reducible, instance 100]

                                Generic one-pass fallback for every supported subtraction promotion.

                                @[instance_reducible]

                                Packed Float subtraction uses one exact-size native output loop.

                                @[instance_reducible, instance 100]

                                Generic one-pass fallback for every supported multiplication promotion.

                                @[instance_reducible]

                                Packed Float multiplication uses one exact-size native output loop.

                                @[instance_reducible, instance 100]

                                Generic one-pass fallback for every supported division promotion.

                                @[instance_reducible]

                                Packed Float division uses one exact-size native output loop.

                                def TorchLean.Tensor.Internal.Rep.cast {α : Type u} [Storage α] {shape : Shape} (tensor : Rep α shape) (target : Type v) [Storage target] [ElementCast α target] :
                                Rep target shape

                                Convert every element while preserving the tensor's static shape.

                                The target Storage instance selects the target physical buffer, so a cast to Float writes a FloatArray and a cast to UInt8 writes a ByteArray.

                                Instances For
                                  @[simp]
                                  theorem TorchLean.Tensor.Internal.Rep.cast_apply {α : Type u} [Storage α] {shape : Shape} (tensor : Rep α shape) (target : Type v) [Storage target] [ElementCast α target] (coordinate : Coord shape) :
                                  (tensor.cast target).get coordinate = ElementCast.apply (tensor.get coordinate)

                                  Reading a cast tensor converts the element at the same coordinate.

                                  def TorchLean.Tensor.Internal.Rep.add {α β γ : Type} [Storage α] [Storage β] [Storage γ] [PointwiseAdd α β γ] {shape : Shape} (left : Rep α shape) (right : Rep β shape) :
                                  Rep γ shape

                                  Add two tensors pointwise, promoting their element types when necessary.

                                  Both conversions and the addition occur in one output-building pass.

                                  Instances For
                                    @[simp]
                                    theorem TorchLean.Tensor.Internal.Rep.add_apply {α β γ : Type} [Storage α] [Storage β] [Storage γ] [operation : PointwiseAdd α β γ] {shape : Shape} (left : Rep α shape) (right : Rep β shape) (coordinate : Coord shape) :
                                    (left.add right).get coordinate = PointwiseAdd.scalar (left.get coordinate) (right.get coordinate)

                                    Coordinate semantics of pointwise tensor addition.

                                    @[instance_reducible]
                                    instance TorchLean.Tensor.Internal.Rep.instHAddOfPointwiseAdd {α β γ : Type} [Storage α] [Storage β] [Storage γ] [PointwiseAdd α β γ] {shape : Shape} :
                                    HAdd (Rep α shape) (Rep β shape) (Rep γ shape)

                                    Tensor addition automatically selects the common element type.

                                    def TorchLean.Tensor.Internal.Rep.sub {α β γ : Type} [Storage α] [Storage β] [Storage γ] [PointwiseSub α β γ] {shape : Shape} (left : Rep α shape) (right : Rep β shape) :
                                    Rep γ shape

                                    Subtract two tensors pointwise, promoting their element types when necessary.

                                    Both conversions and the subtraction occur in one output-building pass.

                                    Instances For
                                      @[simp]
                                      theorem TorchLean.Tensor.Internal.Rep.sub_apply {α β γ : Type} [Storage α] [Storage β] [Storage γ] [operation : PointwiseSub α β γ] {shape : Shape} (left : Rep α shape) (right : Rep β shape) (coordinate : Coord shape) :
                                      (left.sub right).get coordinate = PointwiseSub.scalar (left.get coordinate) (right.get coordinate)

                                      Coordinate semantics of pointwise tensor subtraction.

                                      @[instance_reducible]
                                      instance TorchLean.Tensor.Internal.Rep.instHSubOfPointwiseSub {α β γ : Type} [Storage α] [Storage β] [Storage γ] [PointwiseSub α β γ] {shape : Shape} :
                                      HSub (Rep α shape) (Rep β shape) (Rep γ shape)

                                      Tensor subtraction automatically selects the common element type.

                                      def TorchLean.Tensor.Internal.Rep.mul {α β γ : Type} [Storage α] [Storage β] [Storage γ] [PointwiseMul α β γ] {shape : Shape} (left : Rep α shape) (right : Rep β shape) :
                                      Rep γ shape

                                      Multiply two tensors pointwise, promoting their element types when necessary.

                                      Both conversions and the multiplication occur in one output-building pass.

                                      Instances For
                                        @[simp]
                                        theorem TorchLean.Tensor.Internal.Rep.mul_apply {α β γ : Type} [Storage α] [Storage β] [Storage γ] [operation : PointwiseMul α β γ] {shape : Shape} (left : Rep α shape) (right : Rep β shape) (coordinate : Coord shape) :
                                        (left.mul right).get coordinate = PointwiseMul.scalar (left.get coordinate) (right.get coordinate)

                                        Coordinate semantics of pointwise tensor multiplication.

                                        @[instance_reducible]
                                        instance TorchLean.Tensor.Internal.Rep.instHMulOfPointwiseMul {α β γ : Type} [Storage α] [Storage β] [Storage γ] [PointwiseMul α β γ] {shape : Shape} :
                                        HMul (Rep α shape) (Rep β shape) (Rep γ shape)

                                        Tensor multiplication automatically selects the common element type.

                                        def TorchLean.Tensor.Internal.Rep.div {α β γ : Type} [Storage α] [Storage β] [Storage γ] [PointwiseDiv α β γ] {shape : Shape} (left : Rep α shape) (right : Rep β shape) :
                                        Rep γ shape

                                        Divide two tensors pointwise, promoting their element types when necessary.

                                        Both conversions and the division occur in one output-building pass.

                                        Instances For
                                          @[simp]
                                          theorem TorchLean.Tensor.Internal.Rep.div_apply {α β γ : Type} [Storage α] [Storage β] [Storage γ] [operation : PointwiseDiv α β γ] {shape : Shape} (left : Rep α shape) (right : Rep β shape) (coordinate : Coord shape) :
                                          (left.div right).get coordinate = PointwiseDiv.scalar (left.get coordinate) (right.get coordinate)

                                          Coordinate semantics of pointwise tensor division.

                                          @[instance_reducible]
                                          instance TorchLean.Tensor.Internal.Rep.instHDivOfPointwiseDiv {α β γ : Type} [Storage α] [Storage β] [Storage γ] [PointwiseDiv α β γ] {shape : Shape} :
                                          HDiv (Rep α shape) (Rep β shape) (Rep γ shape)

                                          Tensor division automatically selects the common element type.