onnxruntime/csharp/src/Microsoft.ML.OnnxRuntime/FixedBufferOnnxValue.cs
Yulong Wang 718068f020
update C# API to optimize inference latency (#3171)
* update C# API to optimize inference latency

* rename PinnedOnnxValue to fixedBufferOnnxValue and fix build break

* add more test cases

* add conditions on string tensors for pre-allocated outputs

* change to random inputs

* fix word spell

* resolve comments

* resolve comments

* remove FixedBufferOnnxValueTests.cs

* fix trivial typos in doc
2020-04-08 11:57:40 -07:00

85 lines
2.7 KiB
C#

using Microsoft.ML.OnnxRuntime.Tensors;
using System;
using System.Buffers;
using System.Diagnostics;
namespace Microsoft.ML.OnnxRuntime
{
/// <summary>
/// Represents an Onnx Value with its underlying buffer pinned
/// </summary>
public class FixedBufferOnnxValue : IDisposable
{
internal MemoryHandle PinnedMemory { get; private set; }
internal IntPtr Value { get; private set; }
internal OnnxValueType OnnxValueType { get; private set; }
internal TensorElementType ElementType { get; private set; }
private FixedBufferOnnxValue(MemoryHandle pinnedMemory, IntPtr onnxValue, OnnxValueType onnxValueType, TensorElementType elementType)
{
PinnedMemory = pinnedMemory;
Value = onnxValue;
OnnxValueType = onnxValueType;
ElementType = elementType;
}
/// <summary>
/// Creates a <see cref="FixedBufferOnnxValue"/> object from the tensor and pins its underlying buffer.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value"></param>
/// <returns></returns>
public static FixedBufferOnnxValue CreateFromTensor<T>(Tensor<T> value)
{
if (value is Tensor<string>)
{
throw new ArgumentException("Only numeric tensors can be used to create FixedBufferOnnxValue.", nameof(value));
}
NativeOnnxValueHelper.CreateNativeOnnxValue(value, out IntPtr onnxValue, out MemoryHandle pinnedMemoryHandle, out OnnxValueType onnxValueType, out TensorElementType elementType);
Debug.Assert(
onnxValueType == OnnxValueType.ONNX_TYPE_TENSOR && elementType != TensorElementType.String,
"the value should always be a numeric tensor");
return new FixedBufferOnnxValue(pinnedMemoryHandle, onnxValue, onnxValueType, elementType);
}
#region IDisposable Support
// standard dispose pattern to deal with both managed and native resources
private bool disposed = false;
protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
if (disposing)
{
((IDisposable)PinnedMemory).Dispose();
}
if (Value != IntPtr.Zero)
{
NativeMethods.OrtReleaseValue(Value);
Value = IntPtr.Zero;
}
disposed = true;
}
}
~FixedBufferOnnxValue()
{
Dispose(false);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
#endregion
}
}