anchor.diff:      override __.Message = __.msg
   
   
  -/// Type-neutral interface to Tensor<'T> of any type 'T.
  +/// <summary>Type-neutral interface to Tensor&lt;'T&gt; of any type 'T.</summary>
  +/// <remarks>These functions are useful for working with tensors of unknown types.
  +/// For most use cases the functions provided by <see cref="Tensor`1"/> are better suited.</remarks>
  +/// <seealso cref="Tensor`1"/>
   type ITensor =
   
       /// layout of this tensor (shape, offset and strides)
  
positive.code:     /// <returns>Sequence of indicies.</returns>
      /// <remarks>The sequence sequentially enumerates the indices of all elements of the tensor.</remarks>
      /// <seealso cref="allIdxOfDim``1"/><seealso cref="allElems"/>
      static member allIdx (a: Tensor<'T>) = a.Layout |> TensorLayout.allIdx
  
      /// <summary>Gets a sequence of all indices to enumerate all elements of the specified dimension of the tensor.</summary>
      /// <param name="dim">The dimension to enumerate.</param>
  
negative.code:                     a.Shape a.Layout.Stride
              raise (InvalidOperationException msg)
  
      /// <summary>Changes the shape of a tensor.</summary>
      /// <param name="shp">The target shape.</param>
      /// <param name="a">The tensor to operate on.</param>
      /// <returns>A tensor of the specified shape.</returns>
      /// <seealso cref="Tensor`1.reshape``1"/>
      let reshape shp (a: ITensor) =
          match a |> tryReshapeView shp with
          | Some res -> res
          | None -> a.Copy() |> reshapeView shp
  
      /// <summary>Flattens the tensor into a (one-dimensional) vector.</summary>
      /// <param name="a">The tensor to operate on.</param>
      /// <returns>A vector.</returns>
      /// <seealso cref="Tensor`1.flatten``1"/>
      let flatten (a: ITensor) =
          reshape [Remainder] a    
  
      /// <summary>Swaps the specified dimensions of the tensor.</summary>
      /// <param name="ax1">The dimension to swap.</param>
      /// <param name="ax2">The dimension to swap with.</param>
      /// <param name="a">The tensor to operate on.</param>
      /// <returns>The tensor with the dimensions swapped.</returns>
      /// <seealso cref="Tensor`1.swapDim``1"/>
      let swapDim ax1 ax2 (a: ITensor) =
          a.Relayout (a.Layout |> TensorLayout.swapDim ax1 ax2)
  
      /// <summary>Transpose of a matrix.</summary>
      /// <param name="a">The tensor to operate on.</param>
      /// <returns>The result of this operation.</returns>
      /// <seealso cref="Tensor`1.transpose"/>
      let transpose (a: ITensor) =
          a.Relayout (a.Layout |> TensorLayout.transpose)
  
      /// <summary>Permutes the axes as specified.</summary>
      /// <param name="permut">The permutation to apply to the dimensions of tensor.</param>
      /// <param name="a">The tensor to operate on.</param>
      /// <returns>The tensor with the dimensions permuted.</returns>
      /// <seealso cref="Tensor`1.permuteAxes``1"/>
      let permuteAxes (permut: int list) (a: ITensor) =
          a.Relayout (a.Layout |> TensorLayout.permuteAxes permut)
  
      /// <summary>Reverses the elements in the specified dimension.</summary>
      /// <param name="ax">The axis to reverse.</param>
      /// <param name="a">The tensor to operate on.</param>
      /// <returns>The tensor with the dimensions permuted.</returns>
      /// <seealso cref="Tensor`1.reverseAxis``1"/>
      let reverseAxis ax (a: ITensor) =
          a.Relayout (a.Layout |> TensorLayout.reverseAxis ax)        
  
      /// <summary>Pads the tensor from the left with size-one dimensions until it has at least the specified number of
      /// dimensions.</summary>
      /// <param name="minDims">The minimum number of dimensions.</param>
      /// <param name="a">The tensor to operate on.</param>
      /// <returns>A tensor with at least <paramref name="minDims"/> dimensions.</returns>
      /// <seealso cref="Tensor`1.atLeastND``1"/>
      let atLeastND minDims (a: ITensor) =
          if a.NDims >= minDims then a
          else
              let newShp = List.init (minDims - a.NDims) (fun _ -> 1L)
              a |> reshape newShp
  
      /// <summary>Pads the tensor from the left with size-one dimensions until it has at least one dimension.</summary>
      /// <param name="a">The tensor to operate on.</param>
      /// <returns>A tensor with at least one dimensions.</returns>
      /// <seealso cref="Tensor`1.atLeast1D``1"/>
      let atLeast1D (a: ITensor) = a |> atLeastND 1
  
      /// <summary>Pads the tensor from the left with size-one dimensions until it has at least two dimensions.</summary>
      /// <param name="a">The tensor to operate on.</param>
      /// <returns>A tensor with at least two dimensions.</returns>
      /// <seealso cref="Tensor`1.atLeast2D``1"/>
      let atLeast2D (a: ITensor) = a |> atLeastND 2
  
      /// <summary>Pads the tensor from the left with size-one dimensions until it has at least three dimensions.</summary>
      /// <param name="a">The tensor to operate on.</param>
      /// <returns>A tensor with at least three dimensions.</returns>
      /// <seealso cref="Tensor`1.atLeast3D``1"/>
      let atLeast3D (a: ITensor) = a |> atLeastND 3
  
      /// <summary>Returns a copy of the tensor.</summary>
      /// <param name="a">The tensor to copy.</param>
      /// <param name="order">The memory layout of the copy. (default: row-major)</param>
      /// <returns>A copy of the tensor.</returns>
      /// <seealso cref="Tensor`1.copy``1"/>
      let copy (a: ITensor) = a.Copy()
  
      /// <summary>Transfers a tensor to the specifed device.</summary>
      /// <param name="dev">The target device.</param>
      /// <param name="a">The tensor to transfer.</param>
      /// <returns>A tensor on the target device.</returns>
      /// <seealso cref="Tensor`1.transfer``1"/>
      let transfer (dev: ITensorDevice) (src: ITensor) =
          src.Transfer (dev)
          
  