anchor.diff:  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
  -    abstract Full: shape:int[] * obj * 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).
  
positive.code:     /// 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
  
      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
  
negative.code:             last <- Some (code, res)
              res
  
  /// <summary>
  ///   Represents a raw (i.e. non-differentiable) tensor implemented by a DiffSharp backend.
  /// </summary>
  ///
  /// <remarks>
  ///  Each backend will provide one of more .NET implementations of this type, which may in turn
  ///  wrap handles to native implementations.
  /// </remarks>
  [<AbstractClass>]
  type RawTensor() =
  
      /// Gets the shape of the tensor
      abstract member Shape : int[]
  
      /// Gets the dimensionality of the tensor
      abstract member Dim : int
  
      /// Gets the number of logical elements in the tensor
      abstract member Nelement : int
  
      /// Gets the element storage type for the tensor
      abstract member Dtype : Dtype
  
      /// Gets the device for the tensor
      abstract member Device : Device
  
      /// Gets the device type for the tensor
      abstract member DeviceType : DeviceType
  
      /// Gets the backend for the tensor
      abstract member Backend : Backend
  
      override t.ToString() = t.GetString()
      
      /// Gets the scalar zero tensor for the given configuration
      static member Zero(?dtype, ?device, ?backend) = 
          let statics = BackendStatics.Get(?dtype=dtype, ?backend=backend)
          let device = defaultArg device Device.Default
          statics.Zero(device)
  
      /// Gets the zero tensor for the given shape and configuration
      static member Zeros(shape, ?dtype, ?device, ?backend) = 
          let statics = BackendStatics.Get(?dtype=dtype, ?backend=backend)
          let device = defaultArg device Device.Default
          statics.Zeros(shape, device)
  
      /// Gets the scalar 1 tensor for the given configuration
      static member One(?dtype, ?device, ?backend) = 
          let statics = BackendStatics.Get(?dtype=dtype, ?backend=backend)
          let device = defaultArg device Device.Default
          statics.One(device)
  
      /// Gets a tensor filled with 1 values for the given shape and configuration
      static member Ones(shape, ?dtype, ?device, ?backend) =
          let statics = BackendStatics.Get(?dtype=dtype, ?backend=backend)
          let device = defaultArg device Device.Default
          statics.Ones(shape, device)
  
      /// Gets a tensor filled with the given value for the given shape and configuration
      static member Full(shape, value, ?dtype, ?device, ?backend) =
          let statics = BackendStatics.Get(?dtype=dtype, ?backend=backend)
          let device = defaultArg device Device.Default
          statics.Full(shape, value, device)
  
      /// Gets a tensor filled with random values for the given shape and configuration
      static member Random(shape, ?dtype, ?device, ?backend) =
          let statics = BackendStatics.Get(?dtype=dtype, ?backend=backend)
          let device = defaultArg device Device.Default
          statics.Random(shape, device)
  
      /// Gets a tensor filled with random values from the normal distribution for the given shape and configuration
      static member RandomNormal(shape, ?dtype, ?device, ?backend) =
          let statics = BackendStatics.Get(?dtype=dtype, ?backend=backend)
          let device = defaultArg device Device.Default
          statics.RandomNormal(shape, device)
  
      /// Gets a tensor filled with random integer values from the given range for the given shape and configuration
      static member RandomInt(shape, low, high, ?dtype, ?device, ?backend) =
          let statics = BackendStatics.Get(?dtype=dtype, ?backend=backend)
          let device = defaultArg device Device.Default
          statics.RandomInt(shape|>Seq.toArray, low, high, device)
  
      /// <summary>
      ///   Gets a tensor filled with values drawn from the given .NET object.
      /// </summary>
      ///
      /// <remarks>
      ///  The value may be a scalar, an array, or an array of tupled objects.  If the <c>dtype</c> is not specified
      ///  then it is inferred from the .NET type of the object.
      /// </remarks>
      static member Create(values: obj, ?dtype, ?device, ?backend) =
          // We deliver consistent in-memory data to the backend - a dtype Int32 gets int32 etc.
          let data, shape, dtype =
  