[2022.3] Safe plugins loading (#21037)
* [Core] Safe loading of default plugins (#15073) * Fix "(un)register_plugin(s)" C and Py tests (#15291) * Update test in order to save behaviour
This commit is contained in:
parent
8af1f18596
commit
9839b55081
|
|
@ -127,21 +127,10 @@ TEST(ie_core_register_plugin, registerPlugin) {
|
|||
IE_ASSERT_OK(ie_core_create("", &core));
|
||||
ASSERT_NE(nullptr, core);
|
||||
|
||||
ie_network_t *network = nullptr;
|
||||
IE_EXPECT_OK(ie_core_read_network(core, xml, bin, &network));
|
||||
EXPECT_NE(nullptr, network);
|
||||
|
||||
const char *plugin_name = "openvino_intel_cpu_plugin";
|
||||
const char *plugin_name = "test_plugin";
|
||||
const char *device_name = "BLA";
|
||||
IE_EXPECT_OK(ie_core_register_plugin(core, plugin_name, device_name));
|
||||
|
||||
ie_config_t config = {nullptr, nullptr, nullptr};
|
||||
ie_executable_network_t *exe_network = nullptr;
|
||||
IE_EXPECT_OK(ie_core_load_network(core, network, device_name, &config, &exe_network));
|
||||
EXPECT_NE(nullptr, exe_network);
|
||||
|
||||
ie_exec_network_free(&exe_network);
|
||||
ie_network_free(&network);
|
||||
ie_core_free(&core);
|
||||
}
|
||||
|
||||
|
|
@ -150,43 +139,24 @@ TEST(ie_core_register_plugins, registerPlugins) {
|
|||
IE_ASSERT_OK(ie_core_create("", &core));
|
||||
ASSERT_NE(nullptr, core);
|
||||
|
||||
ie_network_t *network = nullptr;
|
||||
IE_EXPECT_OK(ie_core_read_network(core, xml, bin, &network));
|
||||
EXPECT_NE(nullptr, network);
|
||||
|
||||
IE_EXPECT_OK(ie_core_register_plugins(core, plugins_xml));
|
||||
|
||||
ie_config_t config = {nullptr, nullptr, nullptr};
|
||||
const char *device_name = "CUSTOM";
|
||||
ie_executable_network_t *exe_network = nullptr;
|
||||
IE_EXPECT_OK(ie_core_load_network(core, network, device_name, &config, &exe_network));
|
||||
EXPECT_NE(nullptr, exe_network);
|
||||
|
||||
ie_exec_network_free(&exe_network);
|
||||
ie_network_free(&network);
|
||||
ie_core_free(&core);
|
||||
}
|
||||
|
||||
TEST(ie_core_unregister_plugin, unregisterPlugin) {
|
||||
TEST(ie_core_unload_plugin, unloadPlugin) {
|
||||
ie_core_t *core = nullptr;
|
||||
IE_ASSERT_OK(ie_core_create(plugins_xml, &core));
|
||||
IE_ASSERT_OK(ie_core_create("", &core));
|
||||
ASSERT_NE(nullptr, core);
|
||||
|
||||
ie_network_t *network = nullptr;
|
||||
IE_EXPECT_OK(ie_core_read_network(core, xml, bin, &network));
|
||||
EXPECT_NE(nullptr, network);
|
||||
|
||||
ie_config_t config = {nullptr, nullptr, nullptr};
|
||||
const char *device_name = "CUSTOM";
|
||||
ie_executable_network_t *exe_network = nullptr;
|
||||
IE_EXPECT_OK(ie_core_load_network(core, network, device_name, &config, &exe_network));
|
||||
EXPECT_NE(nullptr, exe_network);
|
||||
|
||||
ie_exec_network_free(&exe_network);
|
||||
ie_network_free(&network);
|
||||
|
||||
const char *device_name = "CPU";
|
||||
ie_core_versions_t versions = {0};
|
||||
// Trigger plugin loading
|
||||
IE_EXPECT_OK(ie_core_get_versions(core, device_name, &versions));
|
||||
// Unload plugin
|
||||
IE_EXPECT_OK(ie_core_unregister_plugin(core, device_name));
|
||||
|
||||
ie_core_versions_free(&versions);
|
||||
ie_core_free(&core);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import pytest
|
||||
import sys
|
||||
import numpy as np
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
|
@ -28,7 +29,6 @@ from tests.test_utils.test_utils import (
|
|||
generate_image,
|
||||
generate_relu_compiled_model,
|
||||
get_relu_model,
|
||||
generate_lib_name,
|
||||
plugins_path,
|
||||
)
|
||||
|
||||
|
|
@ -257,43 +257,40 @@ def test_query_model(device):
|
|||
|
||||
|
||||
@pytest.mark.dynamic_library()
|
||||
def test_register_plugin(device):
|
||||
def test_register_plugin():
|
||||
device = "TEST_DEVICE"
|
||||
lib_name = "test_plugin"
|
||||
full_lib_name = lib_name + ".dll" if sys.platform == "win32" else "lib" + lib_name + ".so"
|
||||
|
||||
core = Core()
|
||||
full_device_name = core.get_property(device, "FULL_DEVICE_NAME")
|
||||
lib_name = generate_lib_name(device, full_device_name)
|
||||
core.register_plugin(lib_name, "BLA")
|
||||
model = core.read_model(model=test_net_xml, weights=test_net_bin)
|
||||
compiled_model = core.compile_model(model, "BLA")
|
||||
assert isinstance(compiled_model, CompiledModel), "Cannot load the network to the registered plugin with name 'BLA'"
|
||||
core.register_plugin(lib_name, device)
|
||||
with pytest.raises(RuntimeError) as e:
|
||||
core.get_versions(device)
|
||||
assert f"Cannot load library '{full_lib_name}'" in str(e.value)
|
||||
|
||||
|
||||
@pytest.mark.dynamic_library()
|
||||
def test_register_plugins(device):
|
||||
def test_register_plugins():
|
||||
device = "TEST_DEVICE"
|
||||
lib_name = "test_plugin"
|
||||
full_lib_name = lib_name + ".dll" if sys.platform == "win32" else "lib" + lib_name + ".so"
|
||||
plugins_xml = plugins_path(device, full_lib_name)
|
||||
|
||||
core = Core()
|
||||
full_device_name = core.get_property(device, "FULL_DEVICE_NAME")
|
||||
plugins_xml = plugins_path(device, full_device_name)
|
||||
core.register_plugins(plugins_xml)
|
||||
model = core.read_model(model=test_net_xml, weights=test_net_bin)
|
||||
compiled_model = core.compile_model(model, "CUSTOM")
|
||||
os.remove(plugins_xml)
|
||||
assert isinstance(compiled_model, CompiledModel), (
|
||||
"Cannot load the network to "
|
||||
"the registered plugin with name 'CUSTOM' "
|
||||
"registered in the XML file"
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.skip(reason="Need to figure out if it's expected behaviour (fails with C++ API as well")
|
||||
def test_unregister_plugin(device):
|
||||
core = Core()
|
||||
core.unload_plugin(device)
|
||||
model = core.read_model(model=test_net_xml, weights=test_net_bin)
|
||||
with pytest.raises(RuntimeError) as e:
|
||||
core.load_network(model, device)
|
||||
assert (
|
||||
f"Device with '{device}' name is not registered in the OpenVINO Runtime"
|
||||
in str(e.value)
|
||||
)
|
||||
core.get_versions(device)
|
||||
assert f"Cannot load library '{full_lib_name}'" in str(e.value)
|
||||
|
||||
|
||||
def test_unload_plugin(device):
|
||||
core = Core()
|
||||
# Trigger plugin loading
|
||||
core.get_versions(device)
|
||||
# Unload plugin
|
||||
core.unload_plugin(device)
|
||||
|
||||
|
||||
@pytest.mark.template_plugin()
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ import numpy as np
|
|||
import pytest
|
||||
|
||||
from pathlib import Path
|
||||
from platform import processor
|
||||
|
||||
import openvino
|
||||
import openvino.runtime.opset8 as ops
|
||||
|
|
@ -28,30 +27,10 @@ def test_compare_models():
|
|||
print("openvino.test_utils.compare_models is not available") # noqa: T201
|
||||
|
||||
|
||||
def generate_lib_name(device, full_device_name):
|
||||
lib_name = ""
|
||||
arch = processor()
|
||||
if arch == "x86_64" or "Intel" in full_device_name or device in ["GNA", "HDDL", "MYRIAD", "VPUX"]:
|
||||
lib_name = "openvino_intel_" + device.lower() + "_plugin"
|
||||
elif arch != "x86_64" and device == "CPU":
|
||||
lib_name = "openvino_arm_cpu_plugin"
|
||||
elif device in ["HETERO", "MULTI", "AUTO"]:
|
||||
lib_name = "openvino_" + device.lower() + "_plugin"
|
||||
return lib_name
|
||||
|
||||
|
||||
def plugins_path(device, full_device_name):
|
||||
lib_name = generate_lib_name(device, full_device_name)
|
||||
full_lib_name = ""
|
||||
|
||||
if sys.platform == "win32":
|
||||
full_lib_name = lib_name + ".dll"
|
||||
else:
|
||||
full_lib_name = "lib" + lib_name + ".so"
|
||||
|
||||
def plugins_path(device, lib_path):
|
||||
plugin_xml = f"""<ie>
|
||||
<plugins>
|
||||
<plugin location="{full_lib_name}" name="CUSTOM">
|
||||
<plugin location="{lib_path}" name="{device}">
|
||||
</plugin>
|
||||
</plugins>
|
||||
</ie>"""
|
||||
|
|
|
|||
|
|
@ -85,16 +85,16 @@ def test_query_network(device):
|
|||
|
||||
|
||||
@pytest.mark.dynamic_library
|
||||
@pytest.mark.skipif(os.environ.get("TEST_DEVICE", "CPU") != "CPU", reason="Device dependent test")
|
||||
def test_register_plugin():
|
||||
ie = IECore()
|
||||
if ie.get_metric("CPU", "FULL_DEVICE_NAME") == "arm_compute::NEON":
|
||||
pytest.skip("Can't run on ARM plugin due-to openvino_intel_cpu_plugin specific test")
|
||||
ie.register_plugin("openvino_intel_cpu_plugin", "BLA")
|
||||
net = ie.read_network(model=test_net_xml, weights=test_net_bin)
|
||||
exec_net = ie.load_network(net, "BLA")
|
||||
assert isinstance(exec_net, ExecutableNetwork), "Cannot load the network to the registered plugin with name 'BLA'"
|
||||
device = "TEST_DEVICE"
|
||||
lib_name = "test_plugin"
|
||||
full_lib_name = lib_name + ".dll" if sys.platform == "win32" else "lib" + lib_name + ".so"
|
||||
|
||||
ie = IECore()
|
||||
ie.register_plugin(lib_name, device)
|
||||
with pytest.raises(RuntimeError) as e:
|
||||
ie.get_versions(device)
|
||||
assert f"Cannot load library '{full_lib_name}'" in str(e.value)
|
||||
|
||||
@pytest.mark.dynamic_library
|
||||
def test_register_plugins():
|
||||
|
|
@ -119,17 +119,15 @@ def test_register_plugins():
|
|||
|
||||
with pytest.raises(RuntimeError) as e:
|
||||
ie.get_versions(device)
|
||||
assert f"Cannot load library '{full_lib_name}" in str(e.value)
|
||||
assert f"Cannot load library '{full_lib_name}'" in str(e.value)
|
||||
|
||||
|
||||
@pytest.mark.skip(reason="Need to figure out if it's expected behaviour (fails with C++ API as well")
|
||||
def test_unregister_plugin(device):
|
||||
def test_unload_plugin(device):
|
||||
ie = IECore()
|
||||
# Trigger plugin loading
|
||||
ie.get_versions(device)
|
||||
# Unload plugin
|
||||
ie.unregister_plugin(device)
|
||||
net = ie.read_network(model=test_net_xml, weights=test_net_bin)
|
||||
with pytest.raises(RuntimeError) as e:
|
||||
ie.load_network(net, device)
|
||||
assert f"Device with '{device}' name is not registered in the OpenVINO Runtime" in str(e.value)
|
||||
|
||||
|
||||
def test_available_devices(device):
|
||||
|
|
|
|||
|
|
@ -33,6 +33,9 @@ add_library(${TARGET_NAME} STATIC ${LIBRARY_SRC} ${PUBLIC_HEADERS})
|
|||
add_library(openvino::util ALIAS ${TARGET_NAME})
|
||||
|
||||
target_link_libraries(${TARGET_NAME} PRIVATE ${CMAKE_DL_LIBS})
|
||||
if (WIN32)
|
||||
target_link_libraries(${TARGET_NAME} PRIVATE Shlwapi)
|
||||
endif()
|
||||
target_include_directories(${TARGET_NAME} PUBLIC
|
||||
$<BUILD_INTERFACE:${UTIL_INCLUDE_DIR}>)
|
||||
|
||||
|
|
|
|||
|
|
@ -97,9 +97,18 @@ std::string get_file_name(const std::string& path);
|
|||
* @brief Interface function to get absolute path of file
|
||||
* @param path - path to file, can be relative to current working directory
|
||||
* @return Absolute path of file
|
||||
* @throw runtime_error if any error occurred
|
||||
* @throw runtime_error if absolute path can't be resolved
|
||||
*/
|
||||
std::string get_absolute_file_path(const std::string& path);
|
||||
|
||||
/**
|
||||
* @brief Interface function to check path to file is absolute or not
|
||||
* @param path - path to file, can be relative to current working directory
|
||||
* @return True if path is absolute and False otherwise
|
||||
* @throw runtime_error if any error occurred
|
||||
*/
|
||||
bool is_absolute_file_path(const std::string& path);
|
||||
|
||||
/**
|
||||
* @brief Interface function to create directorty recursively by given path
|
||||
* @param path - path to file, can be relative to current working directory
|
||||
|
|
@ -242,6 +251,26 @@ inline std::basic_string<C> make_plugin_library_name(const std::basic_string<C>&
|
|||
FileTraits<C>::library_ext();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Format plugin path (canonicalize, complete to absolute or complete to file name) for further
|
||||
* dynamic loading by OS
|
||||
* @param plugin - Path (absolute or relative) or name of a plugin. Depending on platform, `plugin` is wrapped with
|
||||
* shared library suffix and prefix to identify library full name
|
||||
* @return absolute path or file name with extension (to be found in ENV)
|
||||
*/
|
||||
FilePath get_plugin_path(const std::string& plugin);
|
||||
|
||||
/**
|
||||
* @brief Format plugin path (canonicalize, complete to absolute or complete to file name) for further
|
||||
* dynamic loading by OS
|
||||
* @param plugin - Path (absolute or relative) or name of a plugin. Depending on platform, `plugin` is wrapped with
|
||||
* shared library suffix and prefix to identify library full name
|
||||
* @param xml_path - Path (absolute or relative) to XML configuration file
|
||||
* @param as_abs_only - Bool value, allows return file names or not
|
||||
* @return absolute path or file name with extension (to be found in ENV)
|
||||
*/
|
||||
FilePath get_plugin_path(const std::string& plugin, const std::string& xml_path, bool as_abs_only = false);
|
||||
|
||||
/**
|
||||
* @brief load binary data from file
|
||||
* @param path - binary file path to load
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
# ifndef NOMINMAX
|
||||
# define NOMINMAX
|
||||
# endif
|
||||
# include <Shlwapi.h>
|
||||
# include <direct.h>
|
||||
# include <windows.h>
|
||||
/// @brief Max length of absolute file path
|
||||
|
|
@ -351,14 +352,26 @@ std::wstring ov::util::string_to_wstring(const std::string& string) {
|
|||
std::string ov::util::get_absolute_file_path(const std::string& path) {
|
||||
std::string absolutePath;
|
||||
absolutePath.resize(MAX_ABS_PATH);
|
||||
auto absPath = get_absolute_path(&absolutePath[0], path);
|
||||
if (!absPath) {
|
||||
std::stringstream ss;
|
||||
ss << "Can't get absolute file path for [" << path << "], err = " << strerror(errno);
|
||||
throw std::runtime_error(ss.str());
|
||||
std::ignore = get_absolute_path(&absolutePath[0], path);
|
||||
if (!absolutePath.empty()) {
|
||||
// on Linux if file does not exist or no access, function will return NULL, but
|
||||
// `absolutePath` will contain resolved path
|
||||
absolutePath.resize(absolutePath.find('\0'));
|
||||
return std::string(absolutePath);
|
||||
}
|
||||
absolutePath.resize(strlen(absPath));
|
||||
return absolutePath;
|
||||
std::stringstream ss;
|
||||
ss << "Can't get absolute file path for [" << path << "], err = " << strerror(errno);
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
|
||||
bool ov::util::is_absolute_file_path(const std::string& path) {
|
||||
if (path.empty())
|
||||
throw std::runtime_error("Provided path is empty");
|
||||
#ifdef _WIN32
|
||||
return !PathIsRelativeA(path.c_str());
|
||||
#else
|
||||
return path[0] == '/';
|
||||
#endif // _WIN32
|
||||
}
|
||||
|
||||
void ov::util::create_directory_recursive(const std::string& path) {
|
||||
|
|
@ -458,6 +471,64 @@ std::wstring ov::util::get_ov_lib_path_w() {
|
|||
|
||||
#endif // OPENVINO_ENABLE_UNICODE_PATH_SUPPORT
|
||||
|
||||
ov::util::FilePath ov::util::get_plugin_path(const std::string& plugin) {
|
||||
// Assume `plugin` may contain:
|
||||
// 1. /path/to/libexample.so absolute path
|
||||
// 2. ../path/to/libexample.so path relative to working directory
|
||||
// 3. example library name - to be converted to 4th case
|
||||
// 4. libexample.so - path relative to working directory (if exists) or file to be found in ENV
|
||||
|
||||
// For 1-2 cases
|
||||
if (plugin.find(FileTraits<char>::file_separator) != std::string::npos)
|
||||
return ov::util::to_file_path(ov::util::get_absolute_file_path(plugin));
|
||||
|
||||
auto lib_name = plugin;
|
||||
// For 3rd case - convert to 4th case
|
||||
if (!ov::util::ends_with(plugin, ov::util::FileTraits<char>::library_ext()))
|
||||
lib_name = ov::util::make_plugin_library_name({}, plugin);
|
||||
|
||||
// For 4th case
|
||||
auto lib_path = ov::util::to_file_path(ov::util::get_absolute_file_path(lib_name));
|
||||
if (ov::util::file_exists(lib_path))
|
||||
return lib_path;
|
||||
return ov::util::to_file_path(lib_name);
|
||||
}
|
||||
|
||||
ov::util::FilePath ov::util::get_plugin_path(const std::string& plugin, const std::string& xml_path, bool as_abs_only) {
|
||||
// Assume `plugin` (from XML "location" record) contains only:
|
||||
// 1. /path/to/libexample.so absolute path
|
||||
// 2. ../path/to/libexample.so path relative to XML directory
|
||||
// 3. example library name - to be converted to 4th case
|
||||
// 4. libexample.so - path relative to XML directory (if exists) or file to be found in ENV
|
||||
// (if `as_abs_only` is false)
|
||||
|
||||
// For 1st case
|
||||
if (ov::util::is_absolute_file_path(plugin))
|
||||
return ov::util::to_file_path(plugin);
|
||||
|
||||
auto xml_path_ = xml_path;
|
||||
if (xml_path.find(ov::util::FileTraits<char>::file_separator) == std::string::npos)
|
||||
xml_path_ = ov::util::path_join({std::string("."), xml_path}); // treat plugins.xml as CWD/plugins.xml
|
||||
|
||||
// For 2nd case
|
||||
if (plugin.find(ov::util::FileTraits<char>::file_separator) != std::string::npos) {
|
||||
auto path_ = ov::util::path_join({ov::util::get_directory(xml_path_), plugin});
|
||||
return ov::util::to_file_path(ov::util::get_absolute_file_path(path_)); // canonicalize path
|
||||
}
|
||||
|
||||
auto lib_file_name = plugin;
|
||||
// For 3rd case - convert to 4th case
|
||||
if (!ov::util::ends_with(plugin, ov::util::FileTraits<char>::library_ext()))
|
||||
lib_file_name = ov::util::make_plugin_library_name({}, plugin);
|
||||
|
||||
// For 4th case
|
||||
auto lib_path = ov::util::path_join({ov::util::get_directory(xml_path_), lib_file_name});
|
||||
lib_path = ov::util::get_absolute_file_path(lib_path); // canonicalize path
|
||||
if (as_abs_only || ov::util::file_exists(lib_path))
|
||||
return ov::util::to_file_path(lib_path);
|
||||
return ov::util::to_file_path(lib_file_name);
|
||||
}
|
||||
|
||||
std::vector<uint8_t> ov::util::load_binary(const std::string& path) {
|
||||
#if defined(OPENVINO_ENABLE_UNICODE_PATH_SUPPORT) && defined(_WIN32)
|
||||
std::wstring widefilename = ov::util::string_to_wstring(path);
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ std::shared_ptr<void> load_shared_object(const char* path) {
|
|||
}};
|
||||
if (!shared_object) {
|
||||
std::stringstream ss;
|
||||
ss << "Cannot load library '" << path;
|
||||
ss << "Cannot load library '" << path << "'";
|
||||
if (auto error = dlerror()) {
|
||||
ss << ": " << error;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -109,49 +109,6 @@ std::string resolve_extension_path(const std::string& path) {
|
|||
return retvalue;
|
||||
}
|
||||
|
||||
ov::util::FilePath getPluginPath(const std::string& pluginName, bool needAddSuffixes = false) {
|
||||
const auto ieLibraryPath = ie::getInferenceEngineLibraryPath();
|
||||
|
||||
auto pluginPath = ov::util::to_file_path(pluginName.c_str());
|
||||
|
||||
// 0. user can provide a full path
|
||||
|
||||
#ifndef _WIN32
|
||||
try {
|
||||
// dlopen works with absolute paths; otherwise searches from LD_LIBRARY_PATH
|
||||
pluginPath = ov::util::to_file_path(ov::util::get_absolute_file_path(pluginName));
|
||||
} catch (const std::runtime_error&) {
|
||||
// failed to resolve absolute path; not critical
|
||||
}
|
||||
#endif // _WIN32
|
||||
|
||||
if (FileUtils::fileExist(pluginPath))
|
||||
return pluginPath;
|
||||
|
||||
// ov::Core::register_plugin(plugin_name, device_name) case
|
||||
if (needAddSuffixes)
|
||||
pluginPath = FileUtils::makePluginLibraryName({}, pluginPath);
|
||||
|
||||
// plugin can be found either:
|
||||
|
||||
// 1. in openvino-X.Y.Z folder relative to libopenvino.so
|
||||
std::ostringstream str;
|
||||
str << "openvino-" << OPENVINO_VERSION_MAJOR << "." << OPENVINO_VERSION_MINOR << "." << OPENVINO_VERSION_PATCH;
|
||||
const auto subFolder = ov::util::to_file_path(str.str());
|
||||
|
||||
ov::util::FilePath absFilePath = FileUtils::makePath(FileUtils::makePath(ieLibraryPath, subFolder), pluginPath);
|
||||
if (FileUtils::fileExist(absFilePath))
|
||||
return absFilePath;
|
||||
|
||||
// 2. in the openvino.so location
|
||||
absFilePath = FileUtils::makePath(ieLibraryPath, pluginPath);
|
||||
if (FileUtils::fileExist(absFilePath))
|
||||
return absFilePath;
|
||||
|
||||
// 3. in LD_LIBRARY_PATH on Linux / PATH on Windows
|
||||
return pluginPath;
|
||||
}
|
||||
|
||||
template <typename T = ie::Parameter>
|
||||
Parsed<T> parseDeviceNameIntoConfig(const std::string& deviceName, const std::map<std::string, T>& config = {}) {
|
||||
auto config_ = config;
|
||||
|
|
@ -571,8 +528,9 @@ public:
|
|||
* @brief Register plugins for devices which are located in .xml configuration file.
|
||||
* @note The function supports UNICODE path
|
||||
* @param xmlConfigFile An .xml configuraion with device / plugin information
|
||||
* @param ByAbsPath A boolean value - register plugins by absolute file path or not
|
||||
*/
|
||||
void RegisterPluginsInRegistry(const std::string& xmlConfigFile) {
|
||||
void RegisterPluginsInRegistry(const std::string& xmlConfigFile, const bool& ByAbsPath = false) {
|
||||
std::lock_guard<std::mutex> lock(get_mutex());
|
||||
|
||||
auto parse_result = ParseXml(xmlConfigFile.c_str());
|
||||
|
|
@ -588,7 +546,8 @@ public:
|
|||
|
||||
FOREACH_CHILD (pluginNode, devicesNode, "plugin") {
|
||||
std::string deviceName = GetStrAttr(pluginNode, "name");
|
||||
ov::util::FilePath pluginPath = getPluginPath(GetStrAttr(pluginNode, "location"));
|
||||
ov::util::FilePath pluginPath =
|
||||
ov::util::get_plugin_path(GetStrAttr(pluginNode, "location"), xmlConfigFile, ByAbsPath);
|
||||
|
||||
if (deviceName.find('.') != std::string::npos) {
|
||||
IE_THROW() << "Device name must not contain dot '.' symbol";
|
||||
|
|
@ -1286,7 +1245,7 @@ public:
|
|||
IE_THROW() << "Device name must not contain dot '.' symbol";
|
||||
}
|
||||
|
||||
PluginDescriptor desc{getPluginPath(pluginName, true)};
|
||||
PluginDescriptor desc{ov::util::get_plugin_path(pluginName)};
|
||||
pluginRegistry[deviceName] = desc;
|
||||
add_mutex(deviceName);
|
||||
}
|
||||
|
|
@ -1665,7 +1624,9 @@ Core::Core(const std::string& xmlConfigFile) {
|
|||
#ifdef OPENVINO_STATIC_LIBRARY
|
||||
_impl->RegisterPluginsInRegistry(::getStaticPluginsRegistry());
|
||||
#else
|
||||
RegisterPlugins(ov::findPluginXML(xmlConfigFile));
|
||||
// If XML is default, load default plugins by absolute paths
|
||||
auto loadByAbsPath = xmlConfigFile.empty();
|
||||
_impl->RegisterPluginsInRegistry(ov::findPluginXML(xmlConfigFile), loadByAbsPath);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -1943,9 +1904,13 @@ Core::Core(const std::string& xmlConfigFile) {
|
|||
_impl = std::make_shared<Impl>();
|
||||
|
||||
#ifdef OPENVINO_STATIC_LIBRARY
|
||||
_impl->RegisterPluginsInRegistry(::getStaticPluginsRegistry());
|
||||
OV_CORE_CALL_STATEMENT(_impl->RegisterPluginsInRegistry(::getStaticPluginsRegistry());)
|
||||
#else
|
||||
register_plugins(findPluginXML(xmlConfigFile));
|
||||
OV_CORE_CALL_STATEMENT({
|
||||
// If XML is default, load default plugins by absolute paths
|
||||
auto loadByAbsPath = xmlConfigFile.empty();
|
||||
_impl->RegisterPluginsInRegistry(findPluginXML(xmlConfigFile), loadByAbsPath);
|
||||
})
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -32,6 +32,8 @@ ov_add_test_target(
|
|||
LINK_LIBRARIES
|
||||
unitTestUtils
|
||||
INCLUDES
|
||||
# for static ie_plugins.hpp
|
||||
"${CMAKE_BINARY_DIR}/src/inference/"
|
||||
LABELS
|
||||
OV
|
||||
)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,129 @@
|
|||
// Copyright (C) 2023 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include "openvino/runtime/core.hpp"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <gmock/gmock-matchers.h>
|
||||
|
||||
#include <fstream>
|
||||
|
||||
#include "common_test_utils/test_assertions.hpp"
|
||||
#include "file_utils.h"
|
||||
#include "openvino/util/file_util.hpp"
|
||||
|
||||
using namespace testing;
|
||||
using namespace ov::util;
|
||||
|
||||
TEST(CoreTests, ThrowOnRegisterPluginTwice) {
|
||||
ov::Core core;
|
||||
core.register_plugin("test_plugin", "TEST_DEVICE");
|
||||
OV_EXPECT_THROW(core.register_plugin("test_plugin", "TEST_DEVICE"),
|
||||
ov::Exception,
|
||||
::testing::HasSubstr("Device with \"TEST_DEVICE\" is already registered in the OpenVINO Runtime"));
|
||||
}
|
||||
|
||||
TEST(CoreTests, NoThrowOnRegisterPluginsTwice) {
|
||||
ov::Core core;
|
||||
|
||||
auto getPluginXml = [&]() -> std::string {
|
||||
std::string pluginsXML = "test_plugins.xml";
|
||||
std::ofstream file(pluginsXML);
|
||||
file << "<ie><plugins><plugin location=\"libtest_plugin.so\" name=\"TEST_DEVICE\"></plugin></plugins></ie>";
|
||||
file.flush();
|
||||
file.close();
|
||||
return pluginsXML;
|
||||
};
|
||||
|
||||
core.register_plugins(getPluginXml());
|
||||
EXPECT_NO_THROW(core.register_plugins(getPluginXml()));
|
||||
}
|
||||
|
||||
TEST(CoreTests_getPluginPath_FromXML, UseAbsPathAsIs) {
|
||||
auto xmlPath = "path_to_plugins.xml";
|
||||
auto libPath = ov::util::get_absolute_file_path("test_name.ext"); // CWD/test_name.ext
|
||||
for (auto asAbsOnly : std::vector<bool>{true, false}) {
|
||||
auto absPath = from_file_path(get_plugin_path(libPath, xmlPath, asAbsOnly));
|
||||
EXPECT_TRUE(is_absolute_file_path(absPath));
|
||||
EXPECT_STREQ(absPath.c_str(), libPath.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
TEST(CoreTests_getPluginPath_FromXML, ConvertRelativePathAsRelativeToXMLDir) {
|
||||
auto xmlPath = "path_to_plugins.xml";
|
||||
auto libPath = FileUtils::makePath(std::string("."), std::string("test_name.ext")); // ./test_name.ext
|
||||
for (auto asAbsOnly : std::vector<bool>{true, false}) {
|
||||
auto absPath = from_file_path(get_plugin_path(libPath, xmlPath, asAbsOnly)); // XMLDIR/test_name.ext
|
||||
EXPECT_TRUE(is_absolute_file_path(absPath));
|
||||
|
||||
auto refPath = ov::util::get_absolute_file_path(libPath);
|
||||
EXPECT_STREQ(absPath.c_str(), refPath.c_str()); // XMLDIR/test_name.ext == CWD/test_name.ext
|
||||
}
|
||||
}
|
||||
|
||||
TEST(CoreTests_getPluginPath_FromXML, ConvertFileNameToAbsPathIfAsAbsOnly) {
|
||||
auto xmlPath = "path_to_plugins.xml";
|
||||
auto name = "test_name.ext"; // test_name.ext
|
||||
auto absPath = from_file_path(get_plugin_path(name, xmlPath, true)); // XMLDIR/libtest_name.ext.so
|
||||
EXPECT_TRUE(is_absolute_file_path(absPath));
|
||||
|
||||
auto libName = FileUtils::makePluginLibraryName({}, std::string(name));
|
||||
auto refPath = ov::util::get_absolute_file_path(libName);
|
||||
EXPECT_STREQ(absPath.c_str(), refPath.c_str()); // XMLDIR/libtest_name.ext.so == CWD/libtest_name.ext.so
|
||||
}
|
||||
|
||||
TEST(CoreTests_getPluginPath_FromXML, UseFileNameIfNotAsAbsOnly) {
|
||||
auto xmlPath = "path_to_plugins.xml";
|
||||
auto name = "test_name.ext"; // test_name.ext
|
||||
auto libName = from_file_path(get_plugin_path(name, xmlPath)); // libtest_name.ext.so
|
||||
auto refName = FileUtils::makePluginLibraryName({}, std::string(name));
|
||||
EXPECT_STREQ(libName.c_str(), refName.c_str());
|
||||
}
|
||||
|
||||
TEST(CoreTests_getPluginPath, UseAbsPathAsIs) {
|
||||
auto libName = FileUtils::makePluginLibraryName({}, std::string("test_name")); // libtest_name.so
|
||||
auto libPath = ov::util::get_absolute_file_path(libName);
|
||||
auto absPath = from_file_path(get_plugin_path(libPath));
|
||||
EXPECT_TRUE(is_absolute_file_path(absPath));
|
||||
EXPECT_STREQ(absPath.c_str(), libPath.c_str());
|
||||
}
|
||||
|
||||
TEST(CoreTests_getPluginPath, RelativePathIsFromWorkDir) {
|
||||
auto libName = FileUtils::makePluginLibraryName(std::string("."), std::string("test_name")); // ./libtest_name.so
|
||||
auto absPath = from_file_path(get_plugin_path(libName));
|
||||
EXPECT_TRUE(is_absolute_file_path(absPath));
|
||||
EXPECT_STREQ(absPath.c_str(), get_absolute_file_path(libName).c_str());
|
||||
}
|
||||
|
||||
class CoreTests_getPluginPath_Class : public ::testing::Test {
|
||||
public:
|
||||
void SetUp() override {
|
||||
std::ofstream file(libPath);
|
||||
file << "not empty";
|
||||
file.flush();
|
||||
file.close();
|
||||
}
|
||||
|
||||
void TearDown() override {
|
||||
std::remove(libPath.c_str());
|
||||
}
|
||||
|
||||
std::string libName = FileUtils::makePluginLibraryName({}, std::string("test_name")); // libtest_name.so
|
||||
std::string libPath = ov::util::get_absolute_file_path(libName); // CWD/libtest_name.so
|
||||
};
|
||||
|
||||
TEST_F(CoreTests_getPluginPath_Class, FileNameIsFromWorkDirIfExists) {
|
||||
auto absPath = from_file_path(get_plugin_path(libName)); // libtest_name.so -> CWD/libtest_name.so
|
||||
EXPECT_TRUE(is_absolute_file_path(absPath));
|
||||
EXPECT_STREQ(absPath.c_str(), get_absolute_file_path(libName).c_str());
|
||||
}
|
||||
|
||||
TEST(CoreTests_getPluginPath, UseFileNameAsIsIfNotExistInWorkDir) {
|
||||
auto libName = "test_name.ext";
|
||||
auto absPath = from_file_path(get_plugin_path(libName)); // libtest_name.ext.so -> libtest_name.ext.so
|
||||
EXPECT_FALSE(is_absolute_file_path(absPath));
|
||||
|
||||
auto refPath = FileUtils::makePluginLibraryName({}, std::string(libName));
|
||||
EXPECT_STREQ(absPath.c_str(), refPath.c_str());
|
||||
}
|
||||
Loading…
Reference in New Issue