From 147a508a51e5add87b39afa901ebd1c77fae0ad3 Mon Sep 17 00:00:00 2001 From: Ilya Lavrenov Date: Fri, 18 Sep 2020 17:13:27 +0300 Subject: [PATCH] fixes for UWP (#2255) * UWP fixes * Commented code for compilation with UWP * Current state: compiled for DESKTOP_APP * Fixes * Added toolchain * Enabled ONNX imported for Windows Store * Updated toolchain * Fixes * Disable ONNX in case of UWP * Fix for Windows Driver * Applied style check * Dynamic loading of GetDLLDirectory symbols * Clean-up in the toolchain * Updated mkldnn plugin cmake --- CMakeLists.txt | 2 +- cmake/dependencies.cmake | 26 ++--- cmake/features.cmake | 2 +- cmake/uwp.toolchain.cmake | 22 ++++ inference-engine/cmake/features_ie.cmake | 2 +- inference-engine/samples/CMakeLists.txt | 3 +- .../src/inference_engine/file_utils.cpp | 39 ++++--- .../os/win/win_shared_object_loader.cpp | 108 ++++++++++++++++-- .../src/mkldnn_plugin/CMakeLists.txt | 4 +- .../src/preprocessing/ie_preprocess_gapi.cpp | 3 +- .../modules/gapi/src/compiler/gcompiler.cpp | 2 +- ngraph/core/src/file_util.cpp | 8 +- ngraph/test/runtime/backend.cpp | 7 +- ngraph/test/runtime/backend_manager.cpp | 8 +- 14 files changed, 179 insertions(+), 57 deletions(-) create mode 100644 cmake/uwp.toolchain.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index dcfd8764116ad5..86f821394ac177 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -73,7 +73,7 @@ function(build_ngraph) ngraph_set(NGRAPH_UNIT_TEST_ENABLE FALSE) endif() - if(NOT ANDROID) + if(NOT (ANDROID OR WINDOWS_STORE)) ngraph_set(NGRAPH_ONNX_IMPORT_ENABLE TRUE) else() ngraph_set(NGRAPH_ONNX_IMPORT_ENABLE FALSE) diff --git a/cmake/dependencies.cmake b/cmake/dependencies.cmake index 2a5a74db6a85ec..6a44c8769e7c60 100644 --- a/cmake/dependencies.cmake +++ b/cmake/dependencies.cmake @@ -6,20 +6,20 @@ set_temp_directory(TEMP "${IE_MAIN_SOURCE_DIR}") include(dependency_solver) -if(CMAKE_CROSSCOMPILING) - if(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "amd64.*|x86_64.*|AMD64.*") - set(HOST_X86_64 ON) - endif() +if(CMAKE_CROSSCOMPILING AND NGRAPH_ONNX_IMPORT_ENABLE) + if(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "amd64.*|x86_64.*|AMD64.*") + set(HOST_X86_64 ON) + endif() - set(protoc_version "3.7.1") - if(CMAKE_HOST_SYSTEM_NAME MATCHES Linux) - RESOLVE_DEPENDENCY(SYSTEM_PROTOC_ROOT - ARCHIVE_LIN "protoc-${protoc_version}-linux-x86_64.tar.gz" - TARGET_PATH "${TEMP}/protoc-${protoc_version}-linux-x86_64") - debug_message(STATUS "host protoc-${protoc_version} root path = " ${SYSTEM_PROTOC_ROOT}) - else() - message(FATAL_ERROR "Unsupported host system (${CMAKE_HOST_SYSTEM_NAME}) and arch (${CMAKE_HOST_SYSTEM_PROCESSOR}) for cross-compilation") - endif() + set(protoc_version "3.7.1") + if(CMAKE_HOST_SYSTEM_NAME MATCHES Linux) + RESOLVE_DEPENDENCY(SYSTEM_PROTOC_ROOT + ARCHIVE_LIN "protoc-${protoc_version}-linux-x86_64.tar.gz" + TARGET_PATH "${TEMP}/protoc-${protoc_version}-linux-x86_64") + debug_message(STATUS "host protoc-${protoc_version} root path = " ${SYSTEM_PROTOC_ROOT}) + else() + message(FATAL_ERROR "Unsupported host system (${CMAKE_HOST_SYSTEM_NAME}) and arch (${CMAKE_HOST_SYSTEM_PROCESSOR}) for cross-compilation") + endif() reset_deps_cache(SYSTEM_PROTOC) diff --git a/cmake/features.cmake b/cmake/features.cmake index 38b69a7b135e05..d03b573aad9ea8 100644 --- a/cmake/features.cmake +++ b/cmake/features.cmake @@ -17,7 +17,7 @@ ie_option (ENABLE_TESTS "unit, behavior and functional tests" OFF) ie_option (ENABLE_MKL_DNN "MKL-DNN plugin for inference engine" ${ENABLE_MKL_DNN_DEFAULT}) -ie_dependent_option (ENABLE_CLDNN "clDnn based plugin for inference engine" ON "WIN32 OR X86_64;NOT APPLE;NOT MINGW" OFF) +ie_dependent_option (ENABLE_CLDNN "clDnn based plugin for inference engine" ON "WIN32 OR X86_64;NOT APPLE;NOT MINGW;NOT WINDOWS_STORE; NOT WINDOWS_PHONE" OFF) # FIXME: there are compiler failures with LTO and Cross-Compile toolchains. Disabling for now, but # this must be addressed in a proper way diff --git a/cmake/uwp.toolchain.cmake b/cmake/uwp.toolchain.cmake new file mode 100644 index 00000000000000..0cbc410e85ed81 --- /dev/null +++ b/cmake/uwp.toolchain.cmake @@ -0,0 +1,22 @@ +# Copyright (C) 2018-2020 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 +# + +set(CMAKE_SYSTEM_NAME WindowsStore) +set(CMAKE_SYSTEM_VERSION 10.0) + +if (NOT DEFINED CMAKE_SYSTEM_PROCESSOR) + set(CMAKE_SYSTEM_PROCESSOR ${CMAKE_HOST_SYSTEM_PROCESSOR}) +endif() + +file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/src/uwp.hpp" + "#ifdef WINAPI_FAMILY\n" + "#undef WINAPI_FAMILY\n" + "#define WINAPI_FAMILY WINAPI_FAMILY_DESKTOP_APP\n" + "#endif\n") + +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /FI\"${CMAKE_CURRENT_BINARY_DIR}/src/uwp.hpp\"") +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /FI\"${CMAKE_CURRENT_BINARY_DIR}/src/uwp.hpp\"") + +# UWP setting for package isolation +# set(CMAKE_VS_GLOBALS "AppContainerApplication=true") diff --git a/inference-engine/cmake/features_ie.cmake b/inference-engine/cmake/features_ie.cmake index 948a2994984439..71947495cf9e90 100644 --- a/inference-engine/cmake/features_ie.cmake +++ b/inference-engine/cmake/features_ie.cmake @@ -60,7 +60,7 @@ if (ENABLE_GNA) endif() endif() -ie_option (ENABLE_VPU "vpu targeted plugins for inference engine" ON) +ie_dependent_option (ENABLE_VPU "vpu targeted plugins for inference engine" ON "NOT WINDOWS_PHONE;NOT WINDOWS_STORE" OFF) ie_dependent_option (ENABLE_MYRIAD "myriad targeted plugin for inference engine" ON "ENABLE_VPU" OFF) diff --git a/inference-engine/samples/CMakeLists.txt b/inference-engine/samples/CMakeLists.txt index 398ce6961e5221..acbb9ba6b96e9b 100644 --- a/inference-engine/samples/CMakeLists.txt +++ b/inference-engine/samples/CMakeLists.txt @@ -218,7 +218,7 @@ macro(ie_add_sample) set(folder_name cpp_samples) if(IE_SAMPLE_NAME MATCHES ".*_c$") - set(c_sample ON) + set(c_sample ON) set(folder_name c_samples) endif() @@ -232,7 +232,6 @@ macro(ie_add_sample) target_link_libraries(${IE_SAMPLE_NAME} PRIVATE ${OpenCV_LIBRARIES} ${InferenceEngine_LIBRARIES} ${IE_SAMPLE_DEPENDENCIES}) - if(NOT c_sample) target_link_libraries(${IE_SAMPLE_NAME} PRIVATE gflags) endif() diff --git a/inference-engine/src/inference_engine/file_utils.cpp b/inference-engine/src/inference_engine/file_utils.cpp index 58350d01a9b4ca..563d2dc84cf502 100644 --- a/inference-engine/src/inference_engine/file_utils.cpp +++ b/inference-engine/src/inference_engine/file_utils.cpp @@ -19,6 +19,9 @@ # include # include #else +# if defined(WINAPI_FAMILY) && !WINAPI_PARTITION_DESKTOP +# error "Only WINAPI_PARTITION_DESKTOP is supported, because of GetModuleHandleEx[A|W]" +# endif # include #endif @@ -51,48 +54,52 @@ std::basic_string getPathName(const std::basic_string& s) { static std::string getIELibraryPathA() { #ifdef _WIN32 - char ie_library_path[4096]; + CHAR ie_library_path[MAX_PATH]; HMODULE hm = NULL; - if (!GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, - (LPCSTR)getIELibraryPath, &hm)) { + if (!GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, + reinterpret_cast(getIELibraryPath), &hm)) { THROW_IE_EXCEPTION << "GetModuleHandle returned " << GetLastError(); } - GetModuleFileName(hm, (LPSTR)ie_library_path, sizeof(ie_library_path)); + GetModuleFileNameA(hm, (LPSTR)ie_library_path, sizeof(ie_library_path)); return getPathName(std::string(ie_library_path)); -#else -#ifdef USE_STATIC_IE -#ifdef __APPLE__ +#elif defined(__APPLE__) || defined(__linux__) +# ifdef USE_STATIC_IE +# ifdef __APPLE__ Dl_info info; dladdr(reinterpret_cast(getIELibraryPath), &info); std::string path = getPathName(std::string(info.dli_fname)).c_str(); -#else +# else char result[PATH_MAX]; ssize_t count = readlink("/proc/self/exe", result, PATH_MAX); std::string path = getPathName(std::string(result, (count > 0) ? count : 0)); -#endif // __APPLE__ +# endif // __APPLE__ return FileUtils::makePath(path, std::string( "lib")); -#else +# else Dl_info info; dladdr(reinterpret_cast(getIELibraryPath), &info); return getPathName(std::string(info.dli_fname)).c_str(); -#endif // USE_STATIC_IE +# endif // USE_STATIC_IE +#else +# error "Unsupported OS" #endif // _WIN32 } #ifdef ENABLE_UNICODE_PATH_SUPPORT std::wstring getIELibraryPathW() { -#if defined(_WIN32) || defined(_WIN64) - wchar_t ie_library_path[4096]; +#ifdef _WIN32 + WCHAR ie_library_path[MAX_PATH]; HMODULE hm = NULL; if (!GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, - (LPCWSTR)getIELibraryPath, &hm)) { + reinterpret_cast(getIELibraryPath), &hm)) { THROW_IE_EXCEPTION << "GetModuleHandle returned " << GetLastError(); } - GetModuleFileNameW(hm, (LPWSTR)ie_library_path, sizeof(ie_library_path)); + GetModuleFileNameW(hm, (LPWSTR)ie_library_path, sizeof(ie_library_path) / sizeof(ie_library_path[0])); return getPathName(std::wstring(ie_library_path)); -#else +#elif defined(__linux__) || defined(__APPLE__) return ::FileUtils::multiByteCharToWString(getIELibraryPathA().c_str()); +#else +# error "Unsupported OS" #endif } diff --git a/inference-engine/src/inference_engine/os/win/win_shared_object_loader.cpp b/inference-engine/src/inference_engine/os/win/win_shared_object_loader.cpp index f55eea91058987..7b714aa401ad7a 100644 --- a/inference-engine/src/inference_engine/os/win/win_shared_object_loader.cpp +++ b/inference-engine/src/inference_engine/os/win/win_shared_object_loader.cpp @@ -6,6 +6,61 @@ #include "details/ie_so_loader.h" #include "file_utils.h" +// +// LoadLibraryA, LoadLibraryW: +// WINAPI_FAMILY_DESKTOP_APP - OK (default) +// WINAPI_FAMILY_PC_APP - FAIL ?? (defined by cmake) +// WINAPI_FAMILY_PHONE_APP - FAIL ?? +// WINAPI_FAMILY_GAMES - OK +// WINAPI_FAMILY_SERVER - OK +// WINAPI_FAMILY_SYSTEM - OK +// +// GetModuleHandleExA, GetModuleHandleExW: +// WINAPI_FAMILY_DESKTOP_APP - OK (default) +// WINAPI_FAMILY_PC_APP - FAIL ?? (defined by cmake) +// WINAPI_FAMILY_PHONE_APP - FAIL ?? +// WINAPI_FAMILY_GAMES - OK +// WINAPI_FAMILY_SERVER - OK +// WINAPI_FAMILY_SYSTEM - OK +// +// GetModuleHandleA, GetModuleHandleW: +// WINAPI_FAMILY_DESKTOP_APP - OK (default) +// WINAPI_FAMILY_PC_APP - FAIL ?? (defined by cmake) +// WINAPI_FAMILY_PHONE_APP - FAIL ?? +// WINAPI_FAMILY_GAMES - OK +// WINAPI_FAMILY_SERVER - OK +// WINAPI_FAMILY_SYSTEM - OK +// +// SetDllDirectoryA, SetDllDirectoryW: +// WINAPI_FAMILY_DESKTOP_APP - OK (default) +// WINAPI_FAMILY_PC_APP - FAIL ?? (defined by cmake) +// WINAPI_FAMILY_PHONE_APP - FAIL ?? +// WINAPI_FAMILY_GAMES - OK +// WINAPI_FAMILY_SERVER - FAIL +// WINAPI_FAMILY_SYSTEM - FAIL +// +// GetDllDirectoryA, GetDllDirectoryW: +// WINAPI_FAMILY_DESKTOP_APP - FAIL +// WINAPI_FAMILY_PC_APP - FAIL (defined by cmake) +// WINAPI_FAMILY_PHONE_APP - FAIL +// WINAPI_FAMILY_GAMES - FAIL +// WINAPI_FAMILY_SERVER - FAIL +// WINAPI_FAMILY_SYSTEM - FAIL +// +// SetupDiGetClassDevsA, SetupDiEnumDeviceInfo, SetupDiGetDeviceInstanceIdA, SetupDiDestroyDeviceInfoList: +// WINAPI_FAMILY_DESKTOP_APP - FAIL (default) +// WINAPI_FAMILY_PC_APP - FAIL (defined by cmake) +// WINAPI_FAMILY_PHONE_APP - FAIL +// WINAPI_FAMILY_GAMES - FAIL +// WINAPI_FAMILY_SERVER - FAIL +// WINAPI_FAMILY_SYSTEM - FAIL +// + +#if defined(WINAPI_FAMILY) && !WINAPI_PARTITION_DESKTOP +# error "Only WINAPI_PARTITION_DESKTOP is supported, because of LoadLibrary[A|W]" +#endif + +#include #include #include @@ -16,22 +71,53 @@ class SharedObjectLoader::Impl { private: HMODULE shared_object; - void ExcludeCurrentDirectory() { - // Exclude current directory from DLL search path process wise. - // If application specific path was configured before then - // current directory is alread excluded. - // GetDLLDirectory does not distinguish if aplication specific - // path was set to "" or NULL so reset it to "" to keep - // aplication safe. - if (GetDllDirectory(0, NULL) <= 1) { - SetDllDirectory(TEXT("")); + typedef DWORD(* GetDllDirectoryA_Fnc)(DWORD, LPSTR); + typedef DWORD(* GetDllDirectoryW_Fnc)(DWORD, LPWSTR); + + static GetDllDirectoryA_Fnc IEGetDllDirectoryA; + static GetDllDirectoryW_Fnc IEGetDllDirectoryW; + + void LoadSymbols() { + static std::once_flag loadFlag; + std::call_once(loadFlag, [&] () { + if (HMODULE hm = GetModuleHandleW(L"kernel32.dll")) { + IEGetDllDirectoryA = reinterpret_cast(GetProcAddress(hm, "GetDllDirectoryA")); + IEGetDllDirectoryW = reinterpret_cast(GetProcAddress(hm, "GetDllDirectoryW")); + } + }); + } + + // Exclude current directory from DLL search path process wise. + // If application specific path was configured before then + // current directory is already excluded. + // GetDLLDirectory does not distinguish if aplication specific + // path was set to "" or NULL so reset it to "" to keep + // application safe. + void ExcludeCurrentDirectoryA() { + GetDllDirectoryA; +#ifndef WINAPI_FAMILY + LoadSymbols(); + if (IEGetDllDirectoryA && IEGetDllDirectoryA(0, NULL) <= 1) { + SetDllDirectoryA(""); + } +#endif + } + +#ifdef ENABLE_UNICODE_PATH_SUPPORT + void ExcludeCurrentDirectoryW() { +#ifndef WINAPI_FAMILY + LoadSymbols(); + if (IEGetDllDirectoryW && IEGetDllDirectoryW(0, NULL) <= 1) { + SetDllDirectoryW(L""); } +#endif } +#endif public: #ifdef ENABLE_UNICODE_PATH_SUPPORT explicit Impl(const wchar_t* pluginName) { - ExcludeCurrentDirectory(); + ExcludeCurrentDirectoryW(); shared_object = LoadLibraryW(pluginName); if (!shared_object) { @@ -43,7 +129,7 @@ class SharedObjectLoader::Impl { #endif explicit Impl(const char* pluginName) { - ExcludeCurrentDirectory(); + ExcludeCurrentDirectoryA(); shared_object = LoadLibraryA(pluginName); if (!shared_object) { diff --git a/inference-engine/src/mkldnn_plugin/CMakeLists.txt b/inference-engine/src/mkldnn_plugin/CMakeLists.txt index 166818cda371c4..c450e2256cd41f 100644 --- a/inference-engine/src/mkldnn_plugin/CMakeLists.txt +++ b/inference-engine/src/mkldnn_plugin/CMakeLists.txt @@ -174,8 +174,8 @@ target_compile_definitions(${TARGET_NAME} PUBLIC -DMKLDNN_THR=${MKLDNN_THR}) target_link_libraries(${TARGET_NAME} PRIVATE inference_engine inference_engine_lp_transformations inference_engine_transformations mkldnn) -## Cross compiled function -## TODO: The same for proposal, proposalONNX, topk +# Cross compiled function +# TODO: The same for proposal, proposalONNX, topk cross_compiled_file(${TARGET_NAME} ARCH AVX512F AVX2 SSE42 ANY nodes/argmax_imp.cpp diff --git a/inference-engine/src/preprocessing/ie_preprocess_gapi.cpp b/inference-engine/src/preprocessing/ie_preprocess_gapi.cpp index 96db737e598c0a..eba3d59715e045 100644 --- a/inference-engine/src/preprocessing/ie_preprocess_gapi.cpp +++ b/inference-engine/src/preprocessing/ie_preprocess_gapi.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -732,7 +733,7 @@ bool PreprocEngine::useGAPI() { static const bool NO_GAPI = [](const char *str) -> bool { std::string var(str ? str : ""); return var == "N" || var == "NO" || var == "OFF" || var == "0"; - } (std::getenv("USE_GAPI")); + } (getenv("USE_GAPI")); return !NO_GAPI; } diff --git a/inference-engine/thirdparty/fluid/modules/gapi/src/compiler/gcompiler.cpp b/inference-engine/thirdparty/fluid/modules/gapi/src/compiler/gcompiler.cpp index 1ee710c2358343..06327dc3bdb7a4 100644 --- a/inference-engine/thirdparty/fluid/modules/gapi/src/compiler/gcompiler.cpp +++ b/inference-engine/thirdparty/fluid/modules/gapi/src/compiler/gcompiler.cpp @@ -90,7 +90,7 @@ namespace auto dump_info = cv::gimpl::getCompileArg(args); if (!dump_info.has_value()) { - const char* path = std::getenv("GRAPH_DUMP_PATH"); + const char* path = getenv("GRAPH_DUMP_PATH"); return path ? cv::util::make_optional(std::string(path)) : cv::util::optional(); diff --git a/ngraph/core/src/file_util.cpp b/ngraph/core/src/file_util.cpp index 14c855097df8b1..cd22252345264e 100644 --- a/ngraph/core/src/file_util.cpp +++ b/ngraph/core/src/file_util.cpp @@ -187,9 +187,9 @@ void file_util::iterate_files(const string& path, vector files; vector dirs; #ifdef _WIN32 - string file_match = path_join(path, "*"); - WIN32_FIND_DATA data; - HANDLE hFind = FindFirstFile(file_match.c_str(), &data); + std::string file_match = path_join(path, "*"); + WIN32_FIND_DATAA data; + HANDLE hFind = FindFirstFileA(file_match.c_str(), &data); if (hFind != INVALID_HANDLE_VALUE) { do @@ -212,7 +212,7 @@ void file_util::iterate_files(const string& path, string file_name = path_join(path, data.cFileName); func(file_name, false); } - } while (FindNextFile(hFind, &data)); + } while (FindNextFileA(hFind, &data)); FindClose(hFind); } #else diff --git a/ngraph/test/runtime/backend.cpp b/ngraph/test/runtime/backend.cpp index 78169714d1bdf2..da5a7bab7a72b0 100644 --- a/ngraph/test/runtime/backend.cpp +++ b/ngraph/test/runtime/backend.cpp @@ -16,6 +16,9 @@ #ifdef _WIN32 #include +#if defined(WINAPI_FAMILY) && !WINAPI_PARTITION_DESKTOP +#error "Only WINAPI_PARTITION_DESKTOP is supported, because of LoadLibrary[A|W]" +#endif #elif defined(__linux) || defined(__APPLE__) #include #endif @@ -52,9 +55,11 @@ static string find_my_pathname() Dl_info dl_info; dladdr(reinterpret_cast(ngraph::to_lower), &dl_info); return dl_info.dli_fname; +#else +#error "Unsupported OS" #endif #else - return ""; + return {}; #endif } diff --git a/ngraph/test/runtime/backend_manager.cpp b/ngraph/test/runtime/backend_manager.cpp index 139511e899faf6..e15e2df6f522c2 100644 --- a/ngraph/test/runtime/backend_manager.cpp +++ b/ngraph/test/runtime/backend_manager.cpp @@ -161,11 +161,13 @@ DL_HANDLE runtime::BackendManager::open_shared_library(string type) file_util::get_directory(Backend::get_backend_shared_library_search_directory()); string library_path = file_util::path_join(my_directory, library_name); #ifdef _WIN32 - SetDllDirectory((LPCSTR)my_directory.c_str()); - handle = LoadLibrary(library_path.c_str()); -#else + SetDllDirectoryA((LPCSTR)my_directory.c_str()); + handle = LoadLibraryA(library_path.c_str()); +#elif defined(__APPLE__) || defined(__linux__) DLERROR(); // Clear any pending errors handle = dlopen(library_path.c_str(), RTLD_NOW | RTLD_GLOBAL); +#else +#error "Unsupported OS" #endif string error = DLERROR(); if (!handle)