using System; using System.Collections.Generic; namespace Unity.Barracuda { /// /// Interfaces for backend implementers /// see ModelBuilder.cs for detail on layers. /// public interface IOps : IOpsStatistics { /// /// Matrix multiplication o = `x` ⨯ `y` /// /// left Tensor /// transposed `x` flag /// right Tensor /// transposed `y` flag /// output Tensor Tensor MatMul(Tensor x, bool xTranspose, Tensor y, bool yTranspose);// @TODO: consider MatMulAdd instead /// /// Multidimensional Matrix multiplication o = `x` ⨯ `y` /// /// left Tensor /// rank of `x` /// right Tensor /// rank of `y` /// output Tensor Tensor MatMul(Tensor x, int rankX, Tensor y, int rankY); /// /// Dense layer (matrix multiplication) o = `x` ⨯ `w` + `b` /// /// x argument /// w argument /// bias argument /// fused activation type /// output Tensor Tensor Dense(Tensor x, Tensor w, Tensor b, Layer.FusedActivation fusedActivation); /// /// rank3 Dense layer (matrix multiplication) o = `x` ⨯ `w` + `b` /// O: N,_,W,C / X: N,_,W,C / W:N,_,_,C / B:N,_,_,_ /// /// x argument (rank3) /// w argument (rank2) /// bias argument (rank1) /// fused activation type /// output Tensor Tensor Dense3(Tensor x, Tensor w, Tensor b); /// /// 2D convolution /// /// input /// kernel /// bias /// stride /// padding /// fused activation type /// output Tensor Tensor Conv2D(Tensor x, Tensor k, Tensor b, int[] stride, int[] pad, Layer.FusedActivation fusedActivation); /// /// 3D convolution /// /// input /// kernel /// bias /// stride /// padding /// fused activation type /// output Tensor Tensor Conv3D(Tensor x, Tensor k, Tensor b, int[] stride, int[] pad, Layer.FusedActivation fusedActivation); /// /// Depthwise 2D convolution /// /// input /// kernel /// bias /// stride /// padding /// fused activation type /// output Tensor Tensor DepthwiseConv2D(Tensor x, Tensor k, Tensor b, int[] stride, int[] pad, Layer.FusedActivation fusedActivation); /// /// Transpose 2D convolution /// /// input /// kernel /// bias /// stride /// padding /// output adjustments /// fused activation type /// output Tensor Tensor Conv2DTrans(Tensor x, Tensor k, Tensor b, int[] stride, int[] pad, int[] outputAdjustment, Layer.FusedActivation fusedActivation); /// /// Upsample 2D /// /// input /// scale /// bilinear flag /// output Tensor Tensor Upsample2D(Tensor x, int[] scale, bool bilinear); /// /// Upsample 3D /// /// input /// scale /// trilinear flag /// output Tensor Tensor Upsample3D(Tensor x, int[] scale, bool trilinear); /// /// Resample 2D /// /// input /// size /// bilinear flag /// output Tensor Tensor Resample2D(Tensor x, int[] size, bool bilinear); /// /// Depth to space /// /// input /// scale /// mode /// output Tensor Tensor DepthToSpace(Tensor x, int[] scale, Layer.DepthToSpaceMode mode); /// /// Space to depth /// /// input /// scale /// output Tensor Tensor SpaceToDepth(Tensor x, int[] scale); /// /// 2D max pooling /// /// input /// pooling /// stride /// padding /// output Tensor Tensor MaxPool2D(Tensor x, int[] pool, int[] stride, int[] pad); /// /// 2D average pooling /// /// input /// pooling /// stride /// padding /// output Tensor Tensor AvgPool2D(Tensor x, int[] pool, int[] stride, int[] pad); /// /// 2D global max pooling /// /// input /// output Tensor Tensor GlobalMaxPool2D(Tensor x); // @TODO: consider, if it should be just a special case of MaxPool2D with {pool=X.width/height, stride=1} /// /// 2D global average pooling /// /// input /// output Tensor Tensor GlobalAvgPool2D(Tensor x); /// /// 2D global average variance pooling /// /// input /// output Tensor Tensor GlobalAvgVariancePool2D(Tensor x); /// /// 2D border padding /// /// input /// padding /// border value /// output Tensor Tensor Border2D(Tensor x, int[] pad, float borderValue); /// /// 3D border padding /// /// input /// padding /// border value /// output Tensor Tensor Border3D(Tensor x, int[] pad, float borderValue); /// /// Reflection padding /// /// input /// padding /// output Tensor Tensor Pad2DReflect(Tensor x, int[] pad); /// /// Symmetric padding /// /// input /// padding /// output Tensor Tensor Pad2DSymmetric(Tensor x, int[] pad); /// /// Edge padding /// /// input /// padding /// output Tensor Tensor Pad2DEdge(Tensor x, int[] pad); /// /// Scale bias o = s * x + b, element wise /// /// input /// scale /// bias /// output Tensor Tensor ScaleBias(Tensor x, Tensor s, Tensor b); /// /// Normalization /// /// input /// scale /// bias /// pooling /// axis /// threshold /// fused activation type /// output Tensor Tensor Normalization(Tensor x, Tensor s, Tensor b, int pool, int axis, float epsilon, Layer.FusedActivation fusedActivation); /// /// LRN (Local Response Normalization) /// /// input /// alpha /// beta /// bias /// size /// output Tensor Tensor LRN(Tensor x, float alpha, float beta, float bias, int size); /// /// Dropout /// /// input /// alpha /// output Tensor Tensor Dropout(Tensor x, float alpha); /// /// Normal random distribution /// /// shape /// mean /// scale /// seed /// output Tensor Tensor RandomNormal(TensorShape s, float mean, float scale, int seed); /// /// Uniform random distribution /// /// shape /// mean /// scale /// seed /// output Tensor Tensor RandomUniform(TensorShape s, float mean, float scale, int seed); /// /// Multinomial random distribution /// /// input /// count /// seed /// output Tensor Tensor Multinomial(Tensor x, int count, int seed); /// /// One hot /// /// input /// output depth /// on value /// off value /// input rank helper /// output Tensor Tensor OneHot(Tensor x, int depth, float onValue, float offValue, int inputRank=-1); /// /// RoiAlign /// /// input /// rois /// batch indices /// outputHeight /// outputWidth /// samplingRatio /// spatialScale /// output Tensor Tensor RoiAlign(Tensor x, Tensor rois, Tensor indices, int outputHeight, int outputWidth, int samplingRatio, float spatialScale); /// /// Top K indices /// /// input /// k /// axis /// largest flag /// sorted flag /// output Tensor Tensor TopKIndices(Tensor x, int k, int axis, bool largest, bool sorted); /// /// Top K values /// /// input /// indices /// axis /// output Tensor Tensor TopKValues(Tensor X, Tensor I, int axis); /// /// Indices for non zero values /// /// input /// output Tensor Tensor NonZero(Tensor X); /// /// ReLU /// /// input /// output Tensor Tensor Relu(Tensor x); /// /// Softmax /// /// input /// axis /// output Tensor Tensor Softmax(Tensor x, int axis=1); /// /// LogSoftmax /// /// input /// output Tensor Tensor LogSoftmax(Tensor x, int axis=1); /// /// Tanh /// /// input /// output Tensor Tensor Tanh(Tensor x); /// /// Softplus /// /// input /// output Tensor Tensor Softplus(Tensor x); /// /// Sigmoid /// /// input /// output Tensor Tensor Sigmoid(Tensor x); /// /// HardSigmoid /// /// input /// alpha /// alpha /// output Tensor Tensor HardSigmoid(Tensor x, float alpha, float beta); /// /// ELU /// /// input /// alpha /// output Tensor Tensor Elu(Tensor x, float alpha); /// /// ReLU capped to 6 /// /// input /// output Tensor Tensor Relu6(Tensor x); /// /// Leaky ReLU /// /// input /// alpha /// output Tensor Tensor LeakyRelu(Tensor x, float alpha); /// /// SELU /// /// input /// alpha /// gamma /// output Tensor Tensor Selu(Tensor x, float alpha, float gamma); /// /// PReLU /// /// input /// alpha /// output Tensor Tensor PRelu(Tensor x, Tensor alpha); /// /// Swish /// /// input /// output Tensor Tensor Swish(Tensor x); /// /// Abs /// /// input /// output Tensor Tensor Abs(Tensor x); /// /// Neg /// /// input /// output Tensor Tensor Neg(Tensor x); /// /// Ceil /// /// input /// output Tensor Tensor Ceil(Tensor x); /// /// Clip /// /// input /// min value /// max value /// output Tensor Tensor Clip(Tensor x, float min, float max); /// /// Floor /// /// input /// output Tensor Tensor Floor(Tensor x); /// /// Round to nearest integer. In case of halfs, round to nearest even integer /// /// input /// output Tensor Tensor Round(Tensor x); /// /// Reciprocal (1/x) /// /// input /// output Tensor Tensor Reciprocal(Tensor x); /// /// Power /// /// input /// alpha /// output Tensor Tensor Pow(Tensor x, float alpha); /// /// Exponent e^x /// /// input /// output Tensor Tensor Exp(Tensor x); /// /// Log /// /// input /// output Tensor Tensor Log(Tensor x); /// /// Sqrt /// /// input /// output Tensor Tensor Sqrt(Tensor x); /// /// Acos /// /// input /// output Tensor Tensor Acos(Tensor x); /// /// Acosh /// /// input /// output Tensor Tensor Acosh(Tensor x); /// /// Asin /// /// input /// output Tensor Tensor Asin(Tensor x); /// /// Asinh /// /// input /// output Tensor Tensor Asinh(Tensor x); /// /// Atan /// /// input /// output Tensor Tensor Atan(Tensor x); /// /// Atanh /// /// input /// output Tensor Tensor Atanh(Tensor x); /// /// Cos /// /// input /// output Tensor Tensor Cos(Tensor x); /// /// Cosh /// /// input /// output Tensor Tensor Cosh(Tensor x); /// /// Sin /// /// input /// output Tensor Tensor Sin(Tensor x); /// /// Sinh /// /// input /// output Tensor Tensor Sinh(Tensor x); /// /// Tan /// /// input /// output Tensor Tensor Tan(Tensor x); /// /// Erf /// /// input /// output Tensor Tensor Erf(Tensor x); /// /// Add `tensors` together /// /// input tensors /// output Tensor Tensor Add(Tensor[] tensors); /// /// Subtract tensors o = tensors[0] - tensors[1] - ... - tensors[N-1] /// /// input tensors /// output Tensor Tensor Sub(Tensor[] tensors); /// /// Multiply tensors together /// /// input tensors /// output Tensor Tensor Mul(Tensor[] tensors); /// /// Divide tensors o = tensors[0] / tensors[1] / ... / tensors[N-1] /// /// input tensors /// output Tensor Tensor Div(Tensor[] tensors); /// /// Raise tensors to the power o =tensors[0] ^ tensors[1] ^ ... ^ tensors[N-1] /// /// input tensors /// output Tensor Tensor Pow(Tensor[] tensors); /// /// Min /// /// input tensors /// output Tensor Tensor Min(Tensor[] tensors); /// /// Max /// /// input tensors /// output Tensor Tensor Max(Tensor[] tensors); /// /// Mean /// /// input tensors /// output Tensor Tensor Mean(Tensor[] tensors); /// /// Reduce with max /// /// input /// axis /// output Tensor Tensor ReduceMax(Tensor x, int axis); /// /// Reduce with mean /// /// input /// axis /// output Tensor Tensor ReduceMean(Tensor x, int axis); /// /// Reduce with min /// /// input /// axis /// output Tensor Tensor ReduceMin(Tensor x, int axis); /// /// Reduce with product /// /// input /// axis /// output Tensor Tensor ReduceProd(Tensor x, int axis); /// /// Reduce with sum /// /// input /// axis /// output Tensor Tensor ReduceSum(Tensor x, int axis); /// /// ArgMax /// /// input /// axis /// output Tensor Tensor ArgMax(Tensor x, int axis); /// /// ArgMax /// /// input /// axis /// output Tensor Tensor ArgMin(Tensor x, int axis); /// /// Greater /// /// left Tensor /// right Tensor /// Tensor with `true` where a > b Tensor Greater(Tensor a, Tensor b); /// /// Greater or equal /// /// left Tensor /// right Tensor /// Tensor with `true` where a >= b Tensor GreaterEqual(Tensor a, Tensor b); /// /// Less /// /// left Tensor /// right Tensor /// Tensor with `true` where a < b Tensor Less(Tensor a, Tensor b); /// /// Less or equal /// /// left Tensor /// right Tensor /// Tensor with `true` where a < b Tensor LessEqual(Tensor a, Tensor b); /// /// Equal /// /// left Tensor /// right Tensor /// Tensor with `true` where a == b Tensor Equal(Tensor a, Tensor b); /// /// Or /// /// left Tensor /// right Tensor /// Tensor with `true` where a || b Tensor LogicalOr(Tensor a, Tensor b); /// /// And /// /// left Tensor /// right Tensor /// Tensor with `true` where a && b Tensor LogicalAnd(Tensor a, Tensor b); /// /// Xor /// /// left Tensor /// right Tensor /// Tensor with `true` where a xor b Tensor LogicalXor(Tensor a, Tensor b); /// /// Not /// /// input /// Tensor with !x values Tensor LogicalNot(Tensor x); /// /// Where /// /// Tensor c /// Tensor a /// Tensor b /// Tensor with values `c` ? `a` : `b` Tensor Where(Tensor c, Tensor a, Tensor b); /// /// Sign /// /// input /// Tensor with 1 if x > 0 -1 if < 0 and 0 if == 0 values Tensor Sign(Tensor x); /// /// Flatten /// /// input /// output Tensor Tensor Flatten(Tensor x); /// /// Reshape /// /// input /// new shape /// output Tensor Tensor Reshape(Tensor x, TensorShape shape); /// /// Expand /// /// input /// new shape /// output Tensor Tensor Expand(Tensor x, TensorShape shape); /// /// Transpose matrix /// /// input /// output Tensor Tensor Transpose(Tensor x); /// /// Transpose according to permutations /// /// input /// new axis order /// output Tensor Tensor Transpose(Tensor x, int[] permutations); /// /// Concatenate `tensors` across `axis` /// /// input tensors /// axis /// output Tensor Tensor Concat(Tensor[] tensors, int axis); /// /// Strided slice /// /// input /// /// /// stride /// output Tensor Tensor StridedSlice(Tensor x, int[] starts4Dor8D, int[] ends4Dor8D, int[] strides4Dor8D); /// /// Tile /// /// input /// repetition counts /// output Tensor Tensor Tile(Tensor x, int[] repeats); /// /// Gather /// /// input tensors /// axis /// output Tensor Tensor Gather(Tensor[] tensors, int axis); /// /// ScatterND /// /// input tensor /// indices /// updates /// reduction mode /// output Tensor Tensor ScatterND(Tensor x, Tensor indices, Tensor updates, Layer.ScatterNDReductionMode reduction); /// /// Non max suppression tensors[0] - boxes, tensors[1] - scores /// /// /// max output boxes per class /// IOU (Intersection Over Union) threshold /// score threshold /// center point box /// output Tensor Tensor NonMaxSuppression(Tensor[] tensors, int maxOutputBoxesPerClass, float iouThreshold, float scoreThreshold, int centerPointBox); /// /// LSTM /// /// The input sequences packed into one 3-D tensor. /// W parameter weight matrix for input, output, forget, and cell gates - W[iofc] /// R recurrence weight matrix for input, output, forget, and cell gates - R[iofc] /// W bias vectors for input, output, forget, and cell gates - Wb[iofc] /// R bias vectors for input, output, forget, and cell gates - Rb[iofc] /// Initial value of the hidden /// Initial value of the cell /// [Y (concatenated intermediate values of the hidden), Y_h (final hidden), Y_c (final cell)] Tensor[] LSTM(Tensor X, Tensor[] W, Tensor[] R, Tensor[] Wb, Tensor[] Rb, Tensor hidden, Tensor cell); /// /// Shape of the `input` /// /// input /// axis /// output Tensor Tensor Shape(Tensor X, int axis = -1); /// /// Creates a constant of shape `input` /// /// input shape /// value /// Tensor DataType /// output Tensor Tensor ConstantOfShape(TensorShape X, DataType type, float value = 0.0f); /// /// Copy /// /// input /// output Tensor Tensor Copy(Tensor x); /// /// Prepares tensor for use /// /// input /// Tensor Tensor Prepare(Tensor x); /// /// Prepares tensor for use without uploading internal data to device /// /// input /// Tensor Tensor PrepareNoAlloc(Tensor x); /// /// Reset internal allocator /// /// keep cached memory flag void ResetAllocator(bool keepCachedMemory = true); /// /// Called after every layer execution. It allows IOps to run cleanup operations /// such as clearing temporary buffers only used in the scope of the last layer /// executed. /// void PostLayerCleanup(); /// /// Set model executions reporter /// model executions reporter /// void SetModelExecutionsReporter(IModelExecutionsReporter executionsReporter); /// /// Get model executions reporter /// /// model executions reporter IModelExecutionsReporter GetModelExecutionsReporter(); } /// /// Interfaces for model compiler /// internal interface IModelCompiler { /// /// Prepare model for execution, allocating required intermediate tensors /// /// model /// input shapes /// model variables void PrepareModel(Model model, IDictionary inputShapes, IVars vars); /// /// Prepare for layer execution /// /// layer /// inputs void PreExecuteLayer(Layer layer, Tensor[] inputs); } /// /// Interfaces for variables /// public interface IVars : IDisposable { /// /// Set input /// /// name /// input void SetInput(string name, Tensor x); /// /// Prepare storage /// /// model /// `IOps` to prepare tensors /// input shapes dictionary /// takeoverWeights flag /// expect activation data type void PrepareStorage(Model model, IOps optionalOpsToPrepareTensors = null, IDictionary optionalInputShapes = null, bool takeoverWeights = false, DataType dataType = DataType.Float); /// /// Gather layer inputs /// /// layer /// all input tensors Tensor[] GatherInputs(Layer forLayer); /// /// Prepare storage for layer /// /// layer void PrepareStorage(Layer forLayer); /// /// Dispose storage that can be deleted after layer /// /// layer void DisposeAfterLayer(Layer forLayer); /// /// Store `result` for layer /// /// layer /// Tensor to store void Store(Layer fromLayer, Tensor result); /// /// Peek output /// /// name /// Tensor Tensor PeekOutput(string name); /// /// Peek constants /// /// layer name /// Tensor array Tensor[] PeekConstants(string layerName); /// /// Get allocator /// /// current `ITensorAllocator` ITensorAllocator GetAllocator(); } /// /// High level model execution peak memory usage information /// public readonly struct MemoryPeakSummary { private readonly long PeakMemoryUsageGPU; private readonly long PeakMemoryUsageCPU; private readonly long PeakMemoryUsageGPUAndCPU; public MemoryPeakSummary(long peakMemoryUsageGPU, long peakMemoryUsageCPU, long peakMemoryUsageGPUAndCPU) { PeakMemoryUsageGPU = peakMemoryUsageGPU; PeakMemoryUsageCPU = peakMemoryUsageCPU; PeakMemoryUsageGPUAndCPU = peakMemoryUsageGPUAndCPU; } public override string ToString() { return $"GPU: {PeakMemoryUsageGPU:N0} / CPU: {PeakMemoryUsageCPU:N0} / GPU and CPU: {PeakMemoryUsageGPUAndCPU:N0}."; } } /// /// Interfaces for model execution reporter /// public interface IModelExecutionsReporter { #if ENABLE_BARRACUDA_STATS /// /// Mark the model execution as started /// void ModelExecutionStarted(); /// /// Mark the model execution as completed /// void ModelExecutionCompleted(); /// /// Mark a layer execution as started /// layer /// void LayerExecutionStarted(Layer layer); /// /// Mark a layer execution as completed /// void LayerExecutionCompleted(); /// /// Set a layer operation summary /// layer summary /// void SetLayerSummary(string message); /// /// Set a layer theoretical numbers of ALU and memory bandwidth /// number of theoretical ALU operations /// number of theoretical bandwidth in bytes /// void SetLayerALUAndMemStats(long alu, long bytes); /// /// Add a dispatch to current layer /// dispatch information /// void AddLayerDispatch(DispatchInfo dispatchInfo); /// /// Take a memory snapshot /// IVars containing memory information /// context of the snapshot /// optional layer of the snapshot /// void TakeMemorySnapshot(IOps ops, IVars vars, string context, Layer layer=null); /// /// Return a string representation of the executions tracked so far /// as well as a quick summary of peak memory usage. /// if true report will be formatted as a spreadSheet. /// string GenerateStringReport(out MemoryPeakSummary memoryPeakSummary, bool spreadSheetFormat); #endif //ENABLE_BARRACUDA_STATS } public interface IUniqueResource { #if ENABLE_BARRACUDA_STATS /// /// Returns a unique id for identification. /// int uniqueId { get; } #endif //ENABLE_BARRACUDA_STATS } public interface ITensorDataStatistics : IUniqueResource { /// /// Returns the maximum number of element this tensorData can contain. /// int maxCapacity { get; } /// /// Returns the type of the elements this tensorData can contain. /// DataType dataType { get; } #if ENABLE_BARRACUDA_STATS /// /// Returns true if this tensor data is attached to any tensor. /// bool inUse { get; } /// /// Returns true if this tensor data is reserved as GPU memory. /// bool isGPUMem { get; } #endif //ENABLE_BARRACUDA_STATS } #if ENABLE_BARRACUDA_STATS public struct TempMemoryStatistics : IUniqueResource { public TempMemoryStatistics(int uniqueId, int size, bool isGPUMem, string name) { this.uniqueId = uniqueId; this.size = size; this.isGPUMem = isGPUMem; this.name = name; } /// public int uniqueId { get; } /// /// Returns the capacity in byte of this temp memory. /// public int size { get; } /// /// Returns true if this temporary memory is reserved as GPU memory. /// public bool isGPUMem { get; } /// /// Returns name associated with this temp memory. /// public string name { get; } } #endif //ENABLE_BARRACUDA_STATS public interface IOpsStatistics { #if ENABLE_BARRACUDA_STATS /// /// Enumerator for temporary memory statistics. /// IEnumerable GetTempMemoryStatistics(); #endif //ENABLE_BARRACUDA_STATS } public interface ITensorStatistics: IUniqueResource { /// /// Return this tensor name. /// string name { get; } /// /// Return the shape of this tensor. /// TensorShape shape { get; } /// /// Return the data type of this tensor. /// DataType dataType { get; } /// /// Return amount of internal tensor cache in bytes. /// int cacheBytes { get; } /// /// Return this tensor tensor data statistics if any or null. /// ITensorDataStatistics GetTensorDataStatistics(); } public interface IAllocatorStatistics: IUniqueResource { #if ENABLE_BARRACUDA_STATS /// /// Return this allocator name. /// string name { get; } /// /// Used bytes (sum of the parts of the tensorData used by tensors) /// long usedBytes { get; } /// /// Busy bytes (sum of used tensorData capacities in bytes) /// long busyBytes { get; } /// /// Free bytes (sum of un-used tensorData capacities in bytes) /// long freeBytes { get; } /// /// Total bytes (busy + free) /// long totalBytes { get; } /// /// Enumerator for tensors statistics. /// IEnumerable GetTensorsStatistics(); /// /// Enumerator for tensors data statistics. /// IEnumerable GetTensorDatasStatistics(); #endif //ENABLE_BARRACUDA_STATS } public interface IVarsStatistics { #if ENABLE_BARRACUDA_STATS /// /// Enumerator for allocators statistics. /// IEnumerable GetAllocatorsStatistics(); /// /// Enumerator for tensors statistics. /// IEnumerable GetTensorsStatistics(); #endif //ENABLE_BARRACUDA_STATS } /// /// Enum to describe life time of a given allocation /// public enum AllocScope { LayerOutput, InternalToLayer } /// /// Interfaces for tensor allocator /// public interface ITensorAllocator : IDisposable { /// /// Allocate /// /// shape /// tensor lifetime scope /// tensor data type /// allocated Tensor Tensor Alloc(TensorShape shape, AllocScope scope = AllocScope.LayerOutput, DataType dataType = DataType.Float); /// /// Allocate with existing `ITensorData` buffer /// /// shape /// buffer /// tensor lifetime scope /// allocated Tensor Tensor Alloc(TensorShape shape, ITensorData buffer, AllocScope scope = AllocScope.LayerOutput, DataType dataType = DataType.Float); /// /// Allows ITensorAllocator to run cleanup operations such as clearing /// temporary buffers only used in the scope of the last layer executed. /// void PostLayerCleanup(); // MoveToDevice() callback is called from the following Tensor methods: // UploadToDevice(), AttachToDevice() and DetachFromDevice() /// /// Move Tensor to device /// /// Tensor /// new buffer /// old buffer /// dispose detached buffer hint void MoveToDevice(Tensor x, ITensorData newBuffer, ITensorData oldBuffer, bool disposeDetachedBufferHint); // NOTE: Release() should be ready to handle edge-case situation when // externally created new Tensor instance is passed with // ITensorData (tensorOnDevice) that is already owned by the allocator /// /// Release Tensor /// /// Tensor /// called from tensor dispose flag void Release(Tensor x, bool calledFromTensorDispose); /// /// Waive ownership /// /// Tensor void WaiveOwnership(Tensor x); /// /// Reset allocator /// /// keep cached memory flag void Reset(bool keepCachedMemory); // end-of-frame } } // namespace Unity.Barracuda