anchor.diff:      /// A backend type is delivered consistent with in-memory data - a type for dtype Int32 gets int32 data etc.
       abstract CreateFromFlatArray: data: System.Array * shape: int[] * device: Device -> RawTensor
   
  +    /// Get the backend implementation for the given tensor element type and backend.
       static member Get(?dtype: Dtype, ?backend: Backend) =
           // Note we re-examing the default backends etc. each time we create a root tensor.
           let dtype = defaultArg dtype Dtype.Default
  
positive.code: 
          statics.CreateFromFlatArray(data, shape, device)
  
      member t.CreateLike(values: obj, ?dtype: Dtype, ?device: Device, ?backend: Backend) =
          RawTensor.Create(values, dtype=defaultArg dtype t.Dtype, device=defaultArg device t.Device, backend=defaultArg backend t.Backend)
  
      member t.ZeroLike(?dtype: Dtype, ?device: Device, ?backend: Backend) =
          RawTensor.Zero(dtype=defaultArg dtype t.Dtype, device=defaultArg device t.Device, backend=defaultArg backend t.Backend)
  
      member t.ZerosLike(shape: int[], ?dtype: Dtype, ?device: Device, ?backend: Backend) =
          RawTensor.Zeros(shape=shape, dtype=defaultArg dtype t.Dtype, device=defaultArg device t.Device, backend=defaultArg backend t.Backend)
  
      member t.OneLike(?dtype: Dtype, ?device: Device, ?backend: Backend) =
          RawTensor.One(dtype=defaultArg dtype t.Dtype, device=defaultArg device t.Device, backend=defaultArg backend t.Backend)
  
      member t.OnesLike(shape: int[], ?dtype: Dtype, ?device: Device, ?backend: Backend) =
          RawTensor.Ones(shape=shape, dtype=defaultArg dtype t.Dtype, device=defaultArg device t.Device, backend=defaultArg backend t.Backend)
  
      member t.FullLike(shape: int[], value: obj, ?dtype: Dtype, ?device: Device, ?backend: Backend) =
          RawTensor.Full(shape, value, dtype=defaultArg dtype t.Dtype, device=defaultArg device t.Device, backend=defaultArg backend t.Backend)
  
      member t.RandomLike(shape: int[], ?dtype: Dtype, ?device: Device, ?backend: Backend) =
          RawTensor.Random(shape=shape, dtype=defaultArg dtype t.Dtype, device=defaultArg device t.Device, backend=defaultArg backend t.Backend)
  
      member t.RandomNormalLike(shape: int[], ?dtype: Dtype, ?device: Device, ?backend: Backend) =
          RawTensor.RandomNormal(shape=shape, dtype=defaultArg dtype t.Dtype, device=defaultArg device t.Device, backend=defaultArg backend t.Backend)
  
      member t.RandomIntLike(shape: int[], low:int, high:int, ?dtype: Dtype, ?device: Device, ?backend: Backend) =
          RawTensor.RandomInt(shape=shape, low=low, high=high, dtype=defaultArg dtype t.Dtype, device=defaultArg device t.Device, backend=defaultArg backend t.Backend)
  
      abstract member Clone : unit -> RawTensor
      abstract member Expand: newShape: int[] -> RawTensor
      abstract member StackTs: RawTensor[] * dim:int -> RawTensor
      abstract member UnstackT: dim:int -> RawTensor[]
      abstract member CatTs: RawTensor[] * dim: int -> RawTensor
      abstract member SplitT: int[] * dim: int -> RawTensor[]
      abstract member GetString: unit -> string
      
      /// The indexes are an Nx3 array.   The first row is the start bounds, the second row is
      /// the end bounds, the third is 1/0 indicating dimension removal.
      abstract member GetSlice: int[,] -> RawTensor
  
      abstract member ToValues: unit -> obj
      abstract member Equals: RawTensor -> bool
      abstract member Cast : Dtype -> RawTensor
      abstract member MoveTo : Device -> RawTensor
      abstract member ComputeHash: unit -> int
      abstract member AllClose: RawTensor * float * float -> bool
      abstract member ClampT: RawTensor * RawTensor -> RawTensor
      abstract member GatherT: int * RawTensor -> RawTensor
      abstract member LtTT: RawTensor -> RawTensor
      abstract member GtTT: RawTensor -> RawTensor
      abstract member LeTT: RawTensor -> RawTensor
      abstract member GeTT: RawTensor -> RawTensor
      abstract member EqTT: RawTensor -> RawTensor
      abstract member NeqTT: RawTensor -> RawTensor
      abstract member IsInfT : unit -> RawTensor
      abstract member IsNaNT : unit -> RawTensor
      abstract member GetItem : [<System.ParamArray>] indexes: int[] -> obj 
      abstract member MaxIndexT : unit -> int[]
      abstract member MinIndexT : unit -> int[]
      abstract member AddTT : RawTensor -> RawTensor
      abstract member AddTT0 : RawTensor -> RawTensor
      abstract member AddT2T1: RawTensor -> RawTensor
      abstract member AddTTSlice: int[] * RawTensor -> RawTensor
      abstract member SubTT : RawTensor -> RawTensor
      abstract member SubT0T : RawTensor -> RawTensor
      abstract member SubTT0 : RawTensor -> RawTensor
      abstract member MulTT : RawTensor -> RawTensor
      abstract member MulTT0 : RawTensor -> RawTensor
      abstract member DivTT : RawTensor -> RawTensor
      abstract member DivT0T : RawTensor -> RawTensor
      abstract member DivTT0 : RawTensor -> RawTensor
      abstract member PowTT : RawTensor -> RawTensor
      abstract member PowT0T: RawTensor -> RawTensor
      abstract member PowTT0 : RawTensor -> RawTensor
      abstract member MatMulT2T2: RawTensor -> RawTensor
      abstract member MaxPool1D: int * int * int -> RawTensor * RawTensor
      abstract member MaxPool2D: int[] * int[] * int[] -> RawTensor * RawTensor
      abstract member MaxPool3D: int[] * int[] * int[] -> RawTensor * RawTensor
      abstract member MaxUnpool1D: RawTensor * int[] -> RawTensor
      abstract member MaxUnpool2D: RawTensor * int[] -> RawTensor
      abstract member MaxUnpool3D: RawTensor * int[] -> RawTensor
      abstract member Conv1D: RawTensor * int * int -> RawTensor
      abstract member Conv2D: RawTensor * int[] * int[] -> RawTensor
      abstract member Conv3D: RawTensor * int[] * int[] -> RawTensor
      abstract member NegT : unit -> RawTensor
      abstract member SumT : ?resultType: Dtype -> RawTensor
      abstract member SumT2Dim0 : unit -> RawTensor
      abstract member TransposeT: int * int -> RawTensor
      abstract member TransposeT2: unit -> RawTensor
      abstract member SqueezeT: int -> RawTensor
      abstract member UnsqueezeT: int -> RawTensor
      abstract member FlipT: int[] -> RawTensor
      abstract member DilateT: int[] -> RawTensor
      abstract member UndilateT: int[] -> RawTensor
      abstract member ViewT: int[] -> RawTensor
      abstract member SignT: unit -> RawTensor
      abstract member FloorT: unit -> RawTensor
      abstract member CeilT: unit -> RawTensor
      abstract member RoundT: unit -> RawTensor
      abstract member AbsT: unit -> RawTensor
      abstract member ReluT: unit -> RawTensor
      abstract member SoftplusT: unit -> RawTensor
      abstract member SigmoidT: unit -> RawTensor
      abstract member ExpT: unit -> RawTensor
      abstract member LogT: unit -> RawTensor
      abstract member Log10T: unit -> RawTensor
      abstract member SqrtT: unit -> RawTensor
      abstract member SinT: unit -> RawTensor
      abstract member CosT: unit -> RawTensor
      abstract member TanT: unit -> RawTensor
      abstract member SinhT: unit -> RawTensor
      abstract member CoshT: unit -> RawTensor
      abstract member TanhT: unit -> RawTensor
      abstract member AsinT: unit -> RawTensor
      abstract member AcosT: unit -> RawTensor
      abstract member AtanT: unit -> RawTensor
  
      default t.IsInfT() =
  
negative.code: open DiffSharp
  open DiffSharp.Util
  
  /// <summary>
  ///   Represents the static functionality implemented by a DiffSharp backend for a particular tensor element type.
  /// </summary>
  ///
  /// <namespacedoc>
  ///   <summary>Contains types and functionality related to backend implementations for DiffSharp.</summary>
  /// </namespacedoc>
  [<AbstractClass>]
  type BackendStatics() = 
      // cache for most recently accessed backend
      static let mutable last = None
      static let backends = System.Collections.Concurrent.ConcurrentDictionary<int, BackendStatics>()
  
      /// Sets the seed for the default random number generator of the backend
      abstract Seed: seed:int -> unit
  
      /// Gets the scalar 0 tensor for the given device
      abstract Zero: device: Device -> RawTensor
  
      /// Gets a tensor filled with zeros for the given shape and device
      abstract Zeros: shape:int[] * device: Device -> RawTensor
  
      /// Gets the scalar 1 tensor for the given device
      abstract One: device: Device -> RawTensor
  
      /// Gets a tensor filled with ones for the given shape and device
      abstract Ones: shape:int[] * device: Device -> RawTensor
  
      /// Gets a tensor filled with the given value for the given shape and device
      abstract Full: shape:int[] * value: obj * device: Device -> RawTensor
  
      /// Gets a tensor filled with random values for the given shape and device
      abstract Random: shape:int[] * device: Device -> RawTensor
  
      /// Gets a tensor filled with random values from the normal distribution for the given shape and device
      abstract RandomNormal: shape:int[] * device: Device -> RawTensor
  
      /// Gets a tensor filled with random integers from the given range for the given shape and device
      abstract RandomInt: shape:int[] * low:int * high:int * device: Device -> RawTensor
  
      /// Gets the devices supported by this backend
      abstract GetDevices: ?deviceType: DeviceType -> Device list
  
      /// Indicates if a device type is supported by this backend
      abstract IsDeviceTypeSupported: deviceType: DeviceType -> bool
      
      /// Seed all backends with the given random seed, or a new seed based on the current time
      /// if no seed is specified.
      static member Seed(?seed:int) =
          let seed = defaultArg seed (int DateTime.Now.Ticks)
          Random.Seed(seed) // Do not remove. util.Random seed would be set by the Reference backend if it's currently loaded. However we still need to keep this here to ensure util.Random seed is set (it may be used in code other than the Reference backend).
  