// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. using System; using System.Text; using System.Runtime.InteropServices; namespace Microsoft.ML.OnnxRuntime { /// /// Various providers of ONNX operators /// public enum ExecutionProvider { Cpu, MklDnn, Cuda //TODO: add more providers gradually }; /// /// Holds the options for creating an InferenceSession /// public class SessionOptions:IDisposable { public IntPtr _nativePtr; protected static readonly Lazy _default = new Lazy(MakeSessionOptionWithCpuProvider); private static string[] cudaDelayLoadedLibs = { "cublas64_100.dll", "cudnn64_7.dll" }; /// /// Constructs an empty SessionOptions /// public SessionOptions() { _nativePtr = NativeMethods.OrtCreateSessionOptions(); } /// /// Default instance /// public static SessionOptions Default { get { return _default.Value; } } private static SessionOptions MakeSessionOptionWithCpuProvider() { SessionOptions options = new SessionOptions(); NativeMethods.OrtSessionOptionsAppendExecutionProvider_CPU(options._nativePtr, 1); return options; } /// /// A helper method to constuct a SessionOptions object for CUDA execution /// /// A SessionsOptions() object configured for execution on deviceId=0 public static SessionOptions MakeSessionOptionWithCudaProvider() { return MakeSessionOptionWithCudaProvider(0); } /// /// A helper method to constuct a SessionOptions object for CUDA execution /// /// /// A SessionsOptions() object configured for execution on deviceId public static SessionOptions MakeSessionOptionWithCudaProvider(int deviceId=0) { CheckCudaExecutionProviderDLLs(); SessionOptions options = new SessionOptions(); NativeMethods.OrtSessionOptionsAppendExecutionProvider_CUDA(options._nativePtr, deviceId); NativeMethods.OrtSessionOptionsAppendExecutionProvider_CPU(options._nativePtr, 1); return options; } // Declared, but called only if OS = Windows. [DllImport("kernel32.dll")] private static extern IntPtr LoadLibrary(string dllToLoad); [DllImport("kernel32.dll")] static extern uint GetSystemDirectory([Out] StringBuilder lpBuffer, uint uSize); private static bool CheckCudaExecutionProviderDLLs() { if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { foreach (var dll in cudaDelayLoadedLibs) { IntPtr handle = LoadLibrary(dll); if (handle != IntPtr.Zero) continue; var sysdir = new StringBuilder(String.Empty, 2048); GetSystemDirectory(sysdir, (uint)sysdir.Capacity); throw new OnnxRuntimeException( ErrorCode.NoSuchFile, $"kernel32.LoadLibrary():'{dll}' not found. CUDA 10.0 is required for GPU execution. " + $". Verify it is available in the system directory={sysdir}. Else copy it to the output folder." ); } } return true; } #region destructors disposers ~SessionOptions() { Dispose(false); } public void Dispose() { GC.SuppressFinalize(this); Dispose(true); } protected virtual void Dispose(bool disposing) { if (disposing) { // cleanup managed resources } NativeMethods.OrtReleaseSessionOptions(_nativePtr); } #endregion } }