Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions csharp/src/Microsoft.ML.OnnxRuntime/NativeMethods.cs
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,22 @@ public struct OrtApi
public IntPtr ModelMetadataGetGraphDescription;
}

#region ORT Provider options

[StructLayout(LayoutKind.Sequential)]
public struct OrtCUDAProviderOptions
{
public int device_id; // cuda device with id=0 as default device.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

int [](start = 15, length = 3)

I would want to verify that this is being marshalled correctly. In C# int is always 4 bytes. In the native code on Windows it is 4 bytes but on Linux it is 8 bytes. So it might work OK on windows but we need it work everywhere.

Copy link
Contributor

@snnn snnn Apr 14, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No. Even on Linux int is still 4 bytes. You were talking 'long' #Resolved

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are correct.


In reply to: 613471164 [](ancestors = 613471164)

Copy link
Member

@yuslepukhin yuslepukhin Apr 15, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We may have an issue here. The new C API was added without giving a though how this is going to interact with other languages even though the purpose of having C API is language binding. So you will need to verify the fact in the native debugger that the marshalling occurs correctly and make the test test.


In reply to: 613468046 [](ancestors = 613468046)

public OrtCudnnConvAlgoSearch cudnn_conv_algo_search; // cudnn conv algo search option
public UIntPtr gpu_mem_limit; // default cuda memory limitation to maximum finite value of size_t.
public int arena_extend_strategy; // default area extend strategy to KNextPowerOfTwo.
public int do_copy_in_default_stream; // Whether to do copies in the default stream or use separate streams.
public int has_user_compute_stream; // indicator of user specified CUDA compute stream.
public IntPtr user_compute_stream; // user specified CUDA compute stream.
}

#endregion

internal static class NativeMethods
{
private const string nativeLib = "onnxruntime";
Expand Down Expand Up @@ -256,6 +272,8 @@ static NativeMethods()
OrtRegisterCustomOpsLibrary = (DOrtRegisterCustomOpsLibrary)Marshal.GetDelegateForFunctionPointer(api_.RegisterCustomOpsLibrary, typeof(DOrtRegisterCustomOpsLibrary));
OrtAddSessionConfigEntry = (DOrtAddSessionConfigEntry)Marshal.GetDelegateForFunctionPointer(api_.AddSessionConfigEntry, typeof(DOrtAddSessionConfigEntry));
OrtAddInitializer = (DOrtAddInitializer)Marshal.GetDelegateForFunctionPointer(api_.AddInitializer, typeof(DOrtAddInitializer));
SessionOptionsAppendExecutionProvider_CUDA = (DSessionOptionsAppendExecutionProvider_CUDA)Marshal.GetDelegateForFunctionPointer(
api_.SessionOptionsAppendExecutionProvider_CUDA, typeof(DSessionOptionsAppendExecutionProvider_CUDA));

OrtCreateRunOptions = (DOrtCreateRunOptions)Marshal.GetDelegateForFunctionPointer(api_.CreateRunOptions, typeof(DOrtCreateRunOptions));
OrtReleaseRunOptions = (DOrtReleaseRunOptions)Marshal.GetDelegateForFunctionPointer(api_.ReleaseRunOptions, typeof(DOrtReleaseRunOptions));
Expand Down Expand Up @@ -561,6 +579,17 @@ IntPtr[] outputValues /* An array of output value pointers. Array must be alloca
[DllImport(nativeLib, CharSet = charSet)]
public static extern IntPtr /*(OrtStatus*)*/ OrtSessionOptionsAppendExecutionProvider_CUDA(IntPtr /*(OrtSessionOptions*) */ options, int device_id);

/// <summary>
/// Append a CUDA EP instance (configured based on given provider options) to the native OrtSessionOptions instance
/// </summary>
/// <param name="options">Native OrtSessionOptions instance</param>
/// <param name="cudaProviderOptions">Native OrtCUDAProviderOptions instance</param>
public delegate IntPtr /*(OrtStatus*)*/DSessionOptionsAppendExecutionProvider_CUDA(
IntPtr /*(OrtSessionOptions*)*/ options,
ref OrtCUDAProviderOptions cudaProviderOptions);

public static DSessionOptionsAppendExecutionProvider_CUDA SessionOptionsAppendExecutionProvider_CUDA;

[DllImport(nativeLib, CharSet = charSet)]
public static extern IntPtr /*(OrtStatus*)*/ OrtSessionOptionsAppendExecutionProvider_ROCM(IntPtr /*(OrtSessionOptions*) */ options, int device_id);

Expand Down
55 changes: 55 additions & 0 deletions csharp/src/Microsoft.ML.OnnxRuntime/ProviderOptions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;

namespace Microsoft.ML.OnnxRuntime
{
/// <summary>
/// Search Algorithm for Cudnn Conv.
/// </summary>
public enum OrtCudnnConvAlgoSearch
{
EXHAUSTIVE, //!< expensive exhaustive benchmarking using cudnnFindConvolutionForwardAlgorithmEx
HEURISTIC, //!< lightweight heuristic based search using cudnnGetConvolutionForwardAlgorithm_v7
DEFAULT, //!< default algorithm using CUDNN_CONVOLUTION_FWD_ALGO_IMPLICIT_PRECOMP_GEMM
}

/// <summary>
/// Holds provider options configuration for creating an InferenceSession.
/// </summary>
public static class ProviderOptions
{
#region Public Methods

/// <summary>
/// Get CUDA provider options with default setting.
/// </summary>
/// <returns> CUDA provider options instance. </returns>
public static OrtCUDAProviderOptions GetDefaultCUDAProviderOptions()
{
OrtCUDAProviderOptions cuda_options;
cuda_options.device_id = 0;
cuda_options.cudnn_conv_algo_search = OrtCudnnConvAlgoSearch.EXHAUSTIVE;
if (IntPtr.Size == 8)
{
cuda_options.gpu_mem_limit = (UIntPtr)UInt64.MaxValue;
}
else
{
cuda_options.gpu_mem_limit = (UIntPtr)UInt32.MaxValue;
}
cuda_options.arena_extend_strategy = 0;
cuda_options.do_copy_in_default_stream = 1;
cuda_options.has_user_compute_stream = 0;
cuda_options.user_compute_stream = IntPtr.Zero;

return cuda_options;
}

#endregion
}
}
28 changes: 28 additions & 0 deletions csharp/src/Microsoft.ML.OnnxRuntime/SessionOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,22 @@ public static SessionOptions MakeSessionOptionWithCudaProvider(int deviceId = 0)
return options;
}

/// <summary>
/// A helper method to construct a SessionOptions object for CUDA execution.
/// Use only if CUDA is installed and you have the onnxruntime package specific to this Execution Provider.
/// </summary>
/// <param name="cuda_options">CUDA EP provider options to configure the CUDA EP instance</param>>
/// <returns>A SessionsOptions() object configured for execution with CUDA provider options.</returns>
public static SessionOptions MakeSessionOptionWithCudaProvider(OrtCUDAProviderOptions cuda_options)
{
CheckCudaExecutionProviderDLLs();

SessionOptions options = new SessionOptions();
NativeApiStatus.VerifySuccess(NativeMethods.SessionOptionsAppendExecutionProvider_CUDA(options.Handle, ref cuda_options));
NativeApiStatus.VerifySuccess(NativeMethods.OrtSessionOptionsAppendExecutionProvider_CPU(options.Handle, 1));
return options;
}

/// <summary>
/// A helper method to construct a SessionOptions object for Nuphar execution.
/// Use only if you have the onnxruntime package specific to this Execution Provider.
Expand Down Expand Up @@ -148,6 +164,16 @@ public void AppendExecutionProvider_CUDA(int deviceId)
NativeApiStatus.VerifySuccess(NativeMethods.OrtSessionOptionsAppendExecutionProvider_CUDA(handle, deviceId));
}

/// <summary>
/// Append a CUDA EP instance (based on specified configuration) to the SessionOptions instance
/// Use only if you have the onnxruntime package specific to this Execution Provider.
/// </summary>
/// <param name="cuda_options">CUDA EP provider options to configure the CUDA EP instance</param>
public void AppendExecutionProvider_CUDA(OrtCUDAProviderOptions cuda_options)
{
NativeApiStatus.VerifySuccess(NativeMethods.SessionOptionsAppendExecutionProvider_CUDA(handle, ref cuda_options));
}

/// <summary>
/// Use only if you have the onnxruntime package specific to this Execution Provider.
/// </summary>
Expand Down Expand Up @@ -325,6 +351,7 @@ public void AddFreeDimensionOverrideByName(string dimName, long dimValue)
NativeApiStatus.VerifySuccess(NativeMethods.OrtAddFreeDimensionOverrideByName(handle, pinnedDimName.Pointer, dimValue));
}
}

#endregion

internal IntPtr Handle
Expand Down Expand Up @@ -626,6 +653,7 @@ private static bool CheckCudaExecutionProviderDLLs()


#endregion

#region SafeHandle
/// <summary>
/// Overrides SafeHandle.ReleaseHandle() to properly dispose of
Expand Down
12 changes: 12 additions & 0 deletions csharp/test/Microsoft.ML.OnnxRuntime.Tests/InferenceTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,18 @@ public void CanCreateAndDisposeSessionWithModelPath()
}
}
}
#if USE_CUDA
[Fact]
private void TestCUDAProviderOptions()
{

OrtCUDAProviderOptions cuda_options = ProviderOptions.GetDefaultCUDAProviderOptions();
using (var sessionOptions = new SessionOptions())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This does not test anything. Let's find a way to verify that this indeed happened

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BTW, currently I forgot to pass USE_CUDA in.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can see "Microsoft.ML.OnnxRuntime.Tests.InferenceTest.TestGpu" was skipped in your test run.

{
sessionOptions.AppendExecutionProvider_CUDA(cuda_options);
}
}
#endif

[Theory]
[InlineData(GraphOptimizationLevel.ORT_DISABLE_ALL, true)]
Expand Down