Moved SO Loader to util library (#8017)

* Moved SO Loader to util library

* Removed redundant headers

* Fixed code style

* Fixed build

* Fixed templateFuncTests

* Removed SharedObjectLoader from util library
This commit is contained in:
Ilya Churaev 2021-10-21 06:47:48 +03:00 committed by GitHub
parent 0f3c10c810
commit 83fe59bd3e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 207 additions and 203 deletions

View File

@ -45,9 +45,6 @@ if (LINUX)
file (GLOB LIBRARY_HEADERS
${LIBRARY_HEADERS}
${CMAKE_CURRENT_SOURCE_DIR}/src/os/lin/*.hpp)
elseif (UNIX)
list (APPEND LIBRARY_SRC
${CMAKE_CURRENT_SOURCE_DIR}/src/os/lin/lin_shared_object_loader.cpp)
endif()
if (WIN32)

View File

@ -64,8 +64,15 @@ public:
* @param name Name of a shared library file
*/
template <typename C, typename = enableIfSupportedChar<C>>
SOPointer(const std::basic_string<C>& name) : _so(name.c_str()) {
SOPointer(const std::basic_string<C>& name) {
try {
_so = SharedObjectLoader(name.c_str());
Load(std::integral_constant<bool, HasRelease::value>{});
} catch (const std::runtime_error& ex) {
IE_THROW() << ex.what();
} catch (...) {
details::Rethrow();
}
}
/**
@ -158,6 +165,8 @@ protected:
using CreateF = void(std::shared_ptr<T>&);
reinterpret_cast<CreateF*>(create)(_ptr);
}
} catch (const std::runtime_error& ex) {
IE_THROW() << ex.what();
} catch (...) {
details::Rethrow();
}
@ -170,6 +179,8 @@ protected:
try {
using CreateF = void(std::shared_ptr<T>&);
reinterpret_cast<CreateF*>(_so.get_symbol(SOCreatorTrait<T>::name))(_ptr);
} catch (const std::runtime_error& ex) {
IE_THROW() << ex.what();
} catch (...) {
details::Rethrow();
}

View File

@ -37,6 +37,7 @@
#include "openvino/runtime/core.hpp"
#include "openvino/runtime/executable_network.hpp"
#include "openvino/util/file_util.hpp"
#include "openvino/util/shared_object.hpp"
#include "xml_parse_utils.h"
using namespace InferenceEngine::PluginConfigParams;
@ -685,6 +686,8 @@ public:
// plugin is not created by e.g. invalid env
} catch (ov::Exception&) {
// plugin is not created by e.g. invalid env
} catch (std::runtime_error&) {
// plugin is not created by e.g. invalid env
} catch (const std::exception& ex) {
IE_THROW() << "An exception is thrown while trying to create the " << deviceName
<< " device and call GetMetric: " << ex.what();
@ -724,11 +727,11 @@ public:
auto it_plugin = plugins.find(deviceName);
if (it_plugin == plugins.end()) {
PluginDescriptor desc = it->second;
auto so = load_shared_object(desc.libraryLocation.c_str());
auto so = ov::util::load_shared_object(desc.libraryLocation.c_str());
try {
using CreateF = void(std::shared_ptr<ie::IInferencePlugin>&);
std::shared_ptr<ie::IInferencePlugin> plugin_impl;
reinterpret_cast<CreateF*>(get_symbol(so, OV_PP_TOSTRING(IE_CREATE_PLUGIN)))(plugin_impl);
reinterpret_cast<CreateF*>(ov::util::get_symbol(so, OV_PP_TOSTRING(IE_CREATE_PLUGIN)))(plugin_impl);
auto plugin = InferencePlugin{so, plugin_impl};
{

View File

@ -1,97 +0,0 @@
// Copyright (C) 2018-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include <dlfcn.h>
#include <iostream>
#include "details/ie_so_loader.h"
#include "file_utils.h"
#include "openvino/util/file_util.hpp"
#include "shared_object.hpp"
namespace ov {
namespace runtime {
std::shared_ptr<void> load_shared_object(const char* path) {
auto shared_object = std::shared_ptr<void>{dlopen(path, RTLD_NOW), [](void* shared_object) {
if (shared_object != nullptr) {
if (0 != dlclose(shared_object)) {
std::cerr << "dlclose failed: " << dlerror() << std::endl;
}
}
}};
if (!shared_object) {
IE_THROW() << "Cannot load library '" << path << "': " << dlerror();
}
return shared_object;
}
#ifdef OPENVINO_ENABLE_UNICODE_PATH_SUPPORT
std::shared_ptr<void> load_shared_object(const wchar_t* path) {
return load_shared_object(ov::util::wstring_to_string(path).c_str());
}
#endif // OPENVINO_ENABLE_UNICODE_PATH_SUPPORT
void* get_symbol(const std::shared_ptr<void>& shared_object, const char* symbol_name) {
if (!shared_object) {
IE_THROW() << "Cannot get '" << symbol_name << "' content from unknown library!";
}
void* procAddr = nullptr;
procAddr = dlsym(shared_object.get(), symbol_name);
if (procAddr == nullptr) {
IE_THROW(NotFound) << "dlSym cannot locate method '" << symbol_name << "': " << dlerror();
}
return procAddr;
}
} // namespace runtime
} // namespace ov
namespace InferenceEngine {
namespace details {
struct SharedObjectLoader::Impl {
std::shared_ptr<void> shared_object = nullptr;
explicit Impl(const std::shared_ptr<void>& shared_object_) : shared_object{shared_object_} {}
explicit Impl(const char* pluginName) : shared_object{ov::runtime::load_shared_object(pluginName)} {}
#ifdef OPENVINO_ENABLE_UNICODE_PATH_SUPPORT
explicit Impl(const wchar_t* pluginName) : Impl(ov::util::wstring_to_string(pluginName).c_str()) {}
#endif // OPENVINO_ENABLE_UNICODE_PATH_SUPPORT
void* get_symbol(const char* symbolName) const {
return ov::runtime::get_symbol(shared_object, symbolName);
}
};
SharedObjectLoader::SharedObjectLoader(const std::shared_ptr<void>& shared_object) {
_impl.reset(new Impl(shared_object));
}
#ifdef OPENVINO_ENABLE_UNICODE_PATH_SUPPORT
SharedObjectLoader::SharedObjectLoader(const wchar_t* pluginName) {
_impl.reset(new Impl(pluginName));
}
#endif
SharedObjectLoader::SharedObjectLoader(const char* pluginName) {
_impl.reset(new Impl(pluginName));
}
SharedObjectLoader::~SharedObjectLoader() {}
void* SharedObjectLoader::get_symbol(const char* symbolName) const {
if (_impl == nullptr) {
IE_THROW(NotAllocated) << "SharedObjectLoader is not initialized";
}
return _impl->get_symbol(symbolName);
}
std::shared_ptr<void> SharedObjectLoader::get() const {
return _impl->shared_object;
}
} // namespace details
} // namespace InferenceEngine

View File

@ -0,0 +1,57 @@
// Copyright (C) 2018-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include "details/ie_so_loader.h"
#include "ie_common.h"
#include "openvino/util/file_util.hpp"
#include "openvino/util/shared_object.hpp"
namespace InferenceEngine {
namespace details {
struct SharedObjectLoader::Impl {
std::shared_ptr<void> shared_object = nullptr;
explicit Impl(const std::shared_ptr<void>& shared_object_) : shared_object{shared_object_} {}
explicit Impl(const char* pluginName) : shared_object{ov::util::load_shared_object(pluginName)} {}
#ifdef OPENVINO_ENABLE_UNICODE_PATH_SUPPORT
explicit Impl(const wchar_t* pluginName) : Impl(ov::util::wstring_to_string(pluginName).c_str()) {}
#endif // OPENVINO_ENABLE_UNICODE_PATH_SUPPORT
void* get_symbol(const char* symbolName) const {
return ov::util::get_symbol(shared_object, symbolName);
}
};
SharedObjectLoader::SharedObjectLoader(const std::shared_ptr<void>& shared_object) {
_impl.reset(new Impl(shared_object));
}
#ifdef OPENVINO_ENABLE_UNICODE_PATH_SUPPORT
SharedObjectLoader::SharedObjectLoader(const wchar_t* pluginName) {
_impl.reset(new Impl(pluginName));
}
#endif
SharedObjectLoader::SharedObjectLoader(const char* pluginName) {
_impl.reset(new Impl(pluginName));
}
SharedObjectLoader::~SharedObjectLoader() {}
void* SharedObjectLoader::get_symbol(const char* symbolName) const {
if (_impl == nullptr) {
IE_THROW(NotAllocated) << "SharedObjectLoader is not initialized";
}
return _impl->get_symbol(symbolName);
}
std::shared_ptr<void> SharedObjectLoader::get() const {
return _impl->shared_object;
}
} // namespace details
} // namespace InferenceEngine

View File

@ -15,7 +15,6 @@
#include <type_traits>
#include "openvino/runtime/common.hpp"
#include "shared_object.hpp"
namespace ov {
namespace runtime {

View File

@ -5,7 +5,7 @@
#include <gtest/gtest.h>
#include <file_utils.h>
#include "shared_object.hpp"
#include "openvino/util/shared_object.hpp"
#include <cpp/ie_plugin.hpp>
using namespace ::testing;
@ -19,14 +19,14 @@ protected:
}
void loadDll(const string &libraryName) {
shared_object = ov::runtime::load_shared_object(libraryName.c_str());
shared_object = ov::util::load_shared_object(libraryName.c_str());
}
std::shared_ptr<void> shared_object;
using CreateF = void(std::shared_ptr<InferenceEngine::IInferencePlugin>&);
std::function<CreateF> make_std_function(const std::string& functionName) {
std::function<CreateF> ptr(reinterpret_cast<CreateF*>(ov::runtime::get_symbol(shared_object, functionName.c_str())));
std::function<CreateF> ptr(reinterpret_cast<CreateF*>(ov::util::get_symbol(shared_object, functionName.c_str())));
return ptr;
}
};
@ -37,7 +37,7 @@ TEST_F(SharedObjectOVTests, canLoadExistedPlugin) {
}
TEST_F(SharedObjectOVTests, loaderThrowsIfNoPlugin) {
EXPECT_THROW(loadDll("wrong_name"), InferenceEngine::Exception);
EXPECT_THROW(loadDll("wrong_name"), std::runtime_error);
}
TEST_F(SharedObjectOVTests, canFindExistedMethod) {
@ -49,7 +49,7 @@ TEST_F(SharedObjectOVTests, canFindExistedMethod) {
TEST_F(SharedObjectOVTests, throwIfMethodNofFoundInLibrary) {
loadDll(get_mock_engine_name());
EXPECT_THROW(make_std_function("wrong_function"), InferenceEngine::Exception);
EXPECT_THROW(make_std_function("wrong_function"), std::runtime_error);
}
TEST_F(SharedObjectOVTests, canCallExistedMethod) {

View File

@ -41,7 +41,7 @@ TEST_F(SharedObjectLoaderTests, canLoadExistedPlugin) {
}
TEST_F(SharedObjectLoaderTests, loaderThrowsIfNoPlugin) {
EXPECT_THROW(loadDll("wrong_name"), InferenceEngine::Exception);
EXPECT_THROW(loadDll("wrong_name"), std::runtime_error);
}
TEST_F(SharedObjectLoaderTests, canFindExistedMethod) {
@ -53,7 +53,7 @@ TEST_F(SharedObjectLoaderTests, canFindExistedMethod) {
TEST_F(SharedObjectLoaderTests, throwIfMethodNofFoundInLibrary) {
loadDll(get_mock_engine_name());
EXPECT_THROW(make_std_function("wrong_function"), InferenceEngine::Exception);
EXPECT_THROW(make_std_function("wrong_function"), std::runtime_error);
}
TEST_F(SharedObjectLoaderTests, canCallExistedMethod) {

View File

@ -9,6 +9,18 @@ file(GLOB_RECURSE PUBLIC_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/include/*.hpp)
set(UTIL_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include/)
if (WIN32)
# Remove linux specific files
file(GLOB_RECURSE LIN_FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/os/lin/*.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/os/lin/*.hpp)
list(REMOVE_ITEM LIBRARY_SRC ${LIN_FILES})
else()
# Remove windows specific files
file(GLOB_RECURSE WIN_FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/os/win/*.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/os/win/*.hpp)
list(REMOVE_ITEM LIBRARY_SRC ${WIN_FILES})
endif()
# Create named folders for the sources within the .vcproj
# Empty name lists them directly under the .vcproj

View File

@ -9,15 +9,7 @@
#include <string>
#include <vector>
#ifndef OPENVINO_ENABLE_UNICODE_PATH_SUPPORT
# ifdef _WIN32
# if defined __INTEL_COMPILER || defined _MSC_VER
# define OPENVINO_ENABLE_UNICODE_PATH_SUPPORT
# endif
# elif defined(__GNUC__) && (__GNUC__ > 5 || (__GNUC__ == 5 && __GNUC_MINOR__ > 2)) || defined(__clang__)
# define OPENVINO_ENABLE_UNICODE_PATH_SUPPORT
# endif
#endif
#include "openvino/util/util.hpp"
namespace ov {
namespace util {

View File

@ -4,21 +4,24 @@
/**
* @brief A header file for definition of abstraction over platform specific shared objects
* @file ie_system_conf.h
* @file shared_object.hpp
*/
#pragma once
#include "ie_api.h"
#include <memory>
#include "openvino/util/util.hpp"
namespace ov {
namespace runtime {
namespace util {
/**
* @brief Loads a library with the name specified.
* @param path Full or relative path to the plugin library
* @return Reference to shared object
*/
INFERENCE_ENGINE_API_CPP(std::shared_ptr<void>) load_shared_object(const char* path);
std::shared_ptr<void> load_shared_object(const char* path);
#ifdef OPENVINO_ENABLE_UNICODE_PATH_SUPPORT
/**
@ -26,7 +29,7 @@ INFERENCE_ENGINE_API_CPP(std::shared_ptr<void>) load_shared_object(const char* p
* @param path Full or relative path to the plugin library
* @return Reference to shared object
*/
INFERENCE_ENGINE_API_CPP(std::shared_ptr<void>) load_shared_object(const wchar_t* path);
std::shared_ptr<void> load_shared_object(const wchar_t* path);
#endif // OPENVINO_ENABLE_UNICODE_PATH_SUPPORT
/**
* @brief Searches for a function symbol in the loaded module
@ -35,6 +38,7 @@ INFERENCE_ENGINE_API_CPP(std::shared_ptr<void>) load_shared_object(const wchar_t
* @return A pointer to the function if found
* @throws Exception if the function is not found
*/
INFERENCE_ENGINE_API_CPP(void*) get_symbol(const std::shared_ptr<void>& shared_object, const char* symbolName);
} // namespace runtime
void* get_symbol(const std::shared_ptr<void>& shared_object, const char* symbolName);
} // namespace util
} // namespace ov

View File

@ -0,0 +1,15 @@
// Copyright (C) 2018-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#pragma once
#ifndef OPENVINO_ENABLE_UNICODE_PATH_SUPPORT
# ifdef _WIN32
# if defined __INTEL_COMPILER || defined _MSC_VER
# define OPENVINO_ENABLE_UNICODE_PATH_SUPPORT
# endif
# elif defined(__GNUC__) && (__GNUC__ > 5 || (__GNUC__ == 5 && __GNUC_MINOR__ > 2)) || defined(__clang__)
# define OPENVINO_ENABLE_UNICODE_PATH_SUPPORT
# endif
#endif

View File

@ -0,0 +1,53 @@
// Copyright (C) 2018-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include <dlfcn.h>
#include <iostream>
#include <sstream>
#include "openvino/util/file_util.hpp"
#include "openvino/util/shared_object.hpp"
namespace ov {
namespace util {
std::shared_ptr<void> load_shared_object(const char* path) {
auto shared_object = std::shared_ptr<void>{dlopen(path, RTLD_NOW), [](void* shared_object) {
if (shared_object != nullptr) {
if (0 != dlclose(shared_object)) {
std::cerr << "dlclose failed: " << dlerror() << std::endl;
}
}
}};
if (!shared_object) {
std::stringstream ss;
ss << "Cannot load library '" << path << "': " << dlerror();
throw std::runtime_error(ss.str());
}
return shared_object;
}
#ifdef OPENVINO_ENABLE_UNICODE_PATH_SUPPORT
std::shared_ptr<void> load_shared_object(const wchar_t* path) {
return load_shared_object(ov::util::wstring_to_string(path).c_str());
}
#endif // OPENVINO_ENABLE_UNICODE_PATH_SUPPORT
void* get_symbol(const std::shared_ptr<void>& shared_object, const char* symbol_name) {
if (!shared_object) {
std::stringstream ss;
ss << "Cannot get '" << symbol_name << "' content from unknown library!";
throw std::runtime_error(ss.str());
}
void* procAddr = nullptr;
procAddr = dlsym(shared_object.get(), symbol_name);
if (procAddr == nullptr) {
std::stringstream ss;
ss << "dlSym cannot locate method '" << symbol_name << "': " << dlerror();
throw std::runtime_error(ss.str());
}
return procAddr;
}
} // namespace util
} // namespace ov

View File

@ -2,10 +2,10 @@
// SPDX-License-Identifier: Apache-2.0
//
#include "ie_common.h"
#include "details/ie_so_loader.h"
#include "file_utils.h"
#include "shared_object.hpp"
#include <sstream>
#include "openvino/util/file_util.hpp"
#include "openvino/util/shared_object.hpp"
//
// LoadLibraryA, LoadLibraryW:
@ -61,9 +61,10 @@
# error "Only WINAPI_PARTITION_DESKTOP is supported, because of LoadLibrary[A|W]"
#endif
#include <mutex>
#include <direct.h>
#include <mutex>
#ifndef NOMINMAX
# define NOMINMAX
#endif
@ -71,7 +72,7 @@
#include <windows.h>
namespace ov {
namespace runtime {
namespace util {
std::shared_ptr<void> load_shared_object(const char* path) {
void* shared_object = nullptr;
using GetDllDirectoryA_Fnc = DWORD (*)(DWORD, LPSTR);
@ -113,11 +114,11 @@ std::shared_ptr<void> load_shared_object(const char* path) {
if (!shared_object) {
char cwd[1024];
IE_THROW() << "Cannot load library '" << path << "': " << GetLastError()
<< " from cwd: " << _getcwd(cwd, sizeof(cwd));
std::stringstream ss;
ss << "Cannot load library '" << path << "': " << GetLastError() << " from cwd: " << _getcwd(cwd, sizeof(cwd));
throw std::runtime_error(ss.str());
}
return {shared_object,
[] (void* shared_object) {
return {shared_object, [](void* shared_object) {
FreeLibrary(reinterpret_cast<HMODULE>(shared_object));
}};
}
@ -159,11 +160,12 @@ std::shared_ptr<void> load_shared_object(const wchar_t* path) {
}
if (!shared_object) {
char cwd[1024];
IE_THROW() << "Cannot load library '" << ov::util::wstring_to_string(std::wstring(path)) << "': " << GetLastError()
std::stringstream ss;
ss << "Cannot load library '" << ov::util::wstring_to_string(std::wstring(path)) << "': " << GetLastError()
<< " from cwd: " << _getcwd(cwd, sizeof(cwd));
throw std::runtime_error(ss.str());
}
return {shared_object,
[] (void* shared_object) {
return {shared_object, [](void* shared_object) {
FreeLibrary(reinterpret_cast<HMODULE>(shared_object));
}};
}
@ -171,62 +173,18 @@ std::shared_ptr<void> load_shared_object(const wchar_t* path) {
void* get_symbol(const std::shared_ptr<void>& shared_object, const char* symbol_name) {
if (!shared_object) {
IE_THROW() << "Cannot get '" << symbol_name << "' content from unknown library!";
std::stringstream ss;
ss << "Cannot get '" << symbol_name << "' content from unknown library!";
throw std::runtime_error(ss.str());
}
auto procAddr = reinterpret_cast<void*>(GetProcAddress(
reinterpret_cast<HMODULE>(const_cast<void*>(shared_object.get())), symbol_name));
auto procAddr = reinterpret_cast<void*>(
GetProcAddress(reinterpret_cast<HMODULE>(const_cast<void*>(shared_object.get())), symbol_name));
if (procAddr == nullptr) {
IE_THROW(NotFound)
<< "GetProcAddress cannot locate method '" << symbol_name << "': " << GetLastError();
std::stringstream ss;
ss << "GetProcAddress cannot locate method '" << symbol_name << "': " << GetLastError();
throw std::runtime_error(ss.str());
}
return procAddr;
}
} // namespace runtime
} // namespace util
} // namespace ov
namespace InferenceEngine {
namespace details {
struct SharedObjectLoader::Impl {
std::shared_ptr<void> shared_object = nullptr;
explicit Impl(const std::shared_ptr<void>& shared_object_) : shared_object{shared_object_} {}
explicit Impl(const char* pluginName) : shared_object{ov::runtime::load_shared_object(pluginName)} {}
#ifdef OPENVINO_ENABLE_UNICODE_PATH_SUPPORT
explicit Impl(const wchar_t* pluginName) : shared_object{ov::runtime::load_shared_object(pluginName)} {}
#endif // OPENVINO_ENABLE_UNICODE_PATH_SUPPORT
void* get_symbol(const char* symbolName) const {
return ov::runtime::get_symbol(shared_object, symbolName);
}
};
SharedObjectLoader::SharedObjectLoader(const std::shared_ptr<void>& shared_object) {
_impl.reset(new Impl(shared_object));
}
SharedObjectLoader::~SharedObjectLoader() {}
SharedObjectLoader::SharedObjectLoader(const char * pluginName) {
_impl = std::make_shared<Impl>(pluginName);
}
#ifdef OPENVINO_ENABLE_UNICODE_PATH_SUPPORT
SharedObjectLoader::SharedObjectLoader(const wchar_t* pluginName) {
_impl = std::make_shared<Impl>(pluginName);
}
#endif
void* SharedObjectLoader::get_symbol(const char* symbolName) const {
if (_impl == nullptr) {
IE_THROW(NotAllocated) << "SharedObjectLoader is not initialized";
}
return _impl->get_symbol(symbolName);
}
std::shared_ptr<void> SharedObjectLoader::get() const {
return _impl->shared_object;
}
} // namespace details
} // namespace InferenceEngine