private static DisposableNamedOnnxValue DisposableNamedOnnxValueFromNativeMap <K, V>(string name, IntPtr nativeOnnxValueKeys, IntPtr nativeOnnxValueValues)
        {
            var nativeTensorWrapperValues = new NativeOnnxTensorMemory <V>(nativeOnnxValueValues);
            var denseTensorValues         = new DenseTensor <V>(nativeTensorWrapperValues.Memory, nativeTensorWrapperValues.Dimensions);

            if (typeof(K) == typeof(string))
            {
                var map = new Dictionary <string, V>();
                var nativeTensorWrapper = new NativeOnnxTensorMemory <string>(nativeOnnxValueKeys);
                var denseTensorKeys     = new DenseTensor <string>(nativeTensorWrapper.GetBytesAsStringMemory(), nativeTensorWrapper.Dimensions);
                for (var i = 0; i < denseTensorKeys.Length; i++)
                {
                    map.Add(denseTensorKeys.GetValue(i), denseTensorValues.GetValue(i));
                }
                // release native memory
                nativeTensorWrapperValues.Dispose();
                nativeTensorWrapper.Dispose();
                return(new DisposableNamedOnnxValue(string.Empty, map, OnnxValueType.ONNX_TYPE_MAP, TensorElementType.DataTypeMax, null));
            }
            else
            {
                var map = new Dictionary <K, V>();
                var nativeTensorWrapper = new NativeOnnxTensorMemory <K>(nativeOnnxValueKeys);
                var denseTensorKeys     = new DenseTensor <K>(nativeTensorWrapper.Memory, nativeTensorWrapper.Dimensions);
                for (var i = 0; i < denseTensorKeys.Length; i++)
                {
                    map.Add(denseTensorKeys.GetValue(i), denseTensorValues.GetValue(i));
                }
                // release native memory
                nativeTensorWrapperValues.Dispose();
                nativeTensorWrapper.Dispose();
                return(new DisposableNamedOnnxValue(string.Empty, map, OnnxValueType.ONNX_TYPE_MAP, TensorElementType.DataTypeMax, null));
            }
        }
 /// <summary>
 /// This method creates an instance of DisposableNamedOnnxValue that has possession of ortValueElement
 /// native memory Tensor and returns it to the caller. The original ortValueElement argument looses
 /// ownership of the native ortValueElement handle, however, the caller is still responsible for disposing them
 /// on exception. Disposing of OrtValue that has no ownership is a no-op and fine.
 /// </summary>
 /// <typeparam name="T">data type</typeparam>
 /// <param name="name">name of the output</param>
 /// <param name="ortValue">native tensor</param>
 /// <returns>DisposableNamedOnnxValue instance</returns>
 private static DisposableNamedOnnxValue DisposableNamedOnnxValueFromNativeTensor <T>(string name, OrtValue ortValue)
 {
     if (typeof(T) == typeof(string))
     {
         var nativeTensorWrapper = new NativeOnnxTensorMemory <string>(ortValue);
         try
         {
             var dt = new DenseTensor <string>(nativeTensorWrapper.GetBytesAsStringMemory(), nativeTensorWrapper.Dimensions);
             return(new DisposableNamedOnnxValue(name, dt, OnnxValueType.ONNX_TYPE_TENSOR, nativeTensorWrapper.ElementType, nativeTensorWrapper));
         } catch (Exception)
         {
             nativeTensorWrapper.Dispose();
             throw;
         }
     }
     else
     {
         NativeOnnxTensorMemory <T> nativeTensorWrapper = new NativeOnnxTensorMemory <T>(ortValue);
         try
         {
             DenseTensor <T> dt = new DenseTensor <T>(nativeTensorWrapper.Memory, nativeTensorWrapper.Dimensions);
             return(new DisposableNamedOnnxValue(name, dt, OnnxValueType.ONNX_TYPE_TENSOR, nativeTensorWrapper.ElementType, nativeTensorWrapper));
         }
         catch (Exception)
         {
             nativeTensorWrapper.Dispose();
             throw;
         }
     }
 }