Files
openvino/inference-engine/src/inference_engine/ie_core.cpp
2021-02-04 08:42:16 +03:00

783 lines
29 KiB
C++

// Copyright (C) 2018-2020 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include <map>
#include <memory>
#include <string>
#include <vector>
#include <istream>
#include <mutex>
#include <ie_core.hpp>
#include <multi-device/multi_device_config.hpp>
#include <ngraph/opsets/opset.hpp>
#include <ngraph/ngraph.hpp>
#include <ngraph/graph_util.hpp>
#include <ngraph/pass/constant_folding.hpp>
#include <cpp_interfaces/exception2status.hpp>
#include "ie_plugin_cpp.hpp"
#include "ie_plugin_config.hpp"
#include "ie_itt.hpp"
#include "file_utils.h"
#include "ie_network_reader.hpp"
#include "xml_parse_utils.h"
using namespace InferenceEngine::PluginConfigParams;
namespace InferenceEngine {
namespace {
template <typename T>
struct Parsed {
std::string _deviceName;
std::map<std::string, T> _config;
};
template <typename T = Parameter>
Parsed<T> parseDeviceNameIntoConfig(const std::string& deviceName, const std::map<std::string, T>& config = {}) {
auto config_ = config;
auto deviceName_ = deviceName;
if (deviceName_.find("HETERO:") == 0) {
deviceName_ = "HETERO";
config_["TARGET_FALLBACK"] = deviceName.substr(7);
} else if (deviceName_.find("MULTI:") == 0) {
deviceName_ = "MULTI";
config_[InferenceEngine::MultiDeviceConfigParams::KEY_MULTI_DEVICE_PRIORITIES] = deviceName.substr(6);
} else {
DeviceIDParser parser(deviceName_);
deviceName_ = parser.getDeviceName();
std::string deviceIDLocal = parser.getDeviceID();
if (!deviceIDLocal.empty()) {
config_[KEY_DEVICE_ID] = deviceIDLocal;
}
}
return {deviceName_, config_};
}
Parameter copyParameterValue(const Parameter & value) {
if (value.is<bool>()) {
return { value.as<bool>() };
} else if (value.is<int>()) {
return { value.as<int>() };
} else if (value.is<unsigned int>()) {
return { value.as<unsigned int>() };
} else if (value.is<float>()) {
return { value.as<float>() };
} else if (value.is<std::string>()) {
return { value.as<std::string>() };
} else if (value.is<std::vector<std::string> >()) {
return { value.as<std::vector<std::string> >() };
} else if (value.is<std::vector<int> >()) {
return { value.as<std::vector<int> >() };
} else if (value.is<std::vector<float> >()) {
return { value.as<std::vector<float> >() };
} else if (value.is<std::vector<unsigned int> >()) {
return { value.as<std::vector<unsigned int> >() };
} else if (value.is<std::tuple<unsigned int, unsigned int, unsigned int> >()) {
return { value.as<std::tuple<unsigned int, unsigned int, unsigned int> >() };
} else if (value.is<std::tuple<unsigned int, unsigned int> >()) {
return { value.as<std::tuple<unsigned int, unsigned int> >() };
}
return std::move(value);
}
template <typename F>
void allowNotImplemented(F && f) {
try {
f();
} catch (const NotImplemented & ex) { }
}
} // namespace
DeviceIDParser::DeviceIDParser(const std::string& deviceNameWithID) {
deviceName = deviceNameWithID;
auto pos = deviceName.find('.');
if (pos != std::string::npos) {
deviceName = deviceNameWithID.substr(0, pos);
deviceID = deviceNameWithID.substr(pos + 1, deviceNameWithID.size());
}
}
std::string DeviceIDParser::getDeviceID() const {
return deviceID;
}
std::string DeviceIDParser::getDeviceName() const {
return deviceName;
}
std::vector<std::string> DeviceIDParser::getHeteroDevices(std::string fallbackDevice) {
std::vector<std::string> deviceNames;
std::string cdevice;
char delimiter = ',';
size_t pos = 0;
while ((pos = fallbackDevice.find(delimiter)) != std::string::npos) {
deviceNames.push_back(fallbackDevice.substr(0, pos));
fallbackDevice.erase(0, pos + 1);
}
if (!fallbackDevice.empty()) deviceNames.push_back(fallbackDevice);
return deviceNames;
}
std::vector<std::string> DeviceIDParser::getMultiDevices(std::string devicesList) {
std::vector<std::string> deviceNames;
auto trim_request_info = [](std::string device_with_requests) {
auto opening_bracket = device_with_requests.find_first_of('(');
return device_with_requests.substr(0, opening_bracket);
};
std::string device;
char delimiter = ',';
size_t pos = 0;
// in addition to the list of devices, every device can have a #requests in the brackets e.g. "CPU(100)"
// we skip the #requests info here
while ((pos = devicesList.find(delimiter)) != std::string::npos) {
auto d = devicesList.substr(0, pos);
deviceNames.push_back(trim_request_info(d));
devicesList.erase(0, pos + 1);
}
if (!devicesList.empty()) deviceNames.push_back(trim_request_info(devicesList));
return deviceNames;
}
class Core::Impl : public ICore {
// Fields are ordered by deletion order
ITaskExecutor::Ptr _taskExecutor = nullptr;
mutable std::map<std::string, InferencePlugin> plugins;
struct PluginDescriptor {
FileUtils::FilePath libraryLocation;
std::map<std::string, std::string> defaultConfig;
std::vector<FileUtils::FilePath> listOfExtentions;
};
std::unordered_set<std::string> opsetNames;
std::vector<IExtensionPtr> extensions;
std::map<std::string, PluginDescriptor> pluginRegistry;
mutable std::mutex pluginsMutex; // to lock parallel access to pluginRegistry and plugins
public:
Impl();
~Impl() override;
/**
* @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) {
std::lock_guard<std::mutex> lock(pluginsMutex);
auto parse_result = ParseXml(xmlConfigFile.c_str());
if (!parse_result.error_msg.empty()) {
THROW_IE_EXCEPTION << parse_result.error_msg;
}
pugi::xml_document& xmlDoc = *parse_result.xml;
using namespace XMLParseUtils;
pugi::xml_node ieNode = xmlDoc.document_element();
pugi::xml_node devicesNode = ieNode.child("plugins");
FOREACH_CHILD(pluginNode, devicesNode, "plugin") {
std::string deviceName = GetStrAttr(pluginNode, "name");
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";
}
// append IR library path for default IE plugins
{
FileUtils::FilePath absFilePath = FileUtils::makePath(getInferenceEngineLibraryPath(), pluginPath);
if (FileUtils::fileExist(absFilePath)) pluginPath = absFilePath;
}
// check properties
auto propertiesNode = pluginNode.child("properties");
std::map<std::string, std::string> config;
if (propertiesNode) {
FOREACH_CHILD(propertyNode, propertiesNode, "property") {
std::string key = GetStrAttr(propertyNode, "key");
std::string value = GetStrAttr(propertyNode, "value");
config[key] = value;
}
}
// check extensions
auto extensionsNode = pluginNode.child("extensions");
std::vector<FileUtils::FilePath> listOfExtentions;
if (extensionsNode) {
FOREACH_CHILD(extensionNode, extensionsNode, "extension") {
FileUtils::FilePath extensionLocation = FileUtils::toFilePath(GetStrAttr(extensionNode, "location").c_str());
listOfExtentions.push_back(extensionLocation);
}
}
// fill value in plugin registry for later lazy initialization
{
PluginDescriptor desc = {pluginPath, config, listOfExtentions};
pluginRegistry[deviceName] = desc;
}
}
}
//
// ICore public API
//
/**
* @brief Returns global task executor
* @return Reference to task executor
*/
ITaskExecutor::Ptr GetTaskExecutor() const override {
return _taskExecutor;
}
CNNNetwork ReadNetwork(const std::string& modelPath, const std::string& binPath) const override {
OV_ITT_SCOPED_TASK(itt::domains::IE);
return details::ReadNetwork(modelPath, binPath, extensions);
}
CNNNetwork ReadNetwork(const std::string& model, const Blob::CPtr& weights) const override {
OV_ITT_SCOPED_TASK(itt::domains::IE, "Core::Impl::ReadNetwork");
return details::ReadNetwork(model, weights, extensions);
}
ExecutableNetwork LoadNetwork(const CNNNetwork& network, const std::string& deviceName,
const std::map<std::string, std::string>& config) override {
OV_ITT_SCOPED_TASK(itt::domains::IE, "Core::Impl::LoadNetwork");
auto parsed = parseDeviceNameIntoConfig(deviceName, config);
return GetCPPPluginByName(parsed._deviceName).LoadNetwork(network, parsed._config);
}
ExecutableNetwork ImportNetwork(std::istream& networkModel, const std::string& deviceName,
const std::map<std::string, std::string>& config) override {
auto parsed = parseDeviceNameIntoConfig(deviceName, config);
if (parsed._deviceName.empty()) {
ExportMagic magic = {};
auto currentPos = networkModel.tellg();
networkModel.read(magic.data(), magic.size());
auto exportedWithName = (exportMagic == magic);
if (exportedWithName) {
std::getline(networkModel, parsed._deviceName);
}
networkModel.seekg(currentPos, networkModel.beg);
}
return GetCPPPluginByName(parsed._deviceName).ImportNetwork(networkModel, parsed._config);
}
QueryNetworkResult QueryNetwork(const CNNNetwork& network, const std::string& deviceName,
const std::map<std::string, std::string>& config) const override {
auto parsed = parseDeviceNameIntoConfig(deviceName, config);
return GetCPPPluginByName(parsed._deviceName).QueryNetwork(network, parsed._config);
}
Parameter GetMetric(const std::string& deviceName, const std::string& name) const override {
// HETERO case
{
if (deviceName.find("HETERO:") == 0) {
THROW_IE_EXCEPTION
<< "You can get specific metrics with the GetMetric only for the HETERO itself (without devices). "
"To get individual devices's metrics call GetMetric for each device separately";
}
}
// MULTI case
{
if (deviceName.find("MULTI:") == 0) {
THROW_IE_EXCEPTION
<< "You can get specific metrics with the GetMetric only for the MULTI itself (without devices). "
"To get individual devices's metrics call GetMetric for each device separately";
}
}
auto parsed = parseDeviceNameIntoConfig(deviceName);
// we need to return a copy of Parameter object which is created on Core side,
// not in InferenceEngine plugin side, which can be unloaded from Core in a parallel thread
// TODO: remove this WA after *-31417 is resolved
return copyParameterValue(GetCPPPluginByName(parsed._deviceName).GetMetric(name, parsed._config));
}
/**
* @deprecated
* @brief Returns reference to CPP plugin wrapper by a device name
* @param deviceName A name of device
* @return Reference to a CPP plugin wrapper
*/
InferencePlugin GetCPPPluginByName(const std::string& deviceName) const {
OV_ITT_SCOPED_TASK(itt::domains::IE_LT, "Core::Impl::GetCPPPluginByName");
std::lock_guard<std::mutex> lock(pluginsMutex);
auto it = pluginRegistry.find(deviceName);
if (it == pluginRegistry.end()) {
THROW_IE_EXCEPTION << "Device with \"" << deviceName << "\" name is not registered in the InferenceEngine";
}
// Plugin is in registry, but not created, let's create
if (plugins.find(deviceName) == plugins.end()) {
PluginDescriptor desc = it->second;
try {
InferencePlugin plugin(desc.libraryLocation);
{
plugin.SetName(deviceName);
// Set Inference Engine class reference to plugins
ICore* mutableCore = const_cast<ICore*>(static_cast<const ICore*>(this));
plugin.SetCore(mutableCore);
}
// Add registered extensions to new plugin
allowNotImplemented([&](){
for (const auto& ext : extensions) {
plugin.AddExtension(ext);
}
});
// configuring
{
allowNotImplemented([&]() {
plugin.SetConfig(desc.defaultConfig);
});
allowNotImplemented([&]() {
for (auto&& extensionLocation : desc.listOfExtentions) {
plugin.AddExtension(make_so_pointer<IExtension>(extensionLocation));
}
});
}
plugins[deviceName] = plugin;
} 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";
}
}
return plugins[deviceName];
}
/**
* @brief Unload plugin for specified device, but plugin meta-data is still in plugin registry
* @param deviceName A name of device
*/
void UnloadPluginByName(const std::string& deviceName) {
std::lock_guard<std::mutex> lock(pluginsMutex);
auto it = plugins.find(deviceName);
if (it == plugins.end()) {
THROW_IE_EXCEPTION << "Device with \"" << deviceName << "\" name is not registered in the InferenceEngine";
}
plugins.erase(deviceName);
}
/**
* @brief Registers plugin meta-data in registry for specified device
* @param deviceName A name of device
*/
void RegisterPluginByName(const std::string& pluginName, const std::string& deviceName) {
std::lock_guard<std::mutex> lock(pluginsMutex);
auto it = pluginRegistry.find(deviceName);
if (it != pluginRegistry.end()) {
THROW_IE_EXCEPTION << "Device with \"" << deviceName << "\" is already registered in the InferenceEngine";
}
if (deviceName.find('.') != std::string::npos) {
THROW_IE_EXCEPTION << "Device name must not contain dot '.' symbol";
}
// append IR library path for default IE plugins
FileUtils::FilePath pluginPath;
{
pluginPath = FileUtils::makePluginLibraryName({}, FileUtils::toFilePath(pluginName.c_str()));
FileUtils::FilePath absFilePath = FileUtils::makePath(getInferenceEngineLibraryPath(), pluginPath);
if (FileUtils::fileExist(absFilePath)) pluginPath = absFilePath;
}
PluginDescriptor desc = {pluginPath, {}, {}};
pluginRegistry[deviceName] = desc;
}
/**
* @brief Porvides a list of plugin names in registry; physically such plugins may not be created
* @return A list of plugin names
*/
std::vector<std::string> GetListOfDevicesInRegistry() const {
std::lock_guard<std::mutex> lock(pluginsMutex);
std::vector<std::string> listOfDevices;
for (auto&& pluginDesc : pluginRegistry) {
listOfDevices.push_back(pluginDesc.first);
}
return listOfDevices;
}
/**
* @brief Sets config values for a plugin or set of plugins
* @param deviceName A device name to set config to
* If empty, config is set for all the plugins / plugin's meta-data
*/
void SetConfigForPlugins(const std::map<std::string, std::string>& config, const std::string& deviceName) {
std::lock_guard<std::mutex> lock(pluginsMutex);
// set config for plugins in registry
bool configIsSet = false;
for (auto& desc : pluginRegistry) {
if (deviceName.empty() || deviceName == desc.first) {
for (auto&& conf : config) {
desc.second.defaultConfig[conf.first] = conf.second;
}
configIsSet = true;
}
}
if (!configIsSet && !deviceName.empty()) {
THROW_IE_EXCEPTION << "Device with \"" << deviceName << "\" name is not registered in the InferenceEngine";
}
// set config for already created plugins
for (auto& plugin : plugins) {
if (deviceName.empty() || deviceName == plugin.first) {
allowNotImplemented([&]() {
plugin.second.SetConfig(config);
});
}
}
}
/**
* @brief Registers the extension in a Core object
* Such extensions can be used for both CNNNetwork readers and device plugins
*/
void AddExtension(const IExtensionPtr& extension) {
std::lock_guard<std::mutex> lock(pluginsMutex);
std::map<std::string, ngraph::OpSet> opsets = extension->getOpSets();
for (const auto& it : opsets) {
if (opsetNames.find(it.first) != opsetNames.end())
THROW_IE_EXCEPTION << "Cannot add opset with name: " << it.first << ". Opset with the same name already exists.";
opsetNames.insert(it.first);
}
// add extensions for already created plugins
for (auto& plugin : plugins) {
try {
plugin.second.AddExtension(extension);
} catch (...) {}
}
extensions.emplace_back(extension);
}
/**
* @brief Provides a list of extensions
* @return A list of registered extensions
*/
const std::vector<IExtensionPtr>& GetExtensions() const {
return extensions;
}
};
Core::Impl::Impl() {
opsetNames.insert("opset1");
opsetNames.insert("opset2");
opsetNames.insert("opset3");
opsetNames.insert("opset4");
}
Core::Impl::~Impl() {}
Core::Core(const std::string& xmlConfigFile) {
_impl = std::make_shared<Impl>();
std::string xmlConfigFile_ = xmlConfigFile;
if (xmlConfigFile_.empty()) {
// register plugins from default plugins.xml config
FileUtils::FilePath xmlConfigFileDefault = FileUtils::makePath(getInferenceEngineLibraryPath(), FileUtils::toFilePath("plugins.xml"));
xmlConfigFile_ = FileUtils::fromFilePath(xmlConfigFileDefault);
}
RegisterPlugins(xmlConfigFile_);
}
std::map<std::string, Version> Core::GetVersions(const std::string& deviceName) const {
std::map<std::string, Version> versions;
std::vector<std::string> deviceNames;
{
// for compatibility with samples / demo
if (deviceName.find("HETERO") == 0) {
auto pos = deviceName.find_first_of(":");
if (pos != std::string::npos) {
deviceNames = DeviceIDParser::getHeteroDevices(deviceName.substr(pos + 1));
}
deviceNames.push_back("HETERO");
} else if (deviceName.find("MULTI") == 0) {
auto pos = deviceName.find_first_of(":");
if (pos != std::string::npos) {
deviceNames = DeviceIDParser::getMultiDevices(deviceName.substr(pos + 1));
}
deviceNames.push_back("MULTI");
} else {
deviceNames.push_back(deviceName);
}
}
for (auto&& deviceName_ : deviceNames) {
DeviceIDParser parser(deviceName_);
std::string deviceNameLocal = parser.getDeviceName();
InferenceEngine::InferencePlugin cppPlugin = _impl->GetCPPPluginByName(deviceNameLocal);
const Version version = cppPlugin.GetVersion();
versions[deviceNameLocal] = version;
}
return versions;
}
#ifdef ENABLE_UNICODE_PATH_SUPPORT
CNNNetwork Core::ReadNetwork(const std::wstring& modelPath, const std::wstring& binPath) const {
return ReadNetwork(FileUtils::wStringtoMBCSstringChar(modelPath),
FileUtils::wStringtoMBCSstringChar(binPath));
}
#endif
CNNNetwork Core::ReadNetwork(const std::string& modelPath, const std::string& binPath) const {
return _impl->ReadNetwork(modelPath, binPath);
}
CNNNetwork Core::ReadNetwork(const std::string& model, const Blob::CPtr& weights) const {
return _impl->ReadNetwork(model, weights);
}
ExecutableNetwork Core::LoadNetwork(const CNNNetwork& network, const std::string& deviceName,
const std::map<std::string, std::string>& config) {
return _impl->LoadNetwork(network, deviceName, config);
}
void Core::AddExtension(const IExtensionPtr& extension) {
_impl->AddExtension(extension);
}
ExecutableNetwork Core::LoadNetwork(const CNNNetwork& network, RemoteContext::Ptr context,
const std::map<std::string, std::string>& config) {
OV_ITT_SCOPED_TASK(itt::domains::IE, "Core::LoadNetwork");
if (context == nullptr) {
THROW_IE_EXCEPTION << "Remote context is null";
}
auto parsed = parseDeviceNameIntoConfig(context->getDeviceName(), config);
return _impl->GetCPPPluginByName(parsed._deviceName).LoadNetwork(network, parsed._config, context);
}
RemoteContext::Ptr Core::CreateContext(const std::string& deviceName, const ParamMap& params) {
if (deviceName.find("HETERO") == 0) {
THROW_IE_EXCEPTION << "HETERO device does not support remote context";
}
if (deviceName.find("MULTI") == 0) {
THROW_IE_EXCEPTION << "MULTI device does not support remote context";
}
auto parsed = parseDeviceNameIntoConfig(deviceName, params);
return _impl->GetCPPPluginByName(parsed._deviceName).CreateContext(parsed._config);
}
RemoteContext::Ptr Core::GetDefaultContext(const std::string& deviceName) {
if (deviceName.find("HETERO") == 0) {
THROW_IE_EXCEPTION << "HETERO device does not support remote context";
}
if (deviceName.find("MULTI") == 0) {
THROW_IE_EXCEPTION << "MULTI device does not support remote context";
}
auto parsed = parseDeviceNameIntoConfig(deviceName, ParamMap());
return _impl->GetCPPPluginByName(parsed._deviceName).GetDefaultContext(parsed._config);
}
void Core::AddExtension(IExtensionPtr extension, const std::string& deviceName_) {
if (deviceName_.find("HETERO") == 0) {
THROW_IE_EXCEPTION
<< "HETERO device does not support extensions. Please, set extensions directly to fallback devices";
}
if (deviceName_.find("MULTI") == 0) {
THROW_IE_EXCEPTION
<< "MULTI device does not support extensions. Please, set extensions directly to fallback devices";
}
_impl->AddExtension(extension);
}
ExecutableNetwork Core::ImportNetwork(const std::string& modelFileName, const std::string& deviceName,
const std::map<std::string, std::string>& config) {
if (deviceName.find("HETERO") == 0) {
THROW_IE_EXCEPTION << "HETERO device does not support ImportNetwork";
}
if (deviceName.find("MULTI") == 0) {
THROW_IE_EXCEPTION << "MULTI device does not support ImportNetwork";
}
auto parsed = parseDeviceNameIntoConfig(deviceName, config);
return _impl->GetCPPPluginByName(parsed._deviceName).ImportNetwork(modelFileName, parsed._config);
}
ExecutableNetwork Core::ImportNetwork(std::istream& networkModel, const std::string& deviceName,
const std::map<std::string, std::string>& config) {
return _impl->ImportNetwork(networkModel, deviceName, config);
}
ExecutableNetwork Core::ImportNetwork(std::istream& networkModel,
const RemoteContext::Ptr& context,
const std::map<std::string, std::string>& config) {
OV_ITT_SCOPED_TASK(itt::domains::IE, "Core::ImportNetwork");
if (context == nullptr) {
THROW_IE_EXCEPTION << "Remote context is null";
}
std::string deviceName_ = context->getDeviceName();
DeviceIDParser device(deviceName_);
std::string deviceName = device.getDeviceName();
auto parsed = parseDeviceNameIntoConfig(deviceName, config);
return _impl->GetCPPPluginByName(deviceName).ImportNetwork(networkModel, context, parsed._config);
}
QueryNetworkResult Core::QueryNetwork(const CNNNetwork& network, const std::string& deviceName,
const std::map<std::string, std::string>& config) const {
return _impl->QueryNetwork(network, deviceName, config);
}
void Core::SetConfig(const std::map<std::string, std::string>& config, const std::string& deviceName) {
// HETERO case
{
if (deviceName.find("HETERO:") == 0) {
THROW_IE_EXCEPTION << "SetConfig is supported only for HETERO itself (without devices). "
"You can configure the devices with SetConfig before creating the HETERO on top.";
}
}
// MULTI case
{
if (deviceName.find("MULTI:") == 0) {
THROW_IE_EXCEPTION << "SetConfig is supported only for MULTI itself (without devices). "
"You can configure the devices with SetConfig before creating the MULTI on top.";
}
}
if (deviceName.empty()) {
_impl->SetConfigForPlugins(config, std::string());
} else {
auto parsed = parseDeviceNameIntoConfig(deviceName, config);
_impl->SetConfigForPlugins(parsed._config, parsed._deviceName);
}
}
Parameter Core::GetConfig(const std::string& deviceName, const std::string& name) const {
// HETERO case
{
if (deviceName.find("HETERO:") == 0) {
THROW_IE_EXCEPTION
<< "You can only GetConfig of the HETERO itself (without devices). "
"GetConfig is also possible for the individual devices before creating the HETERO on top.";
}
}
// MULTI case
{
if (deviceName.find("MULTI:") == 0) {
THROW_IE_EXCEPTION
<< "You can only GetConfig of the MULTI itself (without devices). "
"GetConfig is also possible for the individual devices before creating the MULTI on top.";
}
}
auto parsed = parseDeviceNameIntoConfig(deviceName);
// we need to return a copy of Parameter object which is created on Core side,
// not in InferenceEngine plugin side, which can be unloaded from Core in a parallel thread
// TODO: remove this WA after *-31417 is resolved
return copyParameterValue(_impl->GetCPPPluginByName(parsed._deviceName).GetConfig(name, parsed._config));
}
Parameter Core::GetMetric(const std::string& deviceName, const std::string& name) const {
return _impl->GetMetric(deviceName, name);
}
std::vector<std::string> Core::GetAvailableDevices() const {
std::vector<std::string> devices;
std::string propertyName = METRIC_KEY(AVAILABLE_DEVICES);
for (auto&& deviceName : _impl->GetListOfDevicesInRegistry()) {
std::vector<std::string> devicesIDs;
try {
Parameter p = GetMetric(deviceName, propertyName);
devicesIDs = p.as<std::vector<std::string>>();
} catch (details::InferenceEngineException&) {
// plugin is not created by e.g. invalid env
} catch (const std::exception& ex) {
THROW_IE_EXCEPTION << "An exception is thrown while trying to create the " << deviceName
<< " device and call GetMetric: " << ex.what();
} catch (...) {
THROW_IE_EXCEPTION << "Unknown exception is thrown while trying to create the " << deviceName
<< " device and call GetMetric";
}
if (devicesIDs.size() > 1) {
for (auto&& deviceID : devicesIDs) {
devices.push_back(deviceName + '.' + deviceID);
}
} else if (!devicesIDs.empty()) {
devices.push_back(deviceName);
}
}
return devices;
}
void Core::RegisterPlugin(const std::string& pluginName, const std::string& deviceName) {
_impl->RegisterPluginByName(pluginName, deviceName);
}
void Core::RegisterPlugins(const std::string& xmlConfigFile) {
_impl->RegisterPluginsInRegistry(xmlConfigFile);
}
void Core::UnregisterPlugin(const std::string& deviceName_) {
DeviceIDParser parser(deviceName_);
std::string deviceName = parser.getDeviceName();
_impl->UnloadPluginByName(deviceName);
}
} // namespace InferenceEngine