Skip to content

Commit

Permalink
[C# and Python APIs] Expose knobs to enable/disable platform telemetr…
Browse files Browse the repository at this point in the history
…y collection (microsoft#5481)
  • Loading branch information
hariharans29 authored Oct 21, 2020
1 parent df22611 commit 4291c57
Show file tree
Hide file tree
Showing 9 changed files with 163 additions and 25 deletions.
4 changes: 2 additions & 2 deletions csharp/src/Microsoft.ML.OnnxRuntime/InferenceSession.cs
Original file line number Diff line number Diff line change
Expand Up @@ -676,7 +676,7 @@ public ulong ProfilingStartTimeNs

private void Init(string modelPath, SessionOptions options)
{
var envHandle = OnnxRuntime.Handle;
var envHandle = OrtEnv.Handle;
var session = IntPtr.Zero;
NativeApiStatus.VerifySuccess(NativeMethods.OrtCreateSession(envHandle, NativeMethods.GetPlatformSerializedString(modelPath), options.Handle, out session));

Expand All @@ -685,7 +685,7 @@ private void Init(string modelPath, SessionOptions options)

private void Init(byte[] modelData, SessionOptions options)
{
var envHandle = OnnxRuntime.Handle;
var envHandle = OrtEnv.Handle;
var session = IntPtr.Zero;

NativeApiStatus.VerifySuccess(NativeMethods.OrtCreateSessionFromArray(envHandle, modelData, (UIntPtr)modelData.Length, options.Handle, out session));
Expand Down
9 changes: 9 additions & 0 deletions csharp/src/Microsoft.ML.OnnxRuntime/NativeMethods.cs
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,9 @@ static NativeMethods()

OrtCreateEnv = (DOrtCreateEnv)Marshal.GetDelegateForFunctionPointer(api_.CreateEnv, typeof(DOrtCreateEnv));
OrtReleaseEnv = (DOrtReleaseEnv)Marshal.GetDelegateForFunctionPointer(api_.ReleaseEnv, typeof(DOrtReleaseEnv));
OrtEnableTelemetryEvents = (DOrtEnableTelemetryEvents)Marshal.GetDelegateForFunctionPointer(api_.EnableTelemetryEvents, typeof(DOrtEnableTelemetryEvents));
OrtDisableTelemetryEvents = (DOrtDisableTelemetryEvents)Marshal.GetDelegateForFunctionPointer(api_.DisableTelemetryEvents, typeof(DOrtDisableTelemetryEvents));

OrtGetErrorCode = (DOrtGetErrorCode)Marshal.GetDelegateForFunctionPointer(api_.GetErrorCode, typeof(DOrtGetErrorCode));
OrtGetErrorMessage = (DOrtGetErrorMessage)Marshal.GetDelegateForFunctionPointer(api_.GetErrorMessage, typeof(DOrtGetErrorMessage));
OrtReleaseStatus = (DOrtReleaseStatus)Marshal.GetDelegateForFunctionPointer(api_.ReleaseStatus, typeof(DOrtReleaseStatus));
Expand Down Expand Up @@ -332,6 +335,12 @@ static NativeMethods()
public delegate void DOrtReleaseEnv(IntPtr /*(OrtEnv*)*/ env);
public static DOrtReleaseEnv OrtReleaseEnv;

public delegate IntPtr /* OrtStatus* */DOrtEnableTelemetryEvents(IntPtr /*(OrtEnv*)*/ env);
public static DOrtEnableTelemetryEvents OrtEnableTelemetryEvents;

public delegate IntPtr /* OrtStatus* */DOrtDisableTelemetryEvents(IntPtr /*(OrtEnv*)*/ env);
public static DOrtDisableTelemetryEvents OrtDisableTelemetryEvents;

#endregion Runtime/Environment API

#region Status API
Expand Down
77 changes: 57 additions & 20 deletions csharp/src/Microsoft.ML.OnnxRuntime/OnnxRuntime.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,41 +38,77 @@ public enum OrtLanguageProjection
}

/// <summary>
/// This class intializes the process-global ONNX runtime
/// C# API users do not need to access this, thus kept as internal
/// This class initializes the process-global ONNX Runtime environment instance (OrtEnv)
/// </summary>
internal sealed class OnnxRuntime : SafeHandle
public sealed class OrtEnv : SafeHandle
{
private static readonly Lazy<OnnxRuntime> _instance = new Lazy<OnnxRuntime>(()=> new OnnxRuntime());

internal static IntPtr Handle // May throw exception in every access, if the constructor have thrown an exception
private static readonly Lazy<OrtEnv> _instance = new Lazy<OrtEnv>(()=> new OrtEnv());

#region private methods
private OrtEnv() //Problem: it is not possible to pass any option for a Singleton
: base(IntPtr.Zero, true)
{
get
NativeApiStatus.VerifySuccess(NativeMethods.OrtCreateEnv(LogLevel.Warning, @"CSharpOnnxRuntime", out handle));
try
{
return _instance.Value.handle;
NativeApiStatus.VerifySuccess(NativeMethods.OrtSetLanguageProjection(handle, OrtLanguageProjection.ORT_PROJECTION_CSHARP));
}
catch (OnnxRuntimeException e)
{
ReleaseHandle();
throw e;
}
}
#endregion

public override bool IsInvalid
#region internal methods
/// <summary>
/// Returns a handle to the native `OrtEnv` instance held by the singleton C# `OrtEnv` instance
/// Exception caching: May throw an exception on every call, if the `OrtEnv` constructor threw an exception
/// during lazy initialization
/// </summary>
internal static IntPtr Handle
{
get
{
return (handle == IntPtr.Zero);
return _instance.Value.handle;
}
}
#endregion

#region public methods

private OnnxRuntime() //Problem: it is not possible to pass any option for a Singleton
:base(IntPtr.Zero, true)
/// <summary>
/// Returns an instance of OrtEnv
/// It returns the same instance on every call - `OrtEnv` is singleton
/// </summary>
public static OrtEnv Instance() { return _instance.Value; }

/// <summary>
/// Enable platform telemetry collection where applicable
/// (currently only official Windows ORT builds have telemetry collection capabilities)
/// </summary>
public void EnableTelemetryEvents()
{
NativeApiStatus.VerifySuccess(NativeMethods.OrtCreateEnv(LogLevel.Warning, @"CSharpOnnxRuntime", out handle));
try
{
NativeApiStatus.VerifySuccess(NativeMethods.OrtSetLanguageProjection(handle, OrtLanguageProjection.ORT_PROJECTION_CSHARP));
}
catch (OnnxRuntimeException e)
NativeApiStatus.VerifySuccess(NativeMethods.OrtEnableTelemetryEvents(Handle));
}

/// <summary>
/// Disable platform telemetry collection
/// </summary>
public void DisableTelemetryEvents()
{
NativeApiStatus.VerifySuccess(NativeMethods.OrtDisableTelemetryEvents(Handle));
}

#endregion

#region SafeHandle
public override bool IsInvalid
{
get
{
ReleaseHandle();
throw e;
return (handle == IntPtr.Zero);
}
}

Expand All @@ -82,5 +118,6 @@ protected override bool ReleaseHandle()
handle = IntPtr.Zero;
return true;
}
#endregion
}
}
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 @@ -164,6 +164,18 @@ public void TestRunOptions()
}
}

[Fact]
public void EnablingAndDisablingTelemetryEventCollection()
{
var ortEnvInstance = OrtEnv.Instance();
ortEnvInstance.DisableTelemetryEvents();

// no-op on non-Windows builds
// may be no-op on certain Windows builds based on build configuration

ortEnvInstance.EnableTelemetryEvents();
}

[Fact]
public void CanCreateAndDisposeSessionWithModelPath()
{
Expand Down
66 changes: 66 additions & 0 deletions docs/CSharp_API.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,10 +92,37 @@ var session = new InferenceSession("model.onnx", SessionOptions.MakeSessionOptio
```

## API Reference

### OrtEnv
```cs
class OrtEnv
```
Holds some methods which can be used to tune the ONNX Runtime's runime environment

#### Constructor
No public constructor available.

#### Methods
```cs
static OrtEnv Instance();
```
Returns an instance of the singlton class `OrtEnv`.

```cs
void EnableTelemetryEvents();
```
Enables platform-specific telemetry collection where applicable. Please see [Privacy](./Privacy.md) for more details.

```cs
void DisableTelemetryEvents();
```
Disables platform-specific telemetry collection. Please see [Privacy](./Privacy.md) for more details.

### InferenceSession
```cs
class InferenceSession: IDisposable
```

The runtime representation of an ONNX model

#### Constructor
Expand Down Expand Up @@ -239,5 +266,44 @@ class OnnxRuntimeException: Exception;

The type of Exception that is thrown in most of the error conditions related to Onnx Runtime.

### ModelMetadata
```cs
class ModelMetadata
```
Encapsulates some metadata about the ONNX model.

#### Constructor
No public constructor available.

The `ModelMetadata` instance for an ONNX model may be obtained by querying the `ModelMetadata` property of an `InferenceSession` instance.

#### Properties
```cs
string ProducerName;
```
Holds the producer name of the ONNX model.

```cs
string GraphName;
```
Holds the graph name of the ONNX model.

```cs
string Domain;
```
Holds the opset domain of the ONNX model.

```cs
string Description;
```
Holds the description of the ONNX model.

```cs
long Version;
```
Holds the version of the ONNX model.

```cs
Dictionary<string, string> CustomMetadataMap;
```
Holds a dictionary containing key-value pairs of custom metadata held by the ONNX model.
3 changes: 2 additions & 1 deletion docs/Privacy.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,5 @@ Currently telemetry is only implemented for Windows builds and is turned **ON**
The Windows provider uses the [TraceLogging](https://docs.microsoft.com/en-us/windows/win32/tracelogging/trace-logging-about) API for its implementation. This enables ONNX Runtime trace events to be collected by the operating system, and based on user consent, this data may be periodically sent to Microsoft servers following GDPR and privacy regulations for anonymity and data access controls.

Windows ML and onnxruntime C APIs allow Trace Logging to be turned on/off (see [API pages](../README.md#api-documentation) for details).
For information on how to enable and disable telemetry, see [C API: Telemetry](./C_API.md#telemetry).
For information on how to enable and disable telemetry, see [C API: Telemetry](./C_API.md#telemetry).
There are equivalent APIs in the C#, Python, and Java language bindings as well.
4 changes: 2 additions & 2 deletions onnxruntime/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
__author__ = "Microsoft"

from onnxruntime.capi._pybind_state import get_all_providers, get_available_providers, get_device, set_seed, \
RunOptions, SessionOptions, set_default_logger_severity, NodeArg, ModelMetadata, GraphOptimizationLevel, \
ExecutionMode, ExecutionOrder, OrtDevice, SessionIOBinding
RunOptions, SessionOptions, set_default_logger_severity, enable_telemetry_events, disable_telemetry_events, \
NodeArg, ModelMetadata, GraphOptimizationLevel, ExecutionMode, ExecutionOrder, OrtDevice, SessionIOBinding

try:
from onnxruntime.capi._pybind_state import set_cuda_mem_limit, set_cuda_device_id
Expand Down
6 changes: 6 additions & 0 deletions onnxruntime/python/onnxruntime_pybind_state.cc
Original file line number Diff line number Diff line change
Expand Up @@ -815,6 +815,12 @@ void addGlobalMethods(py::module& m, const Environment& env) {
m.def(
"get_available_providers", []() -> const std::vector<std::string>& { return GetAvailableProviders(); },
"Return list of available Execution Providers available in this installed version of Onnxruntime.");
m.def(
"enable_telemetry_events", []() -> void { platform_env.GetTelemetryProvider().EnableTelemetryEvents(); },
"Enables platform-specific telemetry collection where applicable.");
m.def(
"disable_telemetry_events", []() -> void { platform_env.GetTelemetryProvider().DisableTelemetryEvents(); },
"Disables platform-specific telemetry collection.");

#ifdef USE_NUPHAR
m.def("set_nuphar_settings", [](const std::string& str) {
Expand Down
7 changes: 7 additions & 0 deletions onnxruntime/test/python/onnxruntime_test_python.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,13 @@ def testGetProviders(self):
sess = onnxrt.InferenceSession(get_name("mul_1.onnx"))
self.assertTrue('CPUExecutionProvider' in sess.get_providers())

def testEnablingAndDisablingTelemetry(self):
onnxrt.disable_telemetry_events()

# no-op on non-Windows builds
# may be no-op on certain Windows builds based on build configuration
onnxrt.enable_telemetry_events()

def testSetProviders(self):
if 'CUDAExecutionProvider' in onnxrt.get_available_providers():
sess = onnxrt.InferenceSession(get_name("mul_1.onnx"))
Expand Down

0 comments on commit 4291c57

Please sign in to comment.