TorchLean API

NN.Spec.Core.TensorReductionShape.ConcatSlice

Concatenation and Slicing #

Concatenation, slicing, sequence concatenation, squeeze/unsqueeze, and channel layout transforms.

def Spec.Tensor.matchShape {α : Type} {s : Shape} (t : Tensor α s) :

Runtime check that a tensor value matches a runtime Shape.

We use this in a few “dynamic” utilities where we have a runtime shape value and want to guard access/casts in a total way.

Instances For
    def Spec.Tensor.concatSpec {α : Type} [Inhabited α] {n d : } (headCount : ) (tensors : List (Tensor α (Shape.dim n (Shape.dim d Shape.scalar)))) (_h_len : tensors.length = headCount) :
    Tensor α (Shape.dim n (Shape.dim (headCount * d) Shape.scalar))

    Concatenate a list of (n,d) tensors along the last axis, producing (n, headCount*d).

    This is mainly used by attention blocks that split/merge heads.

    PyTorch analogy: torch.cat(heads, dim=-1) after splitting heads, followed by a reshape.

    Instances For
      def Spec.Tensor.concatSpec.buildRow {α : Type} {n d : } (i : Fin n) (ts : List (Tensor α (Shape.dim n (Shape.dim d Shape.scalar)))) :
      List α
      Instances For

        Concatenate two vectors by appending v2 after v1.

        Instances For
          def Spec.Tensor.concatDim0Spec {α : Type} {n m : } {s : Shape} (t1 : Tensor α (Shape.dim n s)) (t2 : Tensor α (Shape.dim m s)) :
          Tensor α (Shape.dim (n + m) s)

          Concatenate along axis 0 (append t2 after t1).

          Instances For

            Slicing / concatenation on the leading axis #

            concat_dim0_spec is the "append on axis 0" primitive that powers many higher-level utilities (sequence concatenation, channel skip connections, etc.).

            For backprop and for "undoing" concatenations, it is convenient to have an explicit slice operation. We keep the API compact and index-safe:

            def Spec.Tensor.sliceRange0Spec {α : Type} {n : } {s : Shape} (start len : ) (h : len + start n) (t : Tensor α (Shape.dim n s)) :
            Tensor α (Shape.dim len s)

            Slice len entries along axis 0, starting at start.

            This is the simplest "range slice" one typically needs to express:

            • taking the first n channels/tokens,
            • extracting the skip-connection half after a concat,
            • implementing take/drop without changing the inner shape.

            The proof len + start ≤ n makes the slice total (no out-of-bounds behavior).

            Instances For
              def Spec.Tensor.concatDim0BackwardSpec {α : Type} {n m : } {s : Shape} (δ : Tensor α (Shape.dim (n + m) s)) :
              Tensor α (Shape.dim n s) × Tensor α (Shape.dim m s)

              Backward (adjoint) of concat_dim0_spec.

              If y = concat_dim0_spec x1 x2, then in reverse-mode we split the upstream gradient δy into:

              • δx1 = the first n entries of δy,
              • δx2 = the last m entries of δy.
              Instances For
                def Spec.Tensor.sliceRange0BackwardSpec {α : Type} [Zero α] {n : } {s : Shape} (start len : ) (_h : len + start n) (δ : Tensor α (Shape.dim len s)) :
                Tensor α (Shape.dim n s)

                Backward (adjoint) of slice_range0_spec.

                If y = slice_range0_spec start len x, then slice_range0_backward_spec start len δy re-inserts the gradient into the original shape and fills everything outside the slice with zeros.

                Instances For
                  def Spec.Tensor.concatSequenceSpec {α : Type} {seqLen1 seqLen2 hiddenSize : } (seq1 : Tensor α (Shape.dim seqLen1 (Shape.dim hiddenSize Shape.scalar))) (seq2 : Tensor α (Shape.dim seqLen2 (Shape.dim hiddenSize Shape.scalar))) :
                  Tensor α (Shape.dim (seqLen1 + seqLen2) (Shape.dim hiddenSize Shape.scalar))

                  Concatenate two sequences along time (axis 0), producing a longer sequence.

                  If seq1 : (seqLen1 x hidden) and seq2 : (seqLen2 x hidden), this returns (seqLen1 + seqLen2) x hidden by appending seq2 after seq1.

                  Do not confuse this with Spec.concatSequenceSpec (defined in NN.Spec.Core.Sequence), which concatenates along the feature dimension for same-length sequences.

                  Instances For
                    def Spec.Tensor.concatSequenceInnerSpec {α : Type} {seqLen hiddenSize1 hiddenSize2 : } (seq1 : Tensor α (Shape.dim seqLen (Shape.dim hiddenSize1 Shape.scalar))) (seq2 : Tensor α (Shape.dim seqLen (Shape.dim hiddenSize2 Shape.scalar))) :
                    Tensor α (Shape.dim seqLen (Shape.dim (hiddenSize1 + hiddenSize2) Shape.scalar))

                    Concatenate two sequences along the feature dimension (inner axis).

                    Instances For
                      def Spec.Tensor.expandToColSpec {α : Type} {n : } {s : Shape} (t : Tensor α (Shape.dim n s)) :

                      Expand a (n, s) tensor into (n, 1, s) by inserting a trailing dimension of size 1.

                      PyTorch analogy: t.unsqueeze(-1) for a rank-1 outer dimension (or unsqueeze(dim=1) in 2D terms).

                      Instances For

                        Same as expand_to_col_spec, specialized to vectors.

                        Instances For
                          def Spec.Tensor.squeezeColSpec {α : Type} {n : } {s : Shape} (t : Tensor α (Shape.dim n (Shape.dim 1 s))) :
                          Tensor α (Shape.dim n s)

                          Squeeze a (n,1,s) tensor back into (n,s) by dropping the singleton dimension.

                          Instances For

                            Same as squeeze_col_spec, specialized to vectors.

                            Instances For
                              def Spec.Tensor.unsqueezeSpec {α : Type} {n : } {s : Shape} (t : Tensor α (Shape.dim n s)) (_dim : ) :

                              Unsqueeze (insert a singleton dim). Currently implemented as expand_to_col_spec.

                              Core uses singleton insertion mainly for column vectors, so this operation is specialized to that use case. General axis insertion can extend this definition.

                              Instances For

                                Turn a vector (n) into a batch of size 1: (1,n).

                                Instances For
                                  def Spec.Tensor.batchToEndSpec {α : Type} {batch : } {s : Shape} (t : Tensor α (Shape.dim batch s)) :
                                  Tensor α (s.appendDim batch)

                                  Move a leading batch dimension to the innermost position.

                                  Instances For

                                    Convert channel-first images (b,c,h,w) into channel-last (b,h,w,c).

                                    Instances For