diff --git a/inference-engine/cmake/dependencies.cmake b/inference-engine/cmake/dependencies.cmake index 682f2e55639..728548b9fa5 100644 --- a/inference-engine/cmake/dependencies.cmake +++ b/inference-engine/cmake/dependencies.cmake @@ -72,18 +72,18 @@ if (THREADING STREQUAL "TBB" OR THREADING STREQUAL "TBB_AUTO") if (WIN32) #TODO: add target_path to be platform specific as well, to avoid following if RESOLVE_DEPENDENCY(TBB - ARCHIVE_WIN "tbb2019_20181010_win.zip" #TODO: windows zip archive created incorrectly using old name for folder + ARCHIVE_WIN "tbb2019_20181010_win_with_mall_proxy.zip" #TODO: windows zip archive created incorrectly using old name for folder TARGET_PATH "${TEMP}/tbb" ENVIRONMENT "TBBROOT" VERSION_REGEX ".*_([a-z]*_([a-z0-9]+\\.)*[0-9]+).*") elseif(LINUX) RESOLVE_DEPENDENCY(TBB - ARCHIVE_LIN "tbb2019_20181010_lin.tgz" + ARCHIVE_LIN "tbb2019_20181010_lin_with_mall_proxy.tgz" TARGET_PATH "${TEMP}/tbb" ENVIRONMENT "TBBROOT") else(APPLE) RESOLVE_DEPENDENCY(TBB - ARCHIVE_MAC "tbb2019_20190414_v1_mac.tgz" + ARCHIVE_MAC "tbb2019_20190414_v1_mac_with_mall_proxy.tgz" TARGET_PATH "${TEMP}/tbb" ENVIRONMENT "TBBROOT" VERSION_REGEX ".*_([a-z]*_([a-z0-9]+\\.)*[0-9]+).*") diff --git a/inference-engine/include/details/ie_so_pointer.hpp b/inference-engine/include/details/ie_so_pointer.hpp index 9c803e09c2f..925d81388db 100644 --- a/inference-engine/include/details/ie_so_pointer.hpp +++ b/inference-engine/include/details/ie_so_pointer.hpp @@ -10,10 +10,14 @@ #include #include "ie_so_loader.h" + #include "ie_common.h" #include "ie_plugin.hpp" #include "details/ie_exception.hpp" #include "details/ie_no_release.hpp" +#include "details/os/os_filesystem.hpp" + +#include #include #include @@ -86,11 +90,17 @@ public: * @brief The main constructor * @param name Name of a shared library file */ - explicit SOPointer(const file_name_t &name) - : _so_loader(new Loader(name.c_str())) - , _pointedObj(details::shared_from_irelease( - SymbolLoader(_so_loader).template instantiateSymbol(SOCreatorTrait::name))) { - } + template > + explicit SOPointer(const std::basic_string & name) + : _so_loader(new Loader(name.c_str())), + _pointedObj(details::shared_from_irelease( + SymbolLoader(_so_loader).template instantiateSymbol(SOCreatorTrait::name))) {} + + explicit SOPointer(const char * name) + : _so_loader(new Loader(name)), + _pointedObj(details::shared_from_irelease( + SymbolLoader(_so_loader).template instantiateSymbol(SOCreatorTrait::name))) {} /** * @brief Constructs an object with existing reference diff --git a/inference-engine/include/details/os/lin_shared_object_loader.h b/inference-engine/include/details/os/lin_shared_object_loader.h index 1126e0d13c4..2998f605c06 100644 --- a/inference-engine/include/details/os/lin_shared_object_loader.h +++ b/inference-engine/include/details/os/lin_shared_object_loader.h @@ -10,8 +10,9 @@ #include -#include "../../ie_api.h" -#include "../ie_exception.hpp" +#include "ie_api.h" +#include "details/ie_exception.hpp" +#include "details/os/os_filesystem.hpp" namespace InferenceEngine { namespace details { @@ -35,6 +36,18 @@ public: if (shared_object == nullptr) THROW_IE_EXCEPTION << "Cannot load library '" << pluginName << "': " << dlerror(); } + +#ifdef ENABLE_UNICODE_PATH_SUPPORT + /** + * @brief Loads a library with the name specified. The library is loaded according to + * the POSIX rules for dlopen + * @param pluginName Full or relative path to the library + */ + explicit SharedObjectLoader(const wchar_t* pluginName) : SharedObjectLoader(wStringtoMBCSstringChar(pluginName).c_str()) { + } + +#endif // ENABLE_UNICODE_PATH_SUPPORT + ~SharedObjectLoader() noexcept(false) { if (0 != dlclose(shared_object)) { THROW_IE_EXCEPTION << "dlclose failed: " << dlerror(); diff --git a/inference-engine/include/details/os/os_filesystem.hpp b/inference-engine/include/details/os/os_filesystem.hpp index d94c7da0d69..ea1231001cf 100644 --- a/inference-engine/include/details/os/os_filesystem.hpp +++ b/inference-engine/include/details/os/os_filesystem.hpp @@ -9,13 +9,20 @@ #pragma once #ifdef ENABLE_UNICODE_PATH_SUPPORT -#include #include +#endif + +#include #include namespace InferenceEngine { namespace details { +template +using enableIfSupportedChar = typename std::enable_if<(std::is_same::value || std::is_same::value)>::type; + +#ifdef ENABLE_UNICODE_PATH_SUPPORT + /** * @brief Conversion from wide character string to a single-byte chain. */ @@ -33,7 +40,7 @@ inline const std::wstring multiByteCharToWString(const char* str) { return result; } +#endif // ENABLE_UNICODE_PATH_SUPPORT + } // namespace details } // namespace InferenceEngine - -#endif diff --git a/inference-engine/include/details/os/win_shared_object_loader.h b/inference-engine/include/details/os/win_shared_object_loader.h index 32f3e10c9e9..b373f2074e3 100644 --- a/inference-engine/include/details/os/win_shared_object_loader.h +++ b/inference-engine/include/details/os/win_shared_object_loader.h @@ -8,8 +8,9 @@ */ #pragma once -#include "../../ie_api.h" -#include "../ie_exception.hpp" +#include "ie_api.h" +#include "details/ie_exception.hpp" +#include "details/os/os_filesystem.hpp" // Avoidance of Windows.h to include winsock library. #define _WINSOCKAPI_ @@ -30,14 +31,7 @@ class SharedObjectLoader { private: HMODULE shared_object; -public: - /** - * @brief Loads a library with the name specified. The library is loaded according to the - * WinAPI LoadLibrary rules - * @param pluginName Full or relative path to the plugin library - */ - explicit SharedObjectLoader(LPCTSTR pluginName) { - char cwd[1024]; + void ExcludeCurrentDirectory() { // Exclude current directory from DLL search path process wise. // If application specific path was configured before then // current directory is alread excluded. @@ -45,21 +39,38 @@ public: // path was set to "" or NULL so reset it to "" to keep // aplication safe. if (GetDllDirectory(0, NULL) <= 1) { - SetDllDirectory( -#if defined UNICODE - L""); -#else - ""); -#endif - } - shared_object = LoadLibrary(pluginName); - if (!shared_object) { - THROW_IE_EXCEPTION << "Cannot load library '" - << pluginName << "': " - << GetLastError() - << " from cwd: " << _getcwd(cwd, 1024); + SetDllDirectory(TEXT("")); } } + +public: + /** + * @brief Loads a library with the name specified. The library is loaded according to the + * WinAPI LoadLibrary rules + * @param pluginName Full or relative path to the plugin library + */ + explicit SharedObjectLoader(LPCWSTR pluginName) { + ExcludeCurrentDirectory(); + + shared_object = LoadLibraryW(pluginName); + if (!shared_object) { + char cwd[1024]; + THROW_IE_EXCEPTION << "Cannot load library '" << details::wStringtoMBCSstringChar(std::wstring(pluginName)) << "': " << GetLastError() + << " from cwd: " << _getcwd(cwd, sizeof(cwd)); + } + } + + explicit SharedObjectLoader(LPCSTR pluginName) { + ExcludeCurrentDirectory(); + + shared_object = LoadLibrary(pluginName); + if (!shared_object) { + char cwd[1024]; + THROW_IE_EXCEPTION << "Cannot load library '" << pluginName << "': " << GetLastError() + << " from cwd: " << _getcwd(cwd, sizeof(cwd)); + } + } + ~SharedObjectLoader() { FreeLibrary(shared_object); } diff --git a/inference-engine/include/ie_api.h b/inference-engine/include/ie_api.h index e9132f17c06..d955c8758f0 100644 --- a/inference-engine/include/ie_api.h +++ b/inference-engine/include/ie_api.h @@ -80,7 +80,7 @@ #ifndef ENABLE_UNICODE_PATH_SUPPORT #if defined(_WIN32) #define ENABLE_UNICODE_PATH_SUPPORT - #elif defined(__GNUC__) && (__GNUC__ > 5 || (__GNUC__ == 5 && __GNUC_MINOR__ > 2)) + #elif defined(__GNUC__) && (__GNUC__ > 5 || (__GNUC__ == 5 && __GNUC_MINOR__ > 2)) || defined(__clang__) #define ENABLE_UNICODE_PATH_SUPPORT #endif #endif diff --git a/inference-engine/samples/common/samples/common.hpp b/inference-engine/samples/common/samples/common.hpp index 58efdc673ad..9cf75a5c366 100644 --- a/inference-engine/samples/common/samples/common.hpp +++ b/inference-engine/samples/common/samples/common.hpp @@ -49,13 +49,32 @@ class ConsoleErrorListener : public InferenceEngine::IErrorListener { }; /** - * @brief Trims from both ends (in place) + * @brief trim from start (in place) + * @param s - string to trim + */ +inline void ltrim(std::string &s) { + s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](int c){ + return !std::isspace(c); + })); +} + +/** + * @brief trim from end (in place) + * @param s - string to trim + */ +inline void rtrim(std::string &s) { + s.erase(std::find_if(s.rbegin(), s.rend(), [](int c) { + return !std::isspace(c); + }).base(), s.end()); +} + +/** + * @brief trim from both ends (in place) * @param s - string to trim - * @return trimmed string */ inline std::string &trim(std::string &s) { - s.erase(s.begin(), std::find_if(s.begin(), s.end(), std::not1(std::ptr_fun(std::isspace)))); - s.erase(std::find_if(s.rbegin(), s.rend(), std::not1(std::ptr_fun(std::isspace))).base(), s.end()); + ltrim(s); + rtrim(s); return s; } diff --git a/inference-engine/src/inference_engine/cpp_interfaces/ie_task_executor.cpp b/inference-engine/src/inference_engine/cpp_interfaces/ie_task_executor.cpp index 3868abc9fb0..60b06b676ff 100644 --- a/inference-engine/src/inference_engine/cpp_interfaces/ie_task_executor.cpp +++ b/inference-engine/src/inference_engine/cpp_interfaces/ie_task_executor.cpp @@ -18,7 +18,7 @@ namespace InferenceEngine { TaskExecutor::TaskExecutor(std::string name) : _isStopped(false), _name(name) { _thread = std::make_shared([&] { - anotateSetThreadName(("TaskExecutor thread for " + _name).c_str()); + annotateSetThreadName(("TaskExecutor thread for " + _name).c_str()); while (!_isStopped) { bool isQueueEmpty; Task::Ptr currentTask; diff --git a/inference-engine/src/inference_engine/file_utils.cpp b/inference-engine/src/inference_engine/file_utils.cpp index f9b035a2d4b..36ded6d7773 100644 --- a/inference-engine/src/inference_engine/file_utils.cpp +++ b/inference-engine/src/inference_engine/file_utils.cpp @@ -53,34 +53,3 @@ void FileUtils::readAllFile(const std::string &string_file_name, void *buffer, s inputFile.close(); } -std::string FileUtils::folderOf(const std::string &filepath) { - auto pos = filepath.rfind(FileSeparator); - if (pos == std::string::npos) pos = filepath.rfind(FileSeparator2); - if (pos == std::string::npos) return ""; - return filepath.substr(0, pos); -} - -std::string FileUtils::makePath(const std::string &folder, const std::string &file) { - if (folder.empty()) return file; - return folder + FileSeparator + file; -} - -std::string FileUtils::fileNameNoExt(const std::string &filepath) { - auto pos = filepath.rfind('.'); - if (pos == std::string::npos) return filepath; - return filepath.substr(0, pos); -} - -std::string FileUtils::fileExt(const char *filename) { - return fileExt(std::string(filename)); -} - -std::string FileUtils::fileExt(const std::string &filename) { - auto pos = filename.rfind('.'); - if (pos == std::string::npos) return ""; - return filename.substr(pos + 1); -} - -bool FileUtils::isSharedLibrary(const std::string& fileName) { - return 0 == strncasecmp(fileExt(fileName).c_str(), SharedLibraryExt, strlen(SharedLibraryExt)); -} diff --git a/inference-engine/src/inference_engine/file_utils.h b/inference-engine/src/inference_engine/file_utils.h index ce79a9f1787..aaabb527312 100644 --- a/inference-engine/src/inference_engine/file_utils.h +++ b/inference-engine/src/inference_engine/file_utils.h @@ -24,60 +24,102 @@ #endif #include "ie_api.h" +#include "ie_unicode.hpp" +#include "details/os/os_filesystem.hpp" +#include "details/ie_so_pointer.hpp" namespace FileUtils { + +template struct FileTraits; + #ifdef _WIN32 /// @brief File path separator const char FileSeparator = '\\'; -const char SharedLibraryExt[] = "dll"; -#elif __APPLE__ -const char SharedLibraryExt[] = "dylib"; +template<> struct FileTraits { + constexpr static const auto FileSeparator = ::FileUtils::FileSeparator; + static std::string SharedLibraryPrefix() { return { }; } + static std::string SharedLibraryExt() { return { "dll" }; } +}; +template<> struct FileTraits { + constexpr static const auto FileSeparator = L'\\'; + static std::wstring SharedLibraryPrefix() { return { }; } + static std::wstring SharedLibraryExt() { return { L"dll" }; } +}; +#elif defined __APPLE__ /// @brief File path separator const char FileSeparator = '/'; +template<> struct FileTraits { + constexpr static const auto FileSeparator = ::FileUtils::FileSeparator; + static std::string SharedLibraryPrefix() { return { "lib" }; } + static std::string SharedLibraryExt() { return { "dylib" }; } +}; +template<> struct FileTraits { + constexpr static const auto FileSeparator = L'/'; + static std::wstring SharedLibraryPrefix() { return { L"lib" }; } + static std::wstring SharedLibraryExt() { return { L"dylib" }; } +}; #else -const char SharedLibraryExt[] = "so"; /// @brief File path separator const char FileSeparator = '/'; +template<> struct FileTraits { + constexpr static const auto FileSeparator = ::FileUtils::FileSeparator; + static std::string SharedLibraryPrefix() { return { "lib" }; } + static std::string SharedLibraryExt() { return { "so" }; } +}; +template<> struct FileTraits { + constexpr static const auto FileSeparator = L'/'; + static std::wstring SharedLibraryPrefix() { return { L"lib" }; } + static std::wstring SharedLibraryExt() { return { L"so" }; } +}; #endif -/// @brief Alternative file path separator -const char FileSeparator2 = '/'; // second option /** - * @brief Interface function to get the size of a file + * @brief Interface function to get the size of a file. The function supports UNICODE path * @param fileName - name of the file * @return size of the file */ INFERENCE_ENGINE_API_CPP(long long) fileSize(const char *fileName); +#ifdef ENABLE_UNICODE_PATH_SUPPORT + +inline long long fileSize(const wchar_t* fileName) { + return fileSize(InferenceEngine::details::wStringtoMBCSstringChar(fileName).c_str()); +} + +#endif // ENABLE_UNICODE_PATH_SUPPORT + /** - * @brief Function to get the size of a file + * @brief Function to get the size of a file. The function supports UNICODE path * @param f - string name of the file * @return size of the file */ -inline long long fileSize(const std::string &f) { +template > +inline long long fileSize(const std::basic_string &f) { return fileSize(f.c_str()); } /** - * @brief check if file with a given filename exists + * @brief check if file with a given filename exists. The function supports UNICODE path * @param fileName - given filename * @return true is exists */ -inline bool fileExist(const char *fileName) { +template > +inline bool fileExist(const C * fileName) { return fileSize(fileName) >= 0; } /** - * @brief check if file with a given filename exists + * @brief check if file with a given filename exists. The function supports UNICODE path * @param fileName - string with a given filename * @return true is exists */ -inline bool fileExist(const std::string &fileName) { +template > +inline bool fileExist(const std::basic_string &fileName) { return fileExist(fileName.c_str()); } /** - * @brief CPP Interface function to read a file. In case of read error throws an exception + * @brief CPP Interface function to read a file. In case of read error throws an exception. The function supports UNICODE path * @param file_name - name of the file to read * @param buffer - buffer to read file to * @param maxSize - maximum size in bytes to read @@ -92,40 +134,84 @@ INFERENCE_ENGINE_API_CPP(void) readAllFile(const std::string &file_name, void *b INFERENCE_ENGINE_API_CPP(std::string) folderOf(const std::string &filepath); /** - * @brief CPP Interface function to combint path with filename + * @brief CPP Interface function to combint path with filename. The function supports UNICODE path * @param folder - path to add filename to * @param file - filename to add to path * @return string with combination of the path and the filename divided by file separator */ -INFERENCE_ENGINE_API_CPP(std::string) makePath(const std::string &folder, const std::string &file); +template > +inline std::basic_string makePath(const std::basic_string &folder, const std::basic_string &file) { + if (folder.empty()) + return file; + return folder + FileTraits::FileSeparator + file; +} -/** - * @brief CPP Interface function to remove file extension - * @param filepath - filename with extension - * @return string containing filename without extension - */ -INFERENCE_ENGINE_API_CPP(std::string) fileNameNoExt(const std::string &filepath); - -/** - * @brief CPP Interface function to extract extension from filename - * @param filename - name of the file which extension should be extracted - * @return string with extracted file extension - */ -INFERENCE_ENGINE_API_CPP(std::string) fileExt(const char *filename); +template struct DotSymbol; +template <> struct DotSymbol { constexpr static const char value = '.'; }; +template <> struct DotSymbol { constexpr static const wchar_t value = L'.'; }; /** * @brief CPP Interface function to extract extension from filename * @param filename - string with the name of the file which extension should be extracted * @return string with extracted file extension */ -INFERENCE_ENGINE_API_CPP(std::string) fileExt(const std::string &filename); +template > +inline std::basic_string fileExt(const std::basic_string &filename) { + auto pos = filename.rfind(DotSymbol::value); + if (pos == std::string::npos) + return {}; + return filename.substr(pos + 1); +} /** * @brief CPP Interface function to check if given filename belongs to shared library * @param filename - file name to check * @return true if filename is a shared library filename */ -INFERENCE_ENGINE_API_CPP(bool) isSharedLibrary(const std::string &fileName); +inline bool isSharedLibrary(const std::string &fileName) { + return 0 == +#ifdef _WIN32 + _strnicmp +#else + strncasecmp +#endif + (fileExt(fileName).c_str(), FileTraits::SharedLibraryExt().c_str(), + FileTraits::SharedLibraryExt().size()); +} + +template > +inline std::basic_string makeSharedLibraryName(const std::basic_string &path, const std::basic_string &input) { + std::basic_string separator(1, FileTraits::FileSeparator); + if (path.empty()) + separator = {}; + return path + separator + FileTraits::SharedLibraryPrefix() + input + DotSymbol::value + FileTraits::SharedLibraryExt(); +} + +#ifdef ENABLE_UNICODE_PATH_SUPPORT + +using FilePath = std::wstring; + +inline std::string fromFilePath(const FilePath & path) { + return InferenceEngine::details::wStringtoMBCSstringChar(path); +} + +inline FilePath toFilePath(const std::string & path) { + return InferenceEngine::details::multiByteCharToWString(path.c_str()); +} + +#else + +using FilePath = std::string; + +inline std::string fromFilePath(const FilePath & path) { + return path; +} + +inline FilePath toFilePath(const std::string & path) { + return path; +} + +#endif // ENABLE_UNICODE_PATH_SUPPORT /** * @brief TODO: description diff --git a/inference-engine/src/inference_engine/ie_core.cpp b/inference-engine/src/inference_engine/ie_core.cpp index 06dce037229..f28d2d8b9c8 100644 --- a/inference-engine/src/inference_engine/ie_core.cpp +++ b/inference-engine/src/inference_engine/ie_core.cpp @@ -112,9 +112,9 @@ class Core::Impl : public ICore { mutable std::map > plugins; struct PluginDescriptor { - file_name_t libraryLocation; + FileUtils::FilePath libraryLocation; std::map defaultConfig; - std::vector listOfExtentions; + std::vector listOfExtentions; }; std::map > pluginRegistry; IErrorListener * listener = nullptr; @@ -123,12 +123,20 @@ public: ~Impl() override; /** - * @brief Register plugins for devices which are located in .xml configuration file + * @brief Register plugins for devices which are located in .xml configuration file. The function supports UNICODE path * @param xmlConfigFile - an .xml configuraion with device / plugin information */ void RegisterPluginsInRegistry(const std::string & xmlConfigFile) { +#if defined(ENABLE_UNICODE_PATH_SUPPORT) && defined(_WIN32) + std::wstring wFilePath = InferenceEngine::details::multiByteCharToWString(xmlConfigFile.c_str()); + const wchar_t* resolvedFilepath = wFilePath.c_str(); +#else + const char* resolvedFilepath = xmlConfigFile.c_str(); +#endif + + pugi::xml_document xmlDoc; - pugi::xml_parse_result res = xmlDoc.load_file(xmlConfigFile.c_str()); + pugi::xml_parse_result res = xmlDoc.load_file(resolvedFilepath); if (res.status != pugi::status_ok) { std::ifstream t(xmlConfigFile); @@ -160,7 +168,7 @@ public: for (auto pluginNode = devicesNode.child("plugin"); !pluginNode.empty(); pluginNode = pluginNode.next_sibling("plugin")) { std::string deviceName = GetStrAttr(pluginNode, "name"); - file_name_t pluginPath = GetStrAttr(pluginNode, "location"); + FileUtils::FilePath pluginPath = FileUtils::toFilePath(GetStrAttr(pluginNode, "location").c_str()); if (deviceName.find('.') != std::string::npos) { THROW_IE_EXCEPTION << "Device name must not contain dot '.' symbol"; @@ -168,9 +176,8 @@ public: // append IR library path for default IE plugins { - std::string absPluginPath = FileUtils::makePath(getIELibraryPath(), pluginPath); - if (FileUtils::fileExist(absPluginPath)) - pluginPath = absPluginPath; + FileUtils::FilePath absFilePath = FileUtils::makePath(getInferenceEngineLibraryPath(), pluginPath); + if (FileUtils::fileExist(absFilePath)) pluginPath = absFilePath; } // check properties @@ -188,12 +195,12 @@ public: // check extensions auto extensionsNode = pluginNode.child("extensions"); - std::vector listOfExtentions; + std::vector listOfExtentions; if (extensionsNode) { for (auto extensionNode = extensionsNode.child("extension"); !extensionNode.empty(); extensionNode = extensionNode.next_sibling("extension")) { - std::string extensionLocation = GetStrAttr(extensionNode, "location"); + FileUtils::FilePath extensionLocation = FileUtils::toFilePath(GetStrAttr(extensionNode, "location").c_str()); listOfExtentions.push_back(extensionLocation); } } @@ -262,8 +269,10 @@ public: { cppPlugin.SetConfig(desc.defaultConfig); - for (auto && extensionLocation : desc.listOfExtentions) { - cppPlugin.AddExtension(make_so_pointer(extensionLocation)); + for (auto&& extensionLocation : desc.listOfExtentions) { + // TODO: fix once InferenceEngine::Extension can accept FileUtils::FilePath + // currently, extensions cannot be loaded using wide path + cppPlugin.AddExtension(make_so_pointer(FileUtils::fromFilePath(extensionLocation))); } if (listener) @@ -271,8 +280,9 @@ public: } plugins[deviceName] = cppPlugin; - } catch (const details::InferenceEngineException & ex) { - THROW_IE_EXCEPTION << "Failed to create plugin " << desc.libraryLocation << " for device " << deviceName << "\n" + } catch (const details::InferenceEngineException& ex) { + THROW_IE_EXCEPTION << "Failed to create plugin " << FileUtils::fromFilePath(desc.libraryLocation) + << " for device " << deviceName << "\n" << "Please, check your environment\n" << ex.what() << "\n"; } @@ -309,13 +319,12 @@ public: } // append IR library path for default IE plugins - std::string pluginPath; + FileUtils::FilePath pluginPath; { - pluginPath = make_plugin_name(file_name_t(), pluginName); + pluginPath = FileUtils::makeSharedLibraryName({}, FileUtils::toFilePath(pluginName.c_str())); - std::string absPluginPath = FileUtils::makePath(getIELibraryPath(), pluginPath); - if (FileUtils::fileExist(absPluginPath)) - pluginPath = absPluginPath; + FileUtils::FilePath absFilePath = FileUtils::makePath(getInferenceEngineLibraryPath(), pluginPath); + if (FileUtils::fileExist(absFilePath)) pluginPath = absFilePath; } PluginDescriptor desc = { pluginPath, { }, { } }; @@ -368,7 +377,8 @@ Core::Core(const std::string & xmlConfigFile) { std::string xmlConfigFile_ = xmlConfigFile; if (xmlConfigFile_.empty()) { // register plugins from default plugins.xml config - xmlConfigFile_ = FileUtils::makePath(getIELibraryPath(), "plugins.xml"); + FileUtils::FilePath xmlConfigFileDefault = FileUtils::makePath(getInferenceEngineLibraryPath(), FileUtils::toFilePath("plugins.xml")); + xmlConfigFile_ = FileUtils::fromFilePath(xmlConfigFileDefault); } RegisterPlugins(xmlConfigFile_); diff --git a/inference-engine/src/inference_engine/ie_profiling.hpp b/inference-engine/src/inference_engine/ie_profiling.hpp index 37c5d11f79e..baacac95ca4 100644 --- a/inference-engine/src/inference_engine/ie_profiling.hpp +++ b/inference-engine/src/inference_engine/ie_profiling.hpp @@ -263,7 +263,7 @@ inline static void annotateEnd(IttStatic&, IttProfilingTask& t) { #define IE_PROFILING_AUTO_SCOPE_TASK(PROFILING_TASK) IE_ITT_TASK_SCOPE(PROFILING_TASK); IE_TIMER_SCOPE(PROFILING_TASK.name) -inline static void anotateSetThreadName(const char* name) { +inline static void annotateSetThreadName(const char* name) { #ifdef ENABLE_PROFILING_ITT __itt_thread_set_name(name); #endif diff --git a/inference-engine/src/inference_engine/ie_util_internal.cpp b/inference-engine/src/inference_engine/ie_util_internal.cpp index 1a2f0784607..45861395f44 100644 --- a/inference-engine/src/inference_engine/ie_util_internal.cpp +++ b/inference-engine/src/inference_engine/ie_util_internal.cpp @@ -9,6 +9,7 @@ #include "ie_icnn_network_stats.hpp" #include "cpp/ie_plugin_cpp.hpp" #include "details/ie_cnn_network_tools.h" +#include "details/os/os_filesystem.hpp" #include "file_utils.h" #include "net_pass.h" #include "precision_utils.h" @@ -737,32 +738,54 @@ std::unordered_set getRootDataObjects(ICNNNetwork &network) { namespace { -std::string getPathName(const std::string & s) { - size_t i = s.rfind(FileUtils::FileSeparator, s.length()); +template > +std::basic_string getPathName(const std::basic_string& s) { + size_t i = s.rfind(FileUtils::FileTraits::FileSeparator, s.length()); if (i != std::string::npos) { return(s.substr(0, i)); } - return std::string(); + return {}; } } // namespace -std::string getIELibraryPath() { +#ifndef _WIN32 + +static std::string getIELibraryPathUnix() { + Dl_info info; + dladdr(reinterpret_cast(getIELibraryPath), &info); + return getPathName(std::string(info.dli_fname)).c_str(); +} + +#endif // _WIN32 + +#ifdef ENABLE_UNICODE_PATH_SUPPORT + +std::wstring getIELibraryPathW() { #if defined(_WIN32) || defined(_WIN64) - char ie_library_path[2048]; + wchar_t ie_library_path[4096]; HMODULE hm = NULL; - if (!GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | - GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, - (LPCSTR)getIELibraryPath, &hm)) { + if (!GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, + (LPCWSTR)getIELibraryPath, &hm)) { THROW_IE_EXCEPTION << "GetModuleHandle returned " << GetLastError(); } - GetModuleFileNameA(hm, (LPSTR)ie_library_path, sizeof(ie_library_path)); - return getPathName(ie_library_path); + GetModuleFileNameW(hm, (LPWSTR)ie_library_path, sizeof(ie_library_path)); + return getPathName(std::wstring(ie_library_path)); #else Dl_info info; - dladdr(reinterpret_cast(getIELibraryPath), &info); - return getPathName(info.dli_fname); + dladdr(reinterpret_cast(getIELibraryPath), &info); + return details::multiByteCharToWString(getIELibraryPathUnix().c_str()); +#endif +} + +#endif + +std::string getIELibraryPath() { +#ifdef ENABLE_UNICODE_PATH_SUPPORT + return details::wStringtoMBCSstringChar(getIELibraryPathW()); +#else + return getIELibraryPathUnix(); #endif } diff --git a/inference-engine/src/inference_engine/ie_util_internal.hpp b/inference-engine/src/inference_engine/ie_util_internal.hpp index cf12b732f9f..c048ebeedae 100644 --- a/inference-engine/src/inference_engine/ie_util_internal.hpp +++ b/inference-engine/src/inference_engine/ie_util_internal.hpp @@ -14,6 +14,7 @@ #include #include +#include #include #include @@ -187,6 +188,17 @@ getRootDataObjects(ICNNNetwork &network); INFERENCE_ENGINE_API_CPP(std::string) getIELibraryPath(); +#ifdef ENABLE_UNICODE_PATH_SUPPORT +INFERENCE_ENGINE_API_CPP(std::wstring) getIELibraryPathW(); +inline ::FileUtils::FilePath getInferenceEngineLibraryPath() { + return getIELibraryPathW(); +} +#else +inline ::FileUtils::FilePath getInferenceEngineLibraryPath() { + return getIELibraryPath(); +} +#endif // ENABLE_UNICODE_PATH_SUPPORT + } // namespace InferenceEngine #endif // IE_UTIL_HPP diff --git a/inference-engine/src/mkldnn_plugin/nodes/mkldnn_split_node.cpp b/inference-engine/src/mkldnn_plugin/nodes/mkldnn_split_node.cpp index 30fbf1d909a..eb68e7b897e 100644 --- a/inference-engine/src/mkldnn_plugin/nodes/mkldnn_split_node.cpp +++ b/inference-engine/src/mkldnn_plugin/nodes/mkldnn_split_node.cpp @@ -328,6 +328,42 @@ void MKLDNNSplitNode::selectOptimalPrimitiveDescriptor() { } } + // This logic is needed to cover cases when Split node cannot be optimized out for particular block size + // In general it is significantly better to have additional reorders in graph than to use reference Split implementation + if (convertTo == memory::nChw16c || convertTo == memory::nCdhw16c || + convertTo == memory::nChw8c || convertTo == memory::nCdhw8c) { + int blockSize = convertTo == memory::nChw16c || convertTo == memory::nCdhw16c ? 16 : 8; + bool shouldDecreaseBlockSize = false; + for (auto& parentEdge : getParentEdges()) { + if (parentEdge.lock()->getDims()[1] % blockSize != 0) + shouldDecreaseBlockSize = true; + } + + for (auto& childEdge : getChildEdges()) { + if (childEdge.lock()->getDims()[1] % blockSize != 0) + shouldDecreaseBlockSize = true; + } + + if (shouldDecreaseBlockSize) { + int decreasedBlockSize = 8; + bool canDecreaseBlockSize = true; + for (auto &parentEdge : getParentEdges()) { + if (parentEdge.lock()->getDims()[1] % decreasedBlockSize != 0) + canDecreaseBlockSize = false; + } + + for (auto &childEdge : getChildEdges()) { + if (childEdge.lock()->getDims()[1] % decreasedBlockSize != 0) + canDecreaseBlockSize = false; + } + + if (canDecreaseBlockSize) + convertTo = getParentEdgeAt(0)->getDims().ndims() == 5 ? memory::nCdhw8c : memory::nChw8c; + else + convertTo = MKLDNNMemory::GetPlainFormat(getParentEdgeAt(0)->getDims()); + } + } + if (canOptimize && MKLDNNMemoryDesc(getParentEdgeAt(0)->getDims(), inputDataType, convertTo).blocksExtended()) canOptimize = false; for (size_t i = 0; canOptimize && i < getChildEdges().size(); i++) { diff --git a/inference-engine/tests/helpers/tests_unicode.hpp b/inference-engine/tests/helpers/tests_unicode.hpp new file mode 100644 index 00000000000..b5eb61dc806 --- /dev/null +++ b/inference-engine/tests/helpers/tests_unicode.hpp @@ -0,0 +1,82 @@ +// Copyright (C) 2018-2019 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include +#include +#include +#include
+ +#ifdef ENABLE_UNICODE_PATH_SUPPORT + +static void fixSlashes(std::string &str) { + std::replace(str.begin(), str.end(), '/', '\\'); +} + +static void fixSlashes(std::wstring &str) { + std::replace(str.begin(), str.end(), L'/', L'\\'); +} + +static std::wstring stringToWString(std::string input) { + std::wstring_convert> converter; + std::wstring result = converter.from_bytes(input); + return result; +} + +static bool copyFile(std::wstring source_path, std::wstring dest_path) { +#ifndef _WIN32 + std::ifstream source(InferenceEngine::details::wStringtoMBCSstringChar(source_path), std::ios::binary); + std::ofstream dest(InferenceEngine::details::wStringtoMBCSstringChar(dest_path), std::ios::binary); +#else + fixSlashes(source_path); + fixSlashes(dest_path); + std::ifstream source(source_path, std::ios::binary); + std::ofstream dest(dest_path, std::ios::binary); +#endif + bool result = source && dest; + std::istreambuf_iterator begin_source(source); + std::istreambuf_iterator end_source; + std::ostreambuf_iterator begin_dest(dest); + copy(begin_source, end_source, begin_dest); + + source.close(); + dest.close(); + return result; +} + +static bool copyFile(std::string source_path, std::wstring dest_path) { + return copyFile(stringToWString(source_path), dest_path); +} + +static std::wstring addUnicodePostfixToPath(std::string source_path, std::wstring postfix) { + fixSlashes(source_path); + std::wstring result = stringToWString(source_path); + std::wstring file_name = result.substr(0, result.size() - 4); + std::wstring extension = result.substr(result.size() - 4, result.size()); + result = file_name + postfix + extension; + return result; +} + +static void removeFile(std::wstring path) { + int result = 0; + if (!path.empty()) { +#ifdef _WIN32 + result = _wremove(path.c_str()); +#else + result = remove(InferenceEngine::details::wStringtoMBCSstringChar(path).c_str()); +#endif + } +} + +static const std::vector test_unicode_postfix_vector = { + L"unicode_Яㅎあ", + L"ひらがな日本語", + L"大家有天分", + L"עפצקרשתםןףץ", + L"ث خ ذ ض ظ غ", + L"그것이정당하다", + L"АБВГДЕЁЖЗИЙ", + L"СТУФХЦЧШЩЬЮЯ" +}; + +#endif // ENABLE_UNICODE_PATH_SUPPORT diff --git a/inference-engine/thirdparty/mkl-dnn/src/cpu/jit_avx2_conv_kernel_f32.cpp b/inference-engine/thirdparty/mkl-dnn/src/cpu/jit_avx2_conv_kernel_f32.cpp index 652d0e160bf..8ac336a7275 100644 --- a/inference-engine/thirdparty/mkl-dnn/src/cpu/jit_avx2_conv_kernel_f32.cpp +++ b/inference-engine/thirdparty/mkl-dnn/src/cpu/jit_avx2_conv_kernel_f32.cpp @@ -615,12 +615,19 @@ status_t jit_avx2_conv_fwd_kernel_f32::init_conf(jit_conv_conf_t &jcp, // adjust one of nb_oc_block, ur_w preserving to ur_w >= l_pad if (jcp.ur_w > jcp.l_pad && jcp.ur_w > 1) jcp.ur_w -= 1; - else - for (int b = 3; b > 1; b--) + else { + for (int b = 3; b > 1; b--) { if (jcp.nb_oc % b == 0) { jcp.nb_oc_blocking = b; break; } + } + if ((jcp.nb_oc_blocking + 1) * jcp.ur_w > num_avail_regs) { + // No optimal size for 'nb_oc_blocking' with regards to + // 'nb_oc', default to only unroll by 'ur_w'. + jcp.nb_oc_blocking = 1; + } + } } } diff --git a/inference-engine/thirdparty/mkl-dnn/src/cpu/jit_uni_1x1_conv_utils.hpp b/inference-engine/thirdparty/mkl-dnn/src/cpu/jit_uni_1x1_conv_utils.hpp index 37858d7e640..78ebb9d5251 100644 --- a/inference-engine/thirdparty/mkl-dnn/src/cpu/jit_uni_1x1_conv_utils.hpp +++ b/inference-engine/thirdparty/mkl-dnn/src/cpu/jit_uni_1x1_conv_utils.hpp @@ -97,6 +97,7 @@ inline void rtus_prepare(conv_pd_t *self, const convolution_desc_t *&conv_d, template inline void rtus_prepare_space_info(conv_pd_t *self, memory_tracking::registrar_t &scratchpad) { + if (!self->rtus_.reduce_src_) return; const auto &jcp = self->jcp_; const int max_threads = mkldnn_get_max_threads();