From 8a66ad79a6c401eee4853776a7b37d6ff3919059 Mon Sep 17 00:00:00 2001 From: Sheil Kumar Date: Wed, 12 Aug 2020 12:45:19 -0700 Subject: [PATCH] Add Experimental WinRT API IDL as placeholder for adding new winrt features (#4736) * Add experimental winrt api idl with dummy type to satisfy the build * remove experimental from the api_lib target * make experimental api available on windows builds also * remove /y /d * revert some pathing changes * remove experimental api call from tests * revert cppwinrt cmake changes * switch to stdapi Co-authored-by: Sheil Kumar --- cmake/winml.cmake | 97 +++++++++++++++++++ cmake/winml_cppwinrt.cmake | 5 +- cmake/winml_unittests.cmake | 4 +- ...rosoft.AI.MachineLearning.Experimental.idl | 33 +++++++ winml/dll/module.cpp | 34 ++++++- winml/lib/Api.Experimental/Dummy.cpp | 12 +++ winml/lib/Api.Experimental/Dummy.h | 22 +++++ winml/lib/Api.Experimental/pch/pch.h | 16 +++ winml/lib/Common/inc/NamespaceAliases.h | 8 ++ 9 files changed, 227 insertions(+), 4 deletions(-) create mode 100644 winml/api/Microsoft.AI.MachineLearning.Experimental.idl create mode 100644 winml/lib/Api.Experimental/Dummy.cpp create mode 100644 winml/lib/Api.Experimental/Dummy.h create mode 100644 winml/lib/Api.Experimental/pch/pch.h diff --git a/cmake/winml.cmake b/cmake/winml.cmake index 66d12b3be5..83c1f3031d 100644 --- a/cmake/winml.cmake +++ b/cmake/winml.cmake @@ -20,6 +20,7 @@ set(winml_api_root ${REPO_ROOT}/winml/api) set(winml_dll_dir ${REPO_ROOT}/winml/dll) set(winml_lib_dir ${REPO_ROOT}/winml/lib) set(winml_lib_api_dir ${REPO_ROOT}/winml/lib/api) +set(winml_lib_api_experimental_dir ${REPO_ROOT}/winml/lib/api.experimental) set(winml_lib_api_image_dir ${REPO_ROOT}/winml/lib/api.image) set(winml_lib_api_ort_dir ${REPO_ROOT}/winml/lib/api.ort) set(winml_lib_common_dir ${REPO_ROOT}/winml/lib/common) @@ -28,6 +29,7 @@ set(winml_lib_telemetry_dir ${REPO_ROOT}/winml/lib/telemetry) set(winml_is_inbox OFF) if (onnxruntime_WINML_NAMESPACE_OVERRIDE) set(output_name "${onnxruntime_WINML_NAMESPACE_OVERRIDE}.AI.MachineLearning") + set(experimental_output_name "${onnxruntime_WINML_NAMESPACE_OVERRIDE}.AI.MachineLearning.Experimental") set(idl_native_output_name "${onnxruntime_WINML_NAMESPACE_OVERRIDE}.AI.MachineLearning.Native") set(idl_native_internal_output_name "${onnxruntime_WINML_NAMESPACE_OVERRIDE}.AI.MachineLearning.Native.Internal") @@ -41,6 +43,7 @@ if (onnxruntime_WINML_NAMESPACE_OVERRIDE) set(winml_api_use_ns_prefix false) else() set(output_name "Microsoft.AI.MachineLearning") + set(experimental_output_name "Microsoft.AI.MachineLearning.Experimental") set(idl_native_output_name "Microsoft.AI.MachineLearning.Native") set(idl_native_internal_output_name "Microsoft.AI.MachineLearning.Native.Internal") set(winml_midl_defines "/DROOT_NS=Microsoft") @@ -62,6 +65,7 @@ convert_forward_slashes_to_back(${exclusions} CPPWINRT_COMPONENT_EXCLUSION_LIST) # # For native idl files there are no casing restrictions. get_filename_component(winrt_idl "${winml_api_root}/Windows.AI.MachineLearning.idl" ABSOLUTE) +get_filename_component(winrt_experimental_idl "${winml_api_root}/Microsoft.AI.MachineLearning.Experimental.idl" ABSOLUTE) get_filename_component(idl_native "${winml_api_root}/windows.ai.machineLearning.native.idl" ABSOLUTE) get_filename_component(idl_native_internal "${winml_api_root}/windows.ai.machineLearning.native.internal.idl" ABSOLUTE) @@ -86,6 +90,19 @@ target_cppwinrt(winml_api ${winml_api_use_ns_prefix} # set ns_prefix ) +# generate winml.experimental headers from idl +target_cppwinrt(winml_api_experimental + ${winrt_experimental_idl} # winml winrt idl to compile + ${experimental_output_name} # outputs name + ${winml_lib_api_dir} # location for cppwinrt generated component sources + ${sdk_folder} # location of sdk folder + ${sdk_version} # sdk version + ${target_folder} # the folder this target will be placed under + ${winml_midl_defines} # the midl compiler defines + ${winml_api_use_ns_prefix} # set ns_prefix +) + + target_midl(winml_api_native ${idl_native} # winml native idl to compile ${idl_native_output_name} # outputs name @@ -431,6 +448,7 @@ target_precompiled_header(winml_lib_api pch.h) # Includes target_include_directories(winml_lib_api PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/winml_api) # windows machine learning generated component headers target_include_directories(winml_lib_api PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/winml_api/comp_generated) # windows machine learning generated component headers +target_include_directories(winml_lib_api PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/winml_api_experimental/comp_generated) # windows machine learning generated component headers target_include_directories(winml_lib_api PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/winml/sdk/cppwinrt/include) # sdk cppwinrt headers target_include_directories(winml_lib_api PRIVATE ${winml_lib_api_dir}) @@ -475,6 +493,82 @@ if (onnxruntime_USE_DML) target_add_dml(winml_lib_api) endif(onnxruntime_USE_DML) + +########################### +# Add winml_lib_api_experimental_dir +########################### + +# Add static library that will be archived/linked for both static/dynamic library +add_library(winml_lib_api_experimental STATIC + ${winml_lib_api_experimental_dir}/Dummy.cpp + ${winml_lib_api_experimental_dir}/Dummy.h +) + +# Compiler options +target_compile_features(winml_lib_api_experimental PRIVATE cxx_std_17) +target_compile_options(winml_lib_api_experimental PRIVATE /GR- /await /bigobj /wd4238) + +# Compiler flags +target_compile_definitions(winml_lib_api_experimental PRIVATE WINML_ROOT_NS=${winml_root_ns}) +target_compile_definitions(winml_lib_api_experimental PRIVATE ONNX_NAMESPACE=onnx) +target_compile_definitions(winml_lib_api_experimental PRIVATE ONNX_ML) +target_compile_definitions(winml_lib_api_experimental PRIVATE LOTUS_LOG_THRESHOLD=2) +target_compile_definitions(winml_lib_api_experimental PRIVATE LOTUS_ENABLE_STDERR_LOGGING) +target_compile_definitions(winml_lib_api_experimental PRIVATE PLATFORM_WINDOWS) +target_compile_definitions(winml_lib_api_experimental PRIVATE _SCL_SECURE_NO_WARNINGS) # remove warnings about unchecked iterators + +# Specify the usage of a precompiled header +target_precompiled_header(winml_lib_api_experimental pch.h) + +# Includes +target_include_directories(winml_lib_api_experimental PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/winml_api) # windows machine learning generated component headers +target_include_directories(winml_lib_api_experimental PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/winml_api/comp_generated) # windows machine learning generated component headers +target_include_directories(winml_lib_api_experimental PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/winml_api_experimental/comp_generated) # windows machine learning generated component headers +target_include_directories(winml_lib_api_experimental PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/winml/sdk/cppwinrt/include) # sdk cppwinrt headers + +target_include_directories(winml_lib_api_experimental PRIVATE ${winml_lib_api_dir}) +target_include_directories(winml_lib_api_experimental PRIVATE ${winml_lib_api_dir}/pch) +target_include_directories(winml_lib_api_experimental PRIVATE ${winml_adapter_dir}) +target_include_directories(winml_lib_api_experimental PRIVATE ${winml_lib_api_image_dir}/inc) +target_include_directories(winml_lib_api_experimental PRIVATE ${winml_lib_api_ort_dir}/inc) +target_include_directories(winml_lib_api_experimental PRIVATE ${winml_lib_telemetry_dir}/inc) +target_include_directories(winml_lib_api_experimental PRIVATE ${winml_lib_common_dir}/inc) + +target_include_directories(winml_lib_api_experimental PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) +target_include_directories(winml_lib_api_experimental PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/external/date/include) +target_include_directories(winml_lib_api_experimental PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/external/gsl/include) +target_include_directories(winml_lib_api_experimental PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/external/onnx) + +target_include_directories(winml_lib_api_experimental PRIVATE ${ONNXRUNTIME_INCLUDE_DIR}) +target_include_directories(winml_lib_api_experimental PRIVATE ${ONNXRUNTIME_INCLUDE_DIR}/core/graph) +target_include_directories(winml_lib_api_experimental PRIVATE ${ONNXRUNTIME_ROOT}) +target_include_directories(winml_lib_api_experimental PRIVATE ${ONNXRUNTIME_ROOT}/core/graph) +target_include_directories(winml_lib_api_experimental PRIVATE ${REPO_ROOT}/cmake/external/eigen) +target_include_directories(winml_lib_api_experimental PRIVATE ${REPO_ROOT}/cmake/external/onnx) +target_include_directories(winml_lib_api_experimental PRIVATE ${REPO_ROOT}/cmake/external/protobuf/src) +target_include_directories(winml_lib_api_experimental PRIVATE ${REPO_ROOT}/cmake/external/gsl/include) +target_include_directories(winml_lib_api_experimental PRIVATE ${REPO_ROOT}/cmake/external/SafeInt) + +# Properties +set_target_properties(winml_lib_api_experimental + PROPERTIES + FOLDER + ${target_folder}) + +# Add deps +add_dependencies(winml_lib_api_experimental onnx) +add_dependencies(winml_lib_api_experimental winml_sdk_cppwinrt) +add_dependencies(winml_lib_api_experimental winml_api) +add_dependencies(winml_lib_api_experimental winml_api_native) +add_dependencies(winml_lib_api_experimental winml_api_native_internal) +add_dependencies(winml_lib_api_experimental winml_api_experimental) + +# Link libraries +target_link_libraries(winml_lib_api_experimental PRIVATE wil winml_lib_telemetry) +if (onnxruntime_USE_DML) + target_add_dml(winml_lib_api_experimental) +endif(onnxruntime_USE_DML) + ########################### # Add winml_lib_common ########################### @@ -573,11 +667,13 @@ target_precompiled_header(winml_dll pch.h) # Includes target_include_directories(winml_dll PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/winml_api) # windows machine learning generated component headers target_include_directories(winml_dll PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/winml_api/comp_generated) # windows machine learning generated component headers +target_include_directories(winml_dll PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/winml_api_experimental/comp_generated) # windows machine learning generated component headers target_include_directories(winml_dll PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/winml/sdk/cppwinrt/include) # sdk cppwinrt headers target_include_directories(winml_dll PRIVATE ${winml_dll_dir}) target_include_directories(winml_dll PRIVATE ${winml_lib_api_dir}) target_include_directories(winml_dll PRIVATE ${winml_lib_api_dir}/impl) +target_include_directories(winml_dll PRIVATE ${winml_lib_api_experimental_dir}) target_include_directories(winml_dll PRIVATE ${winml_lib_api_ort_dir}/inc) target_include_directories(winml_dll PRIVATE ${winml_adapter_dir}) target_include_directories(winml_dll PRIVATE ${winml_lib_api_image_dir}/inc) @@ -628,6 +724,7 @@ add_dependencies(winml_dll winml_api_native_internal) target_link_libraries(winml_dll PRIVATE re2) target_link_libraries(winml_dll PRIVATE wil) target_link_libraries(winml_dll PRIVATE winml_lib_api) +target_link_libraries(winml_dll PRIVATE winml_lib_api_experimental) target_link_libraries(winml_dll PRIVATE winml_lib_image) target_link_libraries(winml_dll PRIVATE winml_lib_ort) target_link_libraries(winml_dll PRIVATE winml_lib_telemetry) diff --git a/cmake/winml_cppwinrt.cmake b/cmake/winml_cppwinrt.cmake index acde0406c7..4940d02f0a 100644 --- a/cmake/winml_cppwinrt.cmake +++ b/cmake/winml_cppwinrt.cmake @@ -107,13 +107,14 @@ function(target_cppwinrt # Get directory get_filename_component(idl_source_directory ${file} DIRECTORY) + convert_forward_slashes_to_back(${CMAKE_CURRENT_BINARY_DIR} cmake_current_binary_dir_back_slash) + set(target_outputs ${CMAKE_CURRENT_BINARY_DIR}/${target_name}) convert_forward_slashes_to_back(${target_outputs}/comp output_dir_back_slash) convert_forward_slashes_to_back(${target_outputs}/temp temp_dir_back_slash) convert_forward_slashes_to_back(${target_outputs}/comp_generated generated_dir_back_slash) convert_forward_slashes_to_back(${generated_dir_back_slash}/module.g.cpp module_g_cpp_back_slash) convert_forward_slashes_to_back(${generated_dir_back_slash}/module.g.excl.cpp module_g_ecxl_cpp_back_slash) - if (set_ns_prefix) set(ns_prefix "/ns_prefix") else() @@ -140,10 +141,10 @@ function(target_cppwinrt /metadata_dir ${sdk_metadata_directory} /W1 /char signed /nomidl /nologo /winrt /no_settings_comment /no_def_idir /target "NT60" + /I ${idl_source_directory} /I ${um_sdk_directory} /I ${shared_sdk_directory} /I ${winrt_sdk_directory} - /I ${idl_source_directory} /winmd ${winmd_filename} ${ns_prefix} /h ${header_filename} diff --git a/cmake/winml_unittests.cmake b/cmake/winml_unittests.cmake index 9f7b160c40..1ad800ebe6 100644 --- a/cmake/winml_unittests.cmake +++ b/cmake/winml_unittests.cmake @@ -15,7 +15,9 @@ set(WINML_TEST_INC_DIR ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}/winml_api ${CMAKE_CURRENT_BINARY_DIR}/winml_api/comp_generated - ${CMAKE_CURRENT_BINARY_DIR}/winml/sdk/cppwinrt/include) + ${CMAKE_CURRENT_BINARY_DIR}/winml/sdk/cppwinrt/include + ${CMAKE_CURRENT_BINARY_DIR}/winml_api_experimental/comp_generated +) function(set_winml_target_properties target) set_target_properties(${target} PROPERTIES diff --git a/winml/api/Microsoft.AI.MachineLearning.Experimental.idl b/winml/api/Microsoft.AI.MachineLearning.Experimental.idl new file mode 100644 index 0000000000..4d38e8ea19 --- /dev/null +++ b/winml/api/Microsoft.AI.MachineLearning.Experimental.idl @@ -0,0 +1,33 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +import "Windows.Foundation.idl"; +import "dualapipartitionattribute.idl"; +import "Windows.AI.MachineLearning.idl"; + +#include + +#ifdef BUILD_INBOX +#define ROOT_NS Windows +#define INBOX_ONLY(x) x +#define OTB_ONLY(x) +#else +#define INBOX_ONLY(x) +#define OTB_ONLY(x) x +#endif + +#ifndef ROOT_NS +#define ROOT_NS Microsoft +#endif + +namespace ROOT_NS.AI.MachineLearning.Experimental { + + [threading(both)] + [marshaling_behavior(agile)] + [dualapipartition(1)] + runtimeclass Dummy { + Dummy(); + + void Test(); + } +} // namespace Microsoft.AI.MachineLearning.Experimental \ No newline at end of file diff --git a/winml/dll/module.cpp b/winml/dll/module.cpp index 804182ca53..ac98e56007 100644 --- a/winml/dll/module.cpp +++ b/winml/dll/module.cpp @@ -7,6 +7,10 @@ #include "LearningModelDevice.h" #include "OnnxruntimeProvider.h" +#include "Dummy.h" + +#define STRINGIFY(x) #x +#define XSTRINGIFY(x) STRINGIFY(x) using namespace winmlp; @@ -85,6 +89,34 @@ STDAPI DllCanUnloadNow() { return S_FALSE; } +STDAPI DllGetExperimentalActivationFactory(void* classId, void** factory) noexcept { + try { + *factory = nullptr; + uint32_t length{}; + wchar_t const* const buffer = WINRT_WindowsGetStringRawBuffer(classId, &length); + std::wstring_view const name{buffer, length}; + + 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 dummy_class; + dummy_class << XSTRINGIFY(WINML_ROOT_NS) << ".AI.MachineLearning.Experimental.Dummy"; + if (requal(name, dummy_class.str())) { + *factory = winrt::detach_abi(winrt::make()); + return 0; + } + + return winrt::hresult_class_not_available(name).to_abi(); + } catch (...) { + return winrt::to_hresult(); + } +} + STDAPI DllGetActivationFactory(HSTRING classId, void** factory) { - return WINRT_GetActivationFactory(classId, factory); + auto ret = WINRT_GetActivationFactory(classId, factory); + if (ret != 0) + return DllGetExperimentalActivationFactory(classId, factory); + + return 0; } \ No newline at end of file diff --git a/winml/lib/Api.Experimental/Dummy.cpp b/winml/lib/Api.Experimental/Dummy.cpp new file mode 100644 index 0000000000..ee57f04cf5 --- /dev/null +++ b/winml/lib/Api.Experimental/Dummy.cpp @@ -0,0 +1,12 @@ +#include "pch.h" +#include "Dummy.h" + +namespace WINML_EXPERIMENTALP { + +void Dummy::Test() +{ + throw hresult_not_implemented(); +} + +} // namespace WINML_EXPERIMENTALP + diff --git a/winml/lib/Api.Experimental/Dummy.h b/winml/lib/Api.Experimental/Dummy.h new file mode 100644 index 0000000000..f72b8362da --- /dev/null +++ b/winml/lib/Api.Experimental/Dummy.h @@ -0,0 +1,22 @@ +#pragma once + +#include "Dummy.g.h" + +namespace WINML_EXPERIMENTALP { + +struct Dummy : DummyT +{ + Dummy() = default; + + void Test(); +}; + +} + +namespace WINML_EXPERIMENTAL::factory_implementation { + +struct Dummy : DummyT +{ +}; + +} diff --git a/winml/lib/Api.Experimental/pch/pch.h b/winml/lib/Api.Experimental/pch/pch.h new file mode 100644 index 0000000000..d5d2f48c76 --- /dev/null +++ b/winml/lib/Api.Experimental/pch/pch.h @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#pragma once + +#pragma warning(push) +#pragma warning(disable : 26495) +#pragma warning(disable : 6011) + +#pragma warning(disable : 26451) +#pragma warning(disable : 6387) + +#include "cppwinrt_onnx.h" +#include "dx.h" + +#pragma warning(pop) \ No newline at end of file diff --git a/winml/lib/Common/inc/NamespaceAliases.h b/winml/lib/Common/inc/NamespaceAliases.h index 13926ac49c..4d93b1ce03 100644 --- a/winml/lib/Common/inc/NamespaceAliases.h +++ b/winml/lib/Common/inc/NamespaceAliases.h @@ -35,6 +35,14 @@ namespace winml = WINML; namespace WINMLP {} namespace winmlp = WINMLP; +#define WINML_EXPERIMENTAL winrt::WINML_ROOT_NS::AI::MachineLearning::Experimental +namespace WINML_EXPERIMENTAL {} +namespace winml_experimental = WINML_EXPERIMENTAL; + +#define WINML_EXPERIMENTALP winrt::WINML_ROOT_NS::AI::MachineLearning::Experimental::implementation +namespace WINML_EXPERIMENTALP {} +namespace winml_experimentalp = WINML_EXPERIMENTALP; + namespace _winml::Adapter {} namespace winmla = ::_winml::Adapter;