Remove unsupported plugin from proxy in order to avoid exception catching (#18518)
* Remove unsupported plugin from proxy in order to avoid exception
catching
* Remove from alias for
* Globally remove unavailable devices
* Do not load proxy if no available devices
* Try to fix CI
* Add debug messages
* Avoid two times the same plugin
* Revert "Add debug messages"
This reverts commit 562e36c633.
* Cache hidden devices
* Update if fallback order was changed
* Try to fix CI
* Fixed CoreThreading tests
* Fixed typo
* Try to fix plugin initialization
* Fixed initialization
* Fixed lock
This commit is contained in:
@@ -614,6 +614,14 @@ ov::Plugin ov::CoreImpl::get_plugin(const std::string& pluginName) const {
|
|||||||
initial_config[ov::device::priorities.name()] = it->second;
|
initial_config[ov::device::priorities.name()] = it->second;
|
||||||
}
|
}
|
||||||
plugin.set_property(initial_config);
|
plugin.set_property(initial_config);
|
||||||
|
try {
|
||||||
|
plugin.get_property(ov::available_devices);
|
||||||
|
} catch (const ov::Exception& ex) {
|
||||||
|
OPENVINO_THROW("Failed to create plugin for device ",
|
||||||
|
deviceName,
|
||||||
|
"\nPlease, check your environment\n",
|
||||||
|
ex.what());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
// TODO: remove this block of code once GPU removes support of ov::cache_dir
|
// TODO: remove this block of code once GPU removes support of ov::cache_dir
|
||||||
@@ -664,8 +672,9 @@ ov::Plugin ov::CoreImpl::get_plugin(const std::string& pluginName) const {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
std::lock_guard<std::mutex> g_lock(get_mutex());
|
|
||||||
// add plugin as extension itself
|
// add plugin as extension itself
|
||||||
|
std::lock_guard<std::mutex> g_lock(get_mutex());
|
||||||
|
|
||||||
if (desc.extensionCreateFunc) { // static OpenVINO case
|
if (desc.extensionCreateFunc) { // static OpenVINO case
|
||||||
try {
|
try {
|
||||||
InferenceEngine::IExtensionPtr ext;
|
InferenceEngine::IExtensionPtr ext;
|
||||||
|
|||||||
@@ -146,11 +146,13 @@ void ov::proxy::Plugin::set_property(const ov::AnyMap& properties) {
|
|||||||
// Empty config_name means means global config for all devices
|
// Empty config_name means means global config for all devices
|
||||||
std::string config_name = is_device_in_config(hw_config) ? std::to_string(get_device_from_config(hw_config)) : "";
|
std::string config_name = is_device_in_config(hw_config) ? std::to_string(get_device_from_config(hw_config)) : "";
|
||||||
|
|
||||||
|
bool proxy_config_was_changed = false;
|
||||||
// Parse alias config
|
// Parse alias config
|
||||||
it = hw_config.find(ov::proxy::alias_for.name());
|
it = hw_config.find(ov::proxy::alias_for.name());
|
||||||
bool fill_order = hw_config.find(ov::proxy::device_priorities.name()) == hw_config.end() && m_device_order.empty();
|
bool fill_order = hw_config.find(ov::proxy::device_priorities.name()) == hw_config.end() && m_device_order.empty();
|
||||||
if (it != hw_config.end()) {
|
if (it != hw_config.end()) {
|
||||||
for (auto&& dev : it->second.as<std::vector<std::string>>()) {
|
for (auto&& dev : it->second.as<std::vector<std::string>>()) {
|
||||||
|
proxy_config_was_changed = true;
|
||||||
m_alias_for.emplace(dev);
|
m_alias_for.emplace(dev);
|
||||||
if (fill_order)
|
if (fill_order)
|
||||||
m_device_order.emplace_back(dev);
|
m_device_order.emplace_back(dev);
|
||||||
@@ -160,6 +162,7 @@ void ov::proxy::Plugin::set_property(const ov::AnyMap& properties) {
|
|||||||
// Restore device order
|
// Restore device order
|
||||||
it = hw_config.find(ov::proxy::device_priorities.name());
|
it = hw_config.find(ov::proxy::device_priorities.name());
|
||||||
if (it != hw_config.end()) {
|
if (it != hw_config.end()) {
|
||||||
|
proxy_config_was_changed = true;
|
||||||
m_device_order.clear();
|
m_device_order.clear();
|
||||||
std::vector<std::pair<std::string, size_t>> priority_order;
|
std::vector<std::pair<std::string, size_t>> priority_order;
|
||||||
// Biggest number means minimum priority
|
// Biggest number means minimum priority
|
||||||
@@ -207,6 +210,7 @@ void ov::proxy::Plugin::set_property(const ov::AnyMap& properties) {
|
|||||||
std::lock_guard<std::mutex> lock(m_plugin_mutex);
|
std::lock_guard<std::mutex> lock(m_plugin_mutex);
|
||||||
it = hw_config.find(ov::device::priorities.name());
|
it = hw_config.find(ov::device::priorities.name());
|
||||||
if (it != hw_config.end()) {
|
if (it != hw_config.end()) {
|
||||||
|
proxy_config_was_changed = true;
|
||||||
m_configs[config_name][ov::device::priorities.name()] = it->second;
|
m_configs[config_name][ov::device::priorities.name()] = it->second;
|
||||||
// Main device is needed in case if we don't have alias and would like to be able change fallback order per
|
// Main device is needed in case if we don't have alias and would like to be able change fallback order per
|
||||||
// device
|
// device
|
||||||
@@ -214,12 +218,23 @@ void ov::proxy::Plugin::set_property(const ov::AnyMap& properties) {
|
|||||||
m_alias_for.insert(it->second.as<std::vector<std::string>>()[0]);
|
m_alias_for.insert(it->second.as<std::vector<std::string>>()[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const std::string primary_dev = get_primary_device(get_device_from_config(hw_config));
|
if (proxy_config_was_changed) {
|
||||||
|
// need initialization of hidden devices
|
||||||
|
m_init_devs = false;
|
||||||
|
}
|
||||||
|
|
||||||
// Add fallback priority to detect supported devices in case of HETERO fallback
|
// Add fallback priority to detect supported devices in case of HETERO fallback
|
||||||
auto device_priority = get_internal_property(ov::device::priorities.name(), config_name);
|
auto device_priority = get_internal_property(ov::device::priorities.name(), config_name);
|
||||||
if (!device_priority.empty())
|
if (!device_priority.empty())
|
||||||
hw_config[ov::device::priorities.name()] = device_priority;
|
hw_config[ov::device::priorities.name()] = device_priority;
|
||||||
|
auto dev_id = get_device_from_config(hw_config);
|
||||||
auto dev_properties = remove_proxy_properties(hw_config, true);
|
auto dev_properties = remove_proxy_properties(hw_config, true);
|
||||||
|
|
||||||
|
if (dev_properties.empty() && hw_config.empty())
|
||||||
|
// Nothing to do
|
||||||
|
return;
|
||||||
|
|
||||||
|
const std::string primary_dev = get_primary_device(dev_id);
|
||||||
std::string dev_prop_name;
|
std::string dev_prop_name;
|
||||||
ov::DeviceIDParser pr_parser(primary_dev);
|
ov::DeviceIDParser pr_parser(primary_dev);
|
||||||
for (const auto& it : dev_properties) {
|
for (const auto& it : dev_properties) {
|
||||||
@@ -460,28 +475,49 @@ std::vector<std::vector<std::string>> ov::proxy::Plugin::get_hidden_devices() co
|
|||||||
// Proxy plugin has 2 modes of matching devices:
|
// Proxy plugin has 2 modes of matching devices:
|
||||||
// * Fallback - in this mode we report devices only for the first hidden plugin
|
// * Fallback - in this mode we report devices only for the first hidden plugin
|
||||||
// * Alias - Case when we group all devices under one common name
|
// * Alias - Case when we group all devices under one common name
|
||||||
std::vector<std::vector<std::string>> result;
|
if (m_init_devs)
|
||||||
|
return m_hidden_devices;
|
||||||
|
|
||||||
|
std::lock_guard<std::mutex> lock(m_init_devs_mutex);
|
||||||
|
|
||||||
|
if (m_init_devs)
|
||||||
|
return m_hidden_devices;
|
||||||
|
|
||||||
|
m_hidden_devices.clear();
|
||||||
const auto core = get_core();
|
const auto core = get_core();
|
||||||
OPENVINO_ASSERT(core != nullptr);
|
OPENVINO_ASSERT(core != nullptr);
|
||||||
OPENVINO_ASSERT(!m_alias_for.empty()); // alias_for cannot be empty. 1 is for fallback mode, >1 in other
|
OPENVINO_ASSERT(
|
||||||
|
!m_alias_for.empty(),
|
||||||
|
get_device_name(),
|
||||||
|
" cannot find available devices!"); // alias_for cannot be empty. 1 is for fallback mode, >1 in other
|
||||||
|
|
||||||
// If we have 1 alias we use simple hetero mode
|
// If we have 1 alias we use simple hetero mode
|
||||||
if (m_alias_for.size() == 1) {
|
if (m_alias_for.size() == 1) {
|
||||||
auto device = *m_alias_for.begin();
|
auto device = *m_alias_for.begin();
|
||||||
// Allow to get runtime error, because only one plugin under the alias
|
// Allow to get runtime error, because only one plugin under the alias
|
||||||
const std::vector<std::string> real_devices_ids = core->get_property(device, ov::available_devices);
|
std::vector<std::string> real_devices_ids;
|
||||||
|
try {
|
||||||
|
real_devices_ids = core->get_property(device, ov::available_devices);
|
||||||
|
} catch (const std::runtime_error&) {
|
||||||
|
OPENVINO_THROW(get_device_name(), " cannot find available devices!");
|
||||||
|
}
|
||||||
for (const auto& device_id : real_devices_ids) {
|
for (const auto& device_id : real_devices_ids) {
|
||||||
const std::string full_device_name = device_id.empty() ? device : device + '.' + device_id;
|
const std::string full_device_name = device_id.empty() ? device : device + '.' + device_id;
|
||||||
std::vector<std::string> devices{full_device_name};
|
std::vector<std::string> devices;
|
||||||
|
|
||||||
// Add fallback devices use device_id for individual fallback property
|
// Add fallback devices use device_id for individual fallback property
|
||||||
auto fallback = get_internal_property(ov::device::priorities.name(), device_id).as<std::string>();
|
auto fallback = get_internal_property(ov::device::priorities.name(), device_id).as<std::string>();
|
||||||
if (!fallback.empty()) {
|
if (!fallback.empty()) {
|
||||||
for (const auto& fallback_dev : ov::util::split(fallback, ' ')) {
|
for (const auto& fallback_dev : ov::util::split(fallback, ' ')) {
|
||||||
devices.emplace_back(fallback_dev);
|
if (fallback_dev != device)
|
||||||
|
devices.emplace_back(fallback_dev);
|
||||||
|
else
|
||||||
|
devices.emplace_back(full_device_name);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
devices.emplace_back(full_device_name);
|
||||||
}
|
}
|
||||||
result.emplace_back(devices);
|
m_hidden_devices.emplace_back(devices);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
typedef struct DeviceId {
|
typedef struct DeviceId {
|
||||||
@@ -498,11 +534,13 @@ std::vector<std::vector<std::string>> ov::proxy::Plugin::get_hidden_devices() co
|
|||||||
// 2. Use individual fallback priorities to fill each list
|
// 2. Use individual fallback priorities to fill each list
|
||||||
std::vector<DeviceID_t> all_highlevel_devices;
|
std::vector<DeviceID_t> all_highlevel_devices;
|
||||||
std::set<std::array<uint8_t, ov::device::UUID::MAX_UUID_SIZE>> unique_devices;
|
std::set<std::array<uint8_t, ov::device::UUID::MAX_UUID_SIZE>> unique_devices;
|
||||||
|
std::unordered_set<std::string> unavailable_devices;
|
||||||
for (const auto& device : m_device_order) {
|
for (const auto& device : m_device_order) {
|
||||||
std::vector<std::string> supported_device_ids;
|
std::vector<std::string> supported_device_ids;
|
||||||
try {
|
try {
|
||||||
supported_device_ids = core->get_property(device, ov::available_devices);
|
supported_device_ids = core->get_property(device, ov::available_devices);
|
||||||
} catch (const std::runtime_error&) {
|
} catch (const std::runtime_error&) {
|
||||||
|
unavailable_devices.emplace(device);
|
||||||
// Device cannot be loaded
|
// Device cannot be loaded
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -537,6 +575,10 @@ std::vector<std::vector<std::string>> ov::proxy::Plugin::get_hidden_devices() co
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OPENVINO_ASSERT(!all_highlevel_devices.empty(),
|
||||||
|
get_device_name(),
|
||||||
|
" cannot find available devices!"); // Devices should be found
|
||||||
|
|
||||||
// Use individual fallback order to generate result list
|
// Use individual fallback order to generate result list
|
||||||
for (size_t i = 0; i < all_highlevel_devices.size(); i++) {
|
for (size_t i = 0; i < all_highlevel_devices.size(); i++) {
|
||||||
std::vector<std::string> real_fallback_order;
|
std::vector<std::string> real_fallback_order;
|
||||||
@@ -549,6 +591,8 @@ std::vector<std::vector<std::string>> ov::proxy::Plugin::get_hidden_devices() co
|
|||||||
bool use_hetero_mode = device.no_uuid ? true : false;
|
bool use_hetero_mode = device.no_uuid ? true : false;
|
||||||
std::vector<std::string> device_order;
|
std::vector<std::string> device_order;
|
||||||
for (const auto& fallback_dev : fallback_order) {
|
for (const auto& fallback_dev : fallback_order) {
|
||||||
|
if (unavailable_devices.count(fallback_dev))
|
||||||
|
continue;
|
||||||
if (!found_primary_device) {
|
if (!found_primary_device) {
|
||||||
auto it = device.device_to_full_name.find(fallback_dev);
|
auto it = device.device_to_full_name.find(fallback_dev);
|
||||||
if (it != device.device_to_full_name.end()) {
|
if (it != device.device_to_full_name.end()) {
|
||||||
@@ -567,13 +611,7 @@ std::vector<std::vector<std::string>> ov::proxy::Plugin::get_hidden_devices() co
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// Try to find unique device
|
// Try to find unique device
|
||||||
std::vector<std::string> supported_device_ids;
|
std::vector<std::string> supported_device_ids = core->get_property(fallback_dev, ov::available_devices);
|
||||||
try {
|
|
||||||
supported_device_ids = core->get_property(fallback_dev, ov::available_devices);
|
|
||||||
} catch (const std::runtime_error&) {
|
|
||||||
// Device cannot be loaded, so skipp this device
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
bool found_device = false;
|
bool found_device = false;
|
||||||
bool dev_without_uuid = false;
|
bool dev_without_uuid = false;
|
||||||
for (const auto& device_id : supported_device_ids) {
|
for (const auto& device_id : supported_device_ids) {
|
||||||
@@ -602,7 +640,7 @@ std::vector<std::vector<std::string>> ov::proxy::Plugin::get_hidden_devices() co
|
|||||||
device_order.emplace_back(device.device_to_full_name.begin()->second);
|
device_order.emplace_back(device.device_to_full_name.begin()->second);
|
||||||
real_fallback_order.emplace_back(device.device_to_full_name.begin()->first);
|
real_fallback_order.emplace_back(device.device_to_full_name.begin()->first);
|
||||||
}
|
}
|
||||||
result.emplace_back(device_order);
|
m_hidden_devices.emplace_back(device_order);
|
||||||
std::string new_fallback;
|
std::string new_fallback;
|
||||||
for (const auto& dev : real_fallback_order) {
|
for (const auto& dev : real_fallback_order) {
|
||||||
if (!new_fallback.empty())
|
if (!new_fallback.empty())
|
||||||
@@ -613,7 +651,8 @@ std::vector<std::vector<std::string>> ov::proxy::Plugin::get_hidden_devices() co
|
|||||||
m_configs[std::to_string(i)][ov::device::priorities.name()] = new_fallback;
|
m_configs[std::to_string(i)][ov::device::priorities.name()] = new_fallback;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
m_init_devs = true;
|
||||||
|
return m_hidden_devices;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ov::proxy::Plugin::has_internal_property(const std::string& property, const std::string& config_name) const {
|
bool ov::proxy::Plugin::has_internal_property(const std::string& property, const std::string& config_name) const {
|
||||||
|
|||||||
@@ -51,11 +51,14 @@ private:
|
|||||||
const ov::AnyMap& properties) const;
|
const ov::AnyMap& properties) const;
|
||||||
|
|
||||||
size_t m_default_device = 0;
|
size_t m_default_device = 0;
|
||||||
std::vector<std::string> m_device_order;
|
mutable std::vector<std::string> m_device_order;
|
||||||
std::unordered_set<std::string> m_alias_for;
|
mutable std::unordered_set<std::string> m_alias_for;
|
||||||
// Update per device config in get_hidden_devices
|
// Update per device config in get_hidden_devices
|
||||||
mutable std::unordered_map<std::string, ov::AnyMap> m_configs;
|
mutable std::unordered_map<std::string, ov::AnyMap> m_configs;
|
||||||
mutable std::mutex m_plugin_mutex;
|
mutable std::mutex m_plugin_mutex;
|
||||||
|
mutable std::mutex m_init_devs_mutex;
|
||||||
|
mutable std::vector<std::vector<std::string>> m_hidden_devices;
|
||||||
|
mutable bool m_init_devs{false};
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace proxy
|
} // namespace proxy
|
||||||
|
|||||||
@@ -148,6 +148,72 @@ TEST_F(ProxyTests, get_available_devices_with_low_level_plugin) {
|
|||||||
EXPECT_TRUE(mock_reference_dev.empty());
|
EXPECT_TRUE(mock_reference_dev.empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(ProxyTests, load_proxy_without_several_devices) {
|
||||||
|
ov::AnyMap config;
|
||||||
|
config[ov::proxy::alias_for.name()] = std::vector<std::string>{"Fake1", "Fake2"};
|
||||||
|
config[ov::proxy::device_priorities.name()] = std::vector<std::string>{"Fake1:0", "Fake2:1"};
|
||||||
|
config[ov::device::priorities.name()] = std::vector<std::string>{"Fake1", "Fake2"};
|
||||||
|
// Change device priority
|
||||||
|
core.set_property("MOCK", config);
|
||||||
|
auto available_devices = core.get_available_devices();
|
||||||
|
EXPECT_THROW(core.get_property("MOCK", ov::device::priorities), ov::Exception);
|
||||||
|
std::set<std::string> mock_reference_dev = {"MOCK", "MOCK.0", "MOCK.1", "MOCK.2"};
|
||||||
|
for (const auto& dev : available_devices) {
|
||||||
|
if (mock_reference_dev.find(dev) != mock_reference_dev.end()) {
|
||||||
|
mock_reference_dev.erase(dev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Mock devices shouldn't be found
|
||||||
|
EXPECT_EQ(mock_reference_dev.size(), 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ProxyTests, load_proxy_without_devices) {
|
||||||
|
ov::AnyMap config;
|
||||||
|
config[ov::proxy::alias_for.name()] = "Fake";
|
||||||
|
config[ov::proxy::device_priorities.name()] = "Fake:1";
|
||||||
|
config[ov::device::priorities.name()] = std::vector<std::string>{"Fake"};
|
||||||
|
// Change device priority
|
||||||
|
core.set_property("MOCK", config);
|
||||||
|
auto available_devices = core.get_available_devices();
|
||||||
|
EXPECT_THROW(core.get_property("MOCK", ov::device::priorities), ov::Exception);
|
||||||
|
std::set<std::string> mock_reference_dev = {"MOCK", "MOCK.0", "MOCK.1", "MOCK.2"};
|
||||||
|
for (const auto& dev : available_devices) {
|
||||||
|
if (mock_reference_dev.find(dev) != mock_reference_dev.end()) {
|
||||||
|
mock_reference_dev.erase(dev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Mock devices shouldn't be found
|
||||||
|
EXPECT_EQ(mock_reference_dev.size(), 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ProxyTests, load_proxy_with_unavailable_device) {
|
||||||
|
ov::AnyMap config;
|
||||||
|
config[ov::proxy::alias_for.name()] = std::vector<std::string>{"Fake", "BDE"};
|
||||||
|
config[ov::proxy::device_priorities.name()] = std::vector<std::string>{"Fake:1", "BDE:0"};
|
||||||
|
config[ov::device::priorities.name()] = std::vector<std::string>{"Fake", "BDE"};
|
||||||
|
// Change device priority
|
||||||
|
core.set_property("MOCK", config);
|
||||||
|
auto available_devices = core.get_available_devices();
|
||||||
|
{
|
||||||
|
// We don't change fallback order for hetero case
|
||||||
|
std::unordered_map<std::string, std::string> mock_reference_dev = {{"MOCK.0", "BDE"},
|
||||||
|
{"MOCK.1", "BDE"},
|
||||||
|
{"MOCK.2", "BDE"}};
|
||||||
|
for (const auto& it : mock_reference_dev) {
|
||||||
|
std::cout << it.second << std::endl;
|
||||||
|
EXPECT_EQ(core.get_property(it.first, ov::device::priorities), it.second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::set<std::string> mock_reference_dev = {"MOCK.0", "MOCK.1", "MOCK.2"};
|
||||||
|
for (const auto& dev : available_devices) {
|
||||||
|
if (mock_reference_dev.find(dev) != mock_reference_dev.end()) {
|
||||||
|
mock_reference_dev.erase(dev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// All devices should be found
|
||||||
|
EXPECT_TRUE(mock_reference_dev.empty());
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(ProxyTests, get_available_devices_with_disabled_plugin) {
|
TEST_F(ProxyTests, get_available_devices_with_disabled_plugin) {
|
||||||
ov::AnyMap config;
|
ov::AnyMap config;
|
||||||
config[ov::device::priorities.name()] = "BDE";
|
config[ov::device::priorities.name()] = "BDE";
|
||||||
|
|||||||
Reference in New Issue
Block a user