Add getter/setter of C# OrtEnv log level (#13402)

### Description
* Add getter/setter to access and update C# OrtEnv log level
* Add C API about updating ort env with custom log level to support the
setter above (Following [pybind
implementation](952c99304a/onnxruntime/python/onnxruntime_pybind_state.cc (L923-L924)))
* Add test case to verify getter & setter


### Motivation and Context
* For C++/Python, the log level can be adjusted via OrtEnv, and this
feature is missing in C# binding
This commit is contained in:
yf711 2022-11-04 23:46:00 -05:00 committed by GitHub
parent 0296bc74c1
commit 8b9065a396
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 70 additions and 5 deletions

View file

@ -15,6 +15,7 @@ namespace Microsoft.ML.OnnxRuntime
// NOTE: The order of the APIs in this struct should match exactly that in
// OrtApi ort_api_1_to_<latest_version> (onnxruntime/core/session/onnxruntime_c_api.cc)
// If syncing your new C API, any other C APIs before yours also need to be synced here if haven't
[StructLayout(LayoutKind.Sequential)]
public struct OrtApi
{
@ -252,6 +253,13 @@ namespace Microsoft.ML.OnnxRuntime
public IntPtr ReleaseKernelInfo;
public IntPtr GetTrainingApi;
public IntPtr SessionOptionsAppendExecutionProvider_CANN;
public IntPtr CreateCANNProviderOptions;
public IntPtr UpdateCANNProviderOptions;
public IntPtr GetCANNProviderOptionsAsString;
public IntPtr ReleaseCANNProviderOptions;
public IntPtr MemoryInfoGetDeviceType;
public IntPtr UpdateEnvWithCustomLogLevel;
}
internal static class NativeMethods
@ -427,6 +435,7 @@ namespace Microsoft.ML.OnnxRuntime
= (DSessionOptionsAppendExecutionProvider)Marshal.GetDelegateForFunctionPointer(
api_.SessionOptionsAppendExecutionProvider,
typeof(DSessionOptionsAppendExecutionProvider));
OrtUpdateEnvWithCustomLogLevel = (DOrtUpdateEnvWithCustomLogLevel)Marshal.GetDelegateForFunctionPointer(api_.UpdateEnvWithCustomLogLevel, typeof(DOrtUpdateEnvWithCustomLogLevel));
}
internal class NativeLib
@ -466,9 +475,13 @@ namespace Microsoft.ML.OnnxRuntime
public delegate IntPtr /* OrtStatus* */DOrtDisableTelemetryEvents(IntPtr /*(OrtEnv*)*/ env);
public static DOrtDisableTelemetryEvents OrtDisableTelemetryEvents;
#endregion Runtime/Environment API
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
public delegate IntPtr /* OrtStatus* */DOrtUpdateEnvWithCustomLogLevel(IntPtr /*(OrtEnv*)*/ env, LogLevel custom_log_level);
public static DOrtUpdateEnvWithCustomLogLevel OrtUpdateEnvWithCustomLogLevel;
#region Provider Options API
#endregion Runtime/Environment API
#region Provider Options API
/// <summary>
/// Creates native OrtTensorRTProviderOptions instance

View file

@ -49,12 +49,13 @@ namespace Microsoft.ML.OnnxRuntime
public sealed class OrtEnv : SafeHandle
{
private static readonly Lazy<OrtEnv> _instance = new Lazy<OrtEnv>(()=> new OrtEnv());
private static LogLevel envLogLevel = LogLevel.Warning;
#region private methods
private OrtEnv() //Problem: it is not possible to pass any option for a Singleton
: base(IntPtr.Zero, true)
{
NativeApiStatus.VerifySuccess(NativeMethods.OrtCreateEnv(LogLevel.Warning, @"CSharpOnnxRuntime", out handle));
NativeApiStatus.VerifySuccess(NativeMethods.OrtCreateEnv(envLogLevel, @"CSharpOnnxRuntime", out handle));
try
{
NativeApiStatus.VerifySuccess(NativeMethods.OrtSetLanguageProjection(handle, OrtLanguageProjection.ORT_PROJECTION_CSHARP));
@ -150,6 +151,21 @@ namespace Microsoft.ML.OnnxRuntime
return availableProviders;
}
/// <summary>
/// Get/Set log level property of OrtEnv instance
/// </summary>
/// <returns>env log level</returns>
public LogLevel EnvLogLevel
{
get { return envLogLevel; }
set
{
NativeApiStatus.VerifySuccess(NativeMethods.OrtUpdateEnvWithCustomLogLevel(Handle, value));
envLogLevel = value;
}
}
#endregion
#region SafeHandle

View file

@ -221,6 +221,14 @@ namespace Microsoft.ML.OnnxRuntime.Tests
#endif
}
[Fact(DisplayName = "TestUpdatingEnvWithCustomLogLevel")]
public void TestUpdatingEnvWithCustomLogLevel()
{
var ortEnvInstance = OrtEnv.Instance();
ortEnvInstance.EnvLogLevel = LogLevel.Verbose;
Assert.Equal(LogLevel.Verbose, ortEnvInstance.EnvLogLevel);
}
[Fact(DisplayName = "CanCreateAndDisposeSessionWithModel")]
public void CanCreateAndDisposeSessionWithModel()
{

View file

@ -3589,6 +3589,14 @@ struct OrtApi {
*/
void(ORT_API_CALL* MemoryInfoGetDeviceType)(_In_ const OrtMemoryInfo* ptr, _Out_ OrtMemoryInfoDeviceType* out);
/* \brief Update the OrtEnv instance with custom log severity level
*
* \param[in] ort_env The OrtEnv instance being used
* \param[in] log_severity_level The log severity level.
*
* \since Version 1.14.
*/
ORT_API2_STATUS(UpdateEnvWithCustomLogLevel, _In_ OrtEnv* ort_env, OrtLoggingLevel log_severity_level);
#ifdef __cplusplus
OrtApi(const OrtApi&)=delete; // Prevent users from accidentally copying the API structure, it should always be passed as a pointer

View file

@ -366,7 +366,9 @@ struct Env : detail::Base<OrtEnv> {
Env& EnableTelemetryEvents(); ///< Wraps OrtApi::EnableTelemetryEvents
Env& DisableTelemetryEvents(); ///< Wraps OrtApi::DisableTelemetryEvents
Env& UpdateEnvWithCustomLogLevel(OrtLoggingLevel log_severity_level); ///< Wraps OrtApi::UpdateEnvWithCustomLogLevel
Env& CreateAndRegisterAllocator(const OrtMemoryInfo* mem_info, const OrtArenaCfg* arena_cfg); ///< Wraps OrtApi::CreateAndRegisterAllocator
};

View file

@ -415,6 +415,11 @@ inline Env& Env::DisableTelemetryEvents() {
return *this;
}
inline Env& Env::UpdateEnvWithCustomLogLevel(OrtLoggingLevel log_severity_level) {
ThrowOnError(GetApi().UpdateEnvWithCustomLogLevel(p_, log_severity_level));
return *this;
}
inline Env& Env::CreateAndRegisterAllocator(const OrtMemoryInfo* mem_info, const OrtArenaCfg* arena_cfg) {
ThrowOnError(GetApi().CreateAndRegisterAllocator(p_, mem_info, arena_cfg));
return *this;

View file

@ -169,6 +169,16 @@ ORT_API_STATUS_IMPL(OrtApis::DisableTelemetryEvents, _In_ const OrtEnv* ort_env)
API_IMPL_END
}
ORT_API_STATUS_IMPL(OrtApis::UpdateEnvWithCustomLogLevel, _In_ OrtEnv* ort_env,
OrtLoggingLevel log_severity_level) {
API_IMPL_BEGIN
LoggingManager* default_logging_manager = ort_env->GetLoggingManager();
int severity_level = static_cast<int>(log_severity_level);
default_logging_manager->SetDefaultLoggerSeverity(static_cast<logging::Severity>(severity_level));
return nullptr;
API_IMPL_END
}
ORT_STATUS_PTR CreateTensorImpl(MLDataType ml_type, const int64_t* shape, size_t shape_len,
_Inout_ OrtAllocator* allocator, OrtValue& value) {
TensorShape tensor_shape(shape, shape_len);
@ -2594,7 +2604,9 @@ static constexpr OrtApi ort_api_1_to_12 = {
// End of Version 13 - DO NOT MODIFY ABOVE (see above text for more information)
// Start of Version 14 API in progress, safe to modify/rename/rearrange until we ship
&OrtApis::MemoryInfoGetDeviceType};
&OrtApis::MemoryInfoGetDeviceType,
&OrtApis::UpdateEnvWithCustomLogLevel,
};

View file

@ -403,4 +403,5 @@ ORT_API(void, ReleaseCANNProviderOptions, _Frees_ptr_opt_ OrtCANNProviderOptions
ORT_API(void, MemoryInfoGetDeviceType, _In_ const OrtMemoryInfo* ptr, _Out_ OrtMemoryInfoDeviceType* out);
ORT_API_STATUS_IMPL(UpdateEnvWithCustomLogLevel, _In_ OrtEnv* ort_env, OrtLoggingLevel log_severity_level);
} // namespace OrtApis