diff --git a/cmake/winml.cmake b/cmake/winml.cmake index 76f5c40d91..330ccdcb58 100644 --- a/cmake/winml.cmake +++ b/cmake/winml.cmake @@ -367,6 +367,7 @@ target_include_directories(winml_lib_image PRIVATE ${ONNXRUNTIME_INCLUDE_DIR}) target_include_directories(winml_lib_image PRIVATE ${REPO_ROOT}/cmake/external/gsl/include) target_include_directories(winml_lib_image PRIVATE ${REPO_ROOT}/cmake/external/onnx) target_include_directories(winml_lib_image PRIVATE ${REPO_ROOT}/cmake/external/protobuf/src) +target_include_directories(winml_lib_image PRIVATE ${ONNXRUNTIME_INCLUDE_DIR}/core/platform/windows) # Properties set_target_properties(winml_lib_image diff --git a/winml/lib/Api.Image/EventTimer.h b/winml/lib/Api.Image/EventTimer.h new file mode 100644 index 0000000000..4bd0995c96 --- /dev/null +++ b/winml/lib/Api.Image/EventTimer.h @@ -0,0 +1,25 @@ +#include "pch.h" + +class EventTimer +{ +public: + bool Start() + { + auto now = std::chrono::high_resolution_clock::now(); + if (!_started || + std::chrono::duration_cast(now - _startTime).count() > _kDurationBetweenSendingEvents) + { + _started = true; + _startTime = std::chrono::high_resolution_clock::now(); + return true; + } + + return false; + } + +private: + bool _started = false; + std::chrono::steady_clock::time_point _startTime; + constexpr static long long _kDurationBetweenSendingEvents = 1000 * 50; // duration in (us). send an Event every 50 ms; +}; + diff --git a/winml/lib/Api.Image/TensorToVideoFrameConverter.cpp b/winml/lib/Api.Image/TensorToVideoFrameConverter.cpp index fe691ea009..2812053157 100644 --- a/winml/lib/Api.Image/TensorToVideoFrameConverter.cpp +++ b/winml/lib/Api.Image/TensorToVideoFrameConverter.cpp @@ -5,6 +5,7 @@ #include // winmeta needed for TraceLoggingKeyword #include +#include #include #include @@ -14,6 +15,7 @@ #include "inc/ImageConversionHelpers.h" #include "LearningModelDevice.h" +#include "EventTimer.h" using namespace Microsoft::WRL; using namespace Windows::Graphics::DirectX::Direct3D11; @@ -30,7 +32,9 @@ class GPUTensorToDX12TextureTelemetryEvent { TraceLoggingOpcode(EVENT_TRACE_TYPE_START), TraceLoggingHexInt32(tensorDesc.channelType, "Type"), TraceLoggingInt64(tensorDesc.sizes[2], "Height"), - TraceLoggingInt64(tensorDesc.sizes[3], "Width")); + TraceLoggingInt64(tensorDesc.sizes[3], "Width"), + TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage), + TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES)); } ~GPUTensorToDX12TextureTelemetryEvent() { TraceLoggingWrite( @@ -38,7 +42,35 @@ class GPUTensorToDX12TextureTelemetryEvent { "GPUTensorToDX12Texture", TraceLoggingKeyword(WINML_PROVIDER_KEYWORD_DEFAULT), TraceLoggingOpcode(EVENT_TRACE_TYPE_STOP), - TraceLoggingHexInt32(S_OK, "HRESULT")); + TraceLoggingHexInt32(S_OK, "HRESULT"), + TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage), + TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES)); + } +}; + +class ConvertGPUTensorToSoftwareBitmapTelemetryEvent { + public: + ConvertGPUTensorToSoftwareBitmapTelemetryEvent(const ImageTensorDescription& tensorDesc) { + TraceLoggingWrite( + winml_trace_logging_provider, + "ConvertGPUTensorToSoftwareBitmap", + TraceLoggingKeyword(WINML_PROVIDER_KEYWORD_DEFAULT), + TraceLoggingOpcode(EVENT_TRACE_TYPE_START), + TraceLoggingHexInt32(tensorDesc.channelType, "Type"), + TraceLoggingInt64(tensorDesc.sizes[2], "Height"), + TraceLoggingInt64(tensorDesc.sizes[3], "Width"), + TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage), + TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES)); + } + ~ConvertGPUTensorToSoftwareBitmapTelemetryEvent() { + TraceLoggingWrite( + winml_trace_logging_provider, + "ConvertGPUTensorToSoftwareBitmap", + TraceLoggingKeyword(WINML_PROVIDER_KEYWORD_DEFAULT), + TraceLoggingOpcode(EVENT_TRACE_TYPE_STOP), + TraceLoggingHexInt32(S_OK, "HRESULT"), + TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage), + TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES)); } }; @@ -52,7 +84,9 @@ class ConvertCPUTensorToVideoFrameWithSoftwareBitmapTelemetryEvent { TraceLoggingOpcode(EVENT_TRACE_TYPE_START), TraceLoggingHexInt32(tensorDesc.channelType, "Type"), TraceLoggingInt64(tensorDesc.sizes[2], "Height"), - TraceLoggingInt64(tensorDesc.sizes[3], "Width")); + TraceLoggingInt64(tensorDesc.sizes[3], "Width"), + TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage), + TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES)); } ~ConvertCPUTensorToVideoFrameWithSoftwareBitmapTelemetryEvent() { TraceLoggingWrite( @@ -60,7 +94,9 @@ class ConvertCPUTensorToVideoFrameWithSoftwareBitmapTelemetryEvent { "ConvertCPUTensorToVideoFrameWithSoftwareBitmap", TraceLoggingKeyword(WINML_PROVIDER_KEYWORD_DEFAULT), TraceLoggingOpcode(EVENT_TRACE_TYPE_STOP), - TraceLoggingHexInt32(S_OK, "HRESULT")); + TraceLoggingHexInt32(S_OK, "HRESULT"), + TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage), + TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES)); } }; @@ -345,7 +381,12 @@ void TensorToVideoFrameConverter::ConvertGPUTensorToDX12Texture( CD3DX12_RECT scissorRect(0, 0, (LONG)outputDesc.Width, outputDesc.Height); ComPtr spDx12Device = device_cache.GetD3D12Device(); - GPUTensorToDX12TextureTelemetryEvent telemetrylogger(tensorDesc); + // we're inside a lock from the caller of this function, so it's ok to use this static + static EventTimer eventTimer; + std::optional telemetryLogger; + if (eventTimer.Start()) { + telemetryLogger.emplace(tensorDesc); + } WINML_THROW_HR_IF_FALSE_MSG( E_INVALIDARG, @@ -490,7 +531,12 @@ void TensorToVideoFrameConverter::ConvertGPUTensorToSoftwareBitmap( assert(pInputTensor != nullptr); assert(softwareBitmap != nullptr); - GPUTensorToDX12TextureTelemetryEvent telemetrylogger(tensorDesc); + // we're inside a lock from the caller of this function, so it's ok to use this static + static EventTimer eventTimer; + std::optional telemetryLogger; + if (eventTimer.Start()) { + telemetryLogger.emplace(tensorDesc); + } uint32_t tensorElementSize = tensorDesc.dataType == kImageTensorDataTypeFloat32 ? 4 : 2; uint32_t singleVideoFramebufferSize = static_cast(tensorDesc.sizes[1] * tensorDesc.sizes[2] * tensorDesc.sizes[3] * tensorElementSize); @@ -569,7 +615,13 @@ void TensorToVideoFrameConverter::ConvertCPUTensorToSoftwareBitmap( _In_ void* pCPUTensor, _In_ const ImageTensorDescription& tensorDesc, _Inout_ wgi::SoftwareBitmap& softwareBitmap) { - ConvertCPUTensorToVideoFrameWithSoftwareBitmapTelemetryEvent telemetrylogger(tensorDesc); + + // we're inside a lock from the caller of this function, so it's ok to use this static + static EventTimer eventTimer; + std::optional telemetryLogger; + if (eventTimer.Start()) { + telemetryLogger.emplace(tensorDesc); + } auto height = softwareBitmap.PixelHeight(); auto width = softwareBitmap.PixelWidth(); diff --git a/winml/lib/Api.Image/VideoFrameToTensorConverter.cpp b/winml/lib/Api.Image/VideoFrameToTensorConverter.cpp index 385d1ffcde..1eb82d6a97 100644 --- a/winml/lib/Api.Image/VideoFrameToTensorConverter.cpp +++ b/winml/lib/Api.Image/VideoFrameToTensorConverter.cpp @@ -5,6 +5,7 @@ #include // winmeta needed for TraceLoggingKeyword #include +#include #include #include @@ -13,6 +14,7 @@ #include "inc/D3DDeviceCache.h" #include "LearningModelDevice.h" +#include "EventTimer.h" using namespace Microsoft::WRL; using namespace Windows::Graphics::DirectX::Direct3D11; @@ -29,7 +31,9 @@ class DX12TextureToGPUTensorTelemetryEvent { TraceLoggingOpcode(EVENT_TRACE_TYPE_START), TraceLoggingHexInt32(tensorDesc.channelType, "Type"), TraceLoggingInt64(tensorDesc.sizes[2], "Height"), - TraceLoggingInt64(tensorDesc.sizes[3], "Width")); + TraceLoggingInt64(tensorDesc.sizes[3], "Width"), + TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage), + TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES)); } ~DX12TextureToGPUTensorTelemetryEvent() { TraceLoggingWrite( @@ -37,7 +41,35 @@ class DX12TextureToGPUTensorTelemetryEvent { "DX12TextureToGPUTensor", TraceLoggingKeyword(WINML_PROVIDER_KEYWORD_DEFAULT), TraceLoggingOpcode(EVENT_TRACE_TYPE_STOP), - TraceLoggingHexInt32(S_OK, "HRESULT")); + TraceLoggingHexInt32(S_OK, "HRESULT"), + TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage), + TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES)); + } +}; + +class SoftwareBitmapToGPUTensorTelemetryEvent { + public: + SoftwareBitmapToGPUTensorTelemetryEvent(const ImageTensorDescription& tensorDesc) { + TraceLoggingWrite( + winml_trace_logging_provider, + "SoftwareBitmapToGPUTensor", + TraceLoggingKeyword(WINML_PROVIDER_KEYWORD_DEFAULT), + TraceLoggingOpcode(EVENT_TRACE_TYPE_START), + TraceLoggingHexInt32(tensorDesc.channelType, "Type"), + TraceLoggingInt64(tensorDesc.sizes[2], "Height"), + TraceLoggingInt64(tensorDesc.sizes[3], "Width"), + TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage), + TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES)); + } + ~SoftwareBitmapToGPUTensorTelemetryEvent() { + TraceLoggingWrite( + winml_trace_logging_provider, + "SoftwareBitmapToGPUTensor", + TraceLoggingKeyword(WINML_PROVIDER_KEYWORD_DEFAULT), + TraceLoggingOpcode(EVENT_TRACE_TYPE_STOP), + TraceLoggingHexInt32(S_OK, "HRESULT"), + TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage), + TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES)); } }; @@ -51,7 +83,9 @@ class ConvertVideoFrameWithSoftwareBitmapToCPUTensorTelemetryEvent { TraceLoggingOpcode(EVENT_TRACE_TYPE_START), TraceLoggingHexInt32(tensorDesc.channelType, "Type"), TraceLoggingInt64(tensorDesc.sizes[2], "Height"), - TraceLoggingInt64(tensorDesc.sizes[3], "Width")); + TraceLoggingInt64(tensorDesc.sizes[3], "Width"), + TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage), + TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES)); } ~ConvertVideoFrameWithSoftwareBitmapToCPUTensorTelemetryEvent() { TraceLoggingWrite( @@ -59,7 +93,9 @@ class ConvertVideoFrameWithSoftwareBitmapToCPUTensorTelemetryEvent { "ConvertVideoFrameWithSoftwareBitmapToCPUTensor", TraceLoggingKeyword(WINML_PROVIDER_KEYWORD_DEFAULT), TraceLoggingOpcode(EVENT_TRACE_TYPE_STOP), - TraceLoggingHexInt32(S_OK, "HRESULT")); + TraceLoggingHexInt32(S_OK, "HRESULT"), + TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage), + TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES)); } }; @@ -242,7 +278,12 @@ void VideoFrameToTensorConverter::ConvertDX12TextureToGPUTensor( D3D12_RESOURCE_DESC outputDesc = pOutputResource->GetDesc(); ComPtr spDx12Device = device_cache.GetD3D12Device(); - DX12TextureToGPUTensorTelemetryEvent telemetrylogger(tensorDesc); + // we're inside a lock from the caller of this function, so it's ok to use this static + static EventTimer eventTimer; + std::optional telemetryLogger; + if (eventTimer.Start()) { + telemetryLogger.emplace(tensorDesc); + } // Validate input description WINML_THROW_HR_IF_FALSE_MSG( @@ -406,7 +447,12 @@ void VideoFrameToTensorConverter::ConvertSoftwareBitmapToGPUTensor( assert(pOutputResource != nullptr); assert(videoFrame.SoftwareBitmap() != nullptr); - DX12TextureToGPUTensorTelemetryEvent telemetrylogger(tensorDesc); + // we're inside a lock from the caller of this function, so it's ok to use this static + static EventTimer eventTimer; + std::optional telemetryLogger; + if (eventTimer.Start()) { + telemetryLogger.emplace(tensorDesc); + } wgi::SoftwareBitmap convertedSoftwareBitmap = nullptr; wgi::BitmapBounds scaledBounds = inputBounds; @@ -515,7 +561,12 @@ void VideoFrameToTensorConverter::ConvertSoftwareBitmapToCPUTensor( _Inout_ void* pCPUTensor) { assert(softwareBitmap != nullptr); - ConvertVideoFrameWithSoftwareBitmapToCPUTensorTelemetryEvent telemetrylogger(tensorDesc); + // we're inside a lock from the caller of this function, so it's ok to use this static + static EventTimer eventTimer; + std::optional telemetryLogger; + if (eventTimer.Start()) { + telemetryLogger.emplace(tensorDesc); + } auto height = softwareBitmap.PixelHeight(); auto width = softwareBitmap.PixelWidth();