onnxruntime/winml/dll/module.cpp
Sheil Kumar 87cb6fd495
Add LearningModelBuilder to WinML Experimental Namespace along with various Audio operators (#6623)
* model building

* fix build

* winml adapter model building api

* model building

* make build

* make build again

* add model building with audio op

* inplace and inorder fft

* add ifft

* works!

* cleanup

* add comments

* switch to iterative rather than recursive and use parallelization

* batched parallelization

* fft->dft

* cleanup

* window functions

* add melweightmatrix op

* updates to make spectrogram test work

* push latest

* add onesided

* cleanup

* Clean up building apis and fix mel

* cleanup

* cleanup

* naive stft

* fix test output

* middle c complete

* 3 tones

* cleanup

* signal def new line

* Add save functionality

* Perf improvements, 10x improvement

* cleanup

* use bitreverse lookup table for performance

* implement constant initializers for tensors

* small changes

* add matmul tests

* merge issues

* support add attribute

* add tests for double data type windowfunctions and minor cleanup

* stft onesided/and not tests

* cleanup

* cleanup

* clean up

* cleanup

* remove threading attribute

* forward declare orttypeinfo

* warnings

* fwd declare

* fix warnings

* 1 more warning

* remove saving to e drive...

* cleanup and fix stft test

* add opset picker

* small additions

* add onnxruntime tests

* add signed/unsigned

* fix warning

* fix warning

* finish onnxruntime tests

* make windows namespace build succeed

* add experimental flag

* add experimental api into nuget package

* add experimental api build flag and add to windows ai nuget package

* turn experimental for tests

* add minimum opset version to new experimental domain

* api cleanup

* disable ms experimental ops test when --ms_experimental is not enabled

* add macro behind flag

* remove unused x

* pr feedback

Co-authored-by: Sheil Kumar <sheilk@microsoft.com>
2021-02-12 14:17:10 -08:00

136 lines
4.6 KiB
C++

// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#include "pch.h"
#include <windows.h>
#include <Hstring.h>
#include "LearningModelDevice.h"
#include "OnnxruntimeProvider.h"
#ifndef BUILD_INBOX
#include "LearningModelBuilder.h"
#include "LearningModelOperator.h"
#include "LearningModelSessionOptionsExperimental.h"
#include "LearningModelSessionExperimental.h"
#define STRINGIFY(x) #x
#define XSTRINGIFY(x) STRINGIFY(x)
#endif
using namespace winmlp;
extern "C" BOOL WINAPI DllMain(_In_ HINSTANCE hInstance, DWORD dwReason, _In_ void* lpvReserved) {
switch (dwReason) {
case DLL_PROCESS_ATTACH:
DisableThreadLibraryCalls(hInstance);
// Register the TraceLogging provider feeding telemetry. It's OK if this fails;
// trace logging calls just become no-ops.
telemetry_helper.Register();
break;
case DLL_PROCESS_DETACH:
telemetry_helper.LogWinMLShutDown();
// Unregister Trace Logging Provider feeding telemetry
telemetry_helper.UnRegister();
#ifdef NDEBUG
bool dynamicUnload = (lpvReserved == nullptr);
//
// The OS can reclaim memory more quickly and correctly during process shutdown.
// Continue to do this on debug builds due to leak detection tracing.
//
if (dynamicUnload)
#endif
{
LearningModelDevice::DllUnload();
}
break;
}
return true;
}
extern "C" HRESULT WINAPI MLCreateOperatorRegistry(_COM_Outptr_ IMLOperatorRegistry** registry) try {
winrt::com_ptr<_winml::IEngineFactory> engine_factory;
WINML_THROW_IF_FAILED(CreateOnnxruntimeEngineFactory(engine_factory.put()));
WINML_THROW_IF_FAILED(engine_factory->CreateCustomRegistry(registry));
return S_OK;
}
CATCH_RETURN();
__control_entrypoint(DllExport)
STDAPI DllCanUnloadNow() {
// This dll should not be freed by
// CoFreeUnusedLibraries since there can be outstanding COM object
// references to many objects (AbiCustomRegistry, IMLOperatorKernelContext,
// IMLOperatorTensor, etc) that are not reference counted in this path.
//
// In order to implement DllCanUnloadNow we would need to reference count
// all of the instances of non-WinRT COM objects that have been shared
// across the dll boundary or harden the boundary APIs to make sure to
// additional outstanding references are not cached by callers.
//
// Identifying and curating the complete list of IUnknown based COM objects
// that are shared out as a consequence of the MLCreateOperatorRegistry API
// will be a complex task to complete in RS5.
//
// As a temporary workaround we simply prevent the dll from unloading.
//
// There are no known code paths that rely on opportunistic dll unload.
return S_FALSE;
}
#ifndef BUILD_INBOX
STDAPI DllGetExperimentalActivationFactory(void* classId, void** factory) noexcept {
try {
*factory = nullptr;
std::wstring_view const name{*reinterpret_cast<winrt::hstring*>(&classId)};
auto requal = [](std::wstring_view const& left, std::wstring_view const& right) noexcept {
return std::equal(left.rbegin(), left.rend(), right.rbegin(), right.rend());
};
std::wostringstream learning_model_builder_class;
learning_model_builder_class << XSTRINGIFY(WINML_ROOT_NS) << ".AI.MachineLearning.Experimental.LearningModelBuilder";
if (requal(name, learning_model_builder_class.str())) {
*factory = winrt::detach_abi(winrt::make<WINML_EXPERIMENTAL::factory_implementation::LearningModelBuilder>());
return 0;
}
std::wostringstream learning_model_operator_class;
learning_model_operator_class << XSTRINGIFY(WINML_ROOT_NS) << ".AI.MachineLearning.Experimental.LearningModelOperator";
if (requal(name, learning_model_operator_class.str())) {
*factory = winrt::detach_abi(winrt::make<WINML_EXPERIMENTAL::factory_implementation::LearningModelOperator>());
return 0;
}
std::wostringstream learning_model_session_experimental_class;
learning_model_session_experimental_class << XSTRINGIFY(WINML_ROOT_NS) << ".AI.MachineLearning.Experimental.LearningModelSessionExperimental";
if (requal(name, learning_model_session_experimental_class.str())) {
*factory = winrt::detach_abi(winrt::make<WINML_EXPERIMENTAL::factory_implementation::LearningModelSessionExperimental>());
return 0;
}
return winrt::hresult_class_not_available(name).to_abi();
} catch (...) {
return winrt::to_hresult();
}
}
#endif
STDAPI DllGetActivationFactory(HSTRING classId, void** factory) {
auto ret = WINRT_GetActivationFactory(classId, factory);
#ifndef BUILD_INBOX
if (ret != 0) {
return DllGetExperimentalActivationFactory(classId, factory);
}
#endif
return ret;
}