openvino/src/plugins/hetero/tests/functional/hetero_tests.cpp

740 lines
32 KiB
C++

// Copyright (C) 2018-2023 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include "hetero_tests.hpp"
#include <memory>
#include <string>
#include "common_test_utils/file_utils.hpp"
#include "ie_plugin_config.hpp"
#include "openvino/core/any.hpp"
#include "openvino/core/except.hpp"
#include "openvino/opsets/opset11.hpp"
#include "openvino/pass/serialize.hpp"
#include "openvino/runtime/exec_model_info.hpp"
#include "openvino/runtime/internal_properties.hpp"
#include "openvino/runtime/iplugin.hpp"
#include "openvino/runtime/iremote_context.hpp"
#include "openvino/runtime/iremote_tensor.hpp"
#include "openvino/runtime/make_tensor.hpp"
#include "openvino/runtime/properties.hpp"
#include "openvino/util/file_util.hpp"
#include "openvino/util/shared_object.hpp"
#include "transformations/rt_info/fused_names_attribute.hpp"
namespace {
std::string get_mock_engine_path() {
std::string mock_engine_name("mock_engine");
return ov::util::make_plugin_library_name(CommonTestUtils::getExecutableDirectory(),
mock_engine_name + IE_BUILD_POSTFIX);
}
template <class T>
std::function<T> make_std_function(const std::shared_ptr<void> so, const std::string& functionName) {
std::function<T> ptr(reinterpret_cast<T*>(ov::util::get_symbol(so, functionName.c_str())));
return ptr;
}
bool support_model(const std::shared_ptr<const ov::Model>& model, const ov::SupportedOpsMap& supported_ops) {
for (const auto& op : model->get_ops()) {
if (supported_ops.find(op->get_friendly_name()) == supported_ops.end())
return false;
}
return true;
}
ov::PropertyName RO_property(const std::string& propertyName) {
return ov::PropertyName(propertyName, ov::PropertyMutability::RO);
};
ov::PropertyName RW_property(const std::string& propertyName) {
return ov::PropertyName(propertyName, ov::PropertyMutability::RW);
};
} // namespace
ov::Tensor ov::hetero::tests::HeteroTests::create_and_fill_tensor(const ov::element::Type& type,
const ov::Shape& shape) {
switch (type) {
case ov::element::Type_t::i64:
return create_tensor<ov::element_type_traits<ov::element::Type_t::i64>::value_type>(type, shape);
default:
break;
}
OPENVINO_THROW("Cannot generate tensor. Unsupported element type.");
}
std::shared_ptr<ov::Model> ov::hetero::tests::HeteroTests::create_model_with_subtract() {
auto param = std::make_shared<ov::opset11::Parameter>(ov::element::i64, ov::Shape{1, 3, 2, 2});
param->set_friendly_name("input");
auto const_value = ov::opset11::Constant::create(ov::element::i64, ov::Shape{1, 1, 1, 1}, {1});
const_value->set_friendly_name("const_val");
auto add = std::make_shared<ov::opset11::Add>(param, const_value);
add->set_friendly_name("add");
auto subtract = std::make_shared<ov::opset11::Subtract>(add, const_value);
subtract->set_friendly_name("sub");
auto result = std::make_shared<ov::opset11::Result>(subtract);
result->set_friendly_name("res");
return std::make_shared<ov::Model>(ov::ResultVector{result}, ov::ParameterVector{param});
}
std::shared_ptr<ov::Model> ov::hetero::tests::HeteroTests::create_model_with_subtract_reshape() {
auto param = std::make_shared<ov::opset11::Parameter>(ov::element::i64, ov::Shape{1, 3, 2, 2});
param->set_friendly_name("input");
auto const_value = ov::opset11::Constant::create(ov::element::i64, ov::Shape{1, 1, 1, 1}, {1});
const_value->set_friendly_name("const_val");
auto add = std::make_shared<ov::opset11::Add>(param, const_value);
add->set_friendly_name("add");
auto subtract = std::make_shared<ov::opset11::Subtract>(add, const_value);
subtract->set_friendly_name("sub");
auto reshape_val = ov::opset11::Constant::create(ov::element::i64, ov::Shape{1}, {-1});
reshape_val->set_friendly_name("reshape_val");
auto reshape = std::make_shared<ov::opset11::Reshape>(subtract, reshape_val, true);
reshape->set_friendly_name("reshape");
auto result = std::make_shared<ov::opset11::Result>(reshape);
result->set_friendly_name("res");
return std::make_shared<ov::Model>(ov::ResultVector{result}, ov::ParameterVector{param});
}
std::shared_ptr<ov::Model> ov::hetero::tests::HeteroTests::create_model_with_subtract_reshape_relu() {
auto param = std::make_shared<ov::opset11::Parameter>(ov::element::i64, ov::Shape{1, 3, 2, 2});
param->set_friendly_name("input");
auto const_value = ov::opset11::Constant::create(ov::element::i64, ov::Shape{1, 1, 1, 1}, {1});
const_value->set_friendly_name("const_val");
auto add = std::make_shared<ov::opset11::Add>(param, const_value);
add->set_friendly_name("add");
auto subtract = std::make_shared<ov::opset11::Subtract>(add, const_value);
subtract->set_friendly_name("sub");
auto reshape_val = ov::opset11::Constant::create(ov::element::i64, ov::Shape{1}, {-1});
reshape_val->set_friendly_name("reshape_val");
auto reshape = std::make_shared<ov::opset11::Reshape>(subtract, reshape_val, true);
reshape->set_friendly_name("reshape");
auto relu = std::make_shared<ov::opset11::Relu>(reshape);
relu->set_friendly_name("relu");
auto result = std::make_shared<ov::opset11::Result>(relu);
result->set_friendly_name("res");
return std::make_shared<ov::Model>(ov::ResultVector{result}, ov::ParameterVector{param});
}
std::shared_ptr<ov::Model> ov::hetero::tests::HeteroTests::create_model_with_reshape() {
auto param = std::make_shared<ov::opset11::Parameter>(ov::element::i64, ov::Shape{1, 3, 2, 2});
param->set_friendly_name("input");
auto const_value = ov::opset11::Constant::create(ov::element::i64, ov::Shape{1, 1, 1, 1}, {1});
const_value->set_friendly_name("const_val");
auto add = std::make_shared<ov::opset11::Add>(param, const_value);
add->set_friendly_name("add");
auto reshape_val = ov::opset11::Constant::create(ov::element::i64, ov::Shape{3}, {1, 3, 4});
reshape_val->set_friendly_name("reshape_val");
auto reshape = std::make_shared<ov::opset11::Reshape>(add, reshape_val, true);
reshape->set_friendly_name("reshape");
auto result = std::make_shared<ov::opset11::Result>(reshape);
result->set_friendly_name("res");
return std::make_shared<ov::Model>(ov::ResultVector{result}, ov::ParameterVector{param});
}
// Mock plugins
class MockCompiledModel : public ov::ICompiledModel {
public:
MockCompiledModel(const std::shared_ptr<const ov::Model>& model,
const std::shared_ptr<const ov::IPlugin>& plugin,
const ov::AnyMap& config)
: ov::ICompiledModel(model, plugin),
m_config(config),
m_model(model),
m_has_context(false) {}
MockCompiledModel(const std::shared_ptr<const ov::Model>& model,
const std::shared_ptr<const ov::IPlugin>& plugin,
const ov::AnyMap& config,
const ov::SoPtr<ov::IRemoteContext>& context)
: ov::ICompiledModel(model, plugin),
m_config(config),
m_model(model),
m_has_context(true),
m_context(context) {}
// Methods from a base class ov::ICompiledModel
void export_model(std::ostream& model) const override {
ov::pass::StreamSerialize(model, std::function<void(std::ostream&)>())
.run_on_model(std::const_pointer_cast<ov::Model>(m_model));
}
std::shared_ptr<const ov::Model> get_runtime_model() const override {
auto model = m_model->clone();
// Add execution information into the model
size_t exec_order = 0;
for (const auto& op : model->get_ordered_ops()) {
auto& info = op->get_rt_info();
info[ov::exec_model_info::EXECUTION_ORDER] = std::to_string(exec_order++);
info[ov::exec_model_info::IMPL_TYPE] = get_plugin()->get_device_name() + "_ " + op->get_type_info().name;
auto perf_count_enabled = get_property(ov::enable_profiling.name()).as<bool>();
info[ov::exec_model_info::PERF_COUNTER] = perf_count_enabled ? "0" : "not_executed";
std::string original_names = ov::getFusedNames(op);
if (original_names.empty()) {
original_names = op->get_friendly_name();
} else if (original_names.find(op->get_friendly_name()) == std::string::npos) {
original_names = op->get_friendly_name() + "," + original_names;
}
info[ov::exec_model_info::ORIGINAL_NAMES] = original_names;
if (op->inputs().size() > 0)
info[ov::exec_model_info::RUNTIME_PRECISION] = op->get_input_element_type(0);
else
info[ov::exec_model_info::RUNTIME_PRECISION] = op->get_output_element_type(0);
std::stringstream precisions_ss;
for (size_t i = 0; i < op->get_output_size(); i++) {
if (i > 0)
precisions_ss << ",";
precisions_ss << op->get_output_element_type(i);
}
info[ov::exec_model_info::OUTPUT_PRECISIONS] = precisions_ss.str();
}
return model;
}
void set_property(const ov::AnyMap& properties) override {
OPENVINO_NOT_IMPLEMENTED;
}
ov::Any get_property(const std::string& name) const override {
if (name == ov::supported_properties) {
const std::vector<ov::PropertyName> supported_properties = {ov::num_streams.name(),
ov::enable_profiling.name()};
return decltype(ov::supported_properties)::value_type(supported_properties);
} else if (name == ov::num_streams) {
if (m_config.count(ov::internal::exclusive_async_requests.name())) {
auto exclusive_async_requests = m_config.at(ov::internal::exclusive_async_requests.name()).as<bool>();
if (exclusive_async_requests)
return ov::streams::Num(1);
}
return m_config.count(ov::num_streams.name()) ? m_config.at(ov::num_streams.name()) : ov::streams::Num(1);
} else if (name == ov::enable_profiling) {
return m_config.count(ov::enable_profiling.name()) ? m_config.at(ov::enable_profiling.name()) : false;
} else {
OPENVINO_THROW("get property: " + name);
}
}
std::shared_ptr<ov::ISyncInferRequest> create_sync_infer_request() const override;
const std::shared_ptr<const ov::Model>& get_model() const {
return m_model;
}
ov::SoPtr<ov::IRemoteContext> get_context() const {
return m_context;
}
bool has_context() const {
return m_has_context;
}
private:
ov::AnyMap m_config;
std::shared_ptr<const ov::Model> m_model;
bool m_has_context;
ov::SoPtr<ov::IRemoteContext> m_context;
};
class MockInferRequest : public ov::ISyncInferRequest {
public:
MockInferRequest(const std::shared_ptr<const MockCompiledModel>& compiled_model)
: ov::ISyncInferRequest(compiled_model) {
OPENVINO_ASSERT(compiled_model);
m_model = compiled_model->get_model();
// Allocate input/output tensors
for (const auto& input : get_inputs()) {
allocate_tensor(input, [this, input, compiled_model](ov::SoPtr<ov::ITensor>& tensor) {
// Can add a check to avoid double work in case of shared tensors
allocate_tensor_impl(tensor,
input.get_element_type(),
input.get_partial_shape().is_dynamic() ? ov::Shape{0} : input.get_shape(),
compiled_model->has_context(),
compiled_model->get_context());
});
}
for (const auto& output : get_outputs()) {
allocate_tensor(output, [this, output, compiled_model](ov::SoPtr<ov::ITensor>& tensor) {
// Can add a check to avoid double work in case of shared tensors
allocate_tensor_impl(tensor,
output.get_element_type(),
output.get_partial_shape().is_dynamic() ? ov::Shape{0} : output.get_shape(),
compiled_model->has_context(),
compiled_model->get_context());
});
}
}
~MockInferRequest() = default;
void infer() override {
ov::TensorVector input_tensors;
for (const auto& input : get_inputs()) {
input_tensors.emplace_back(ov::make_tensor(get_tensor(input)));
}
ov::TensorVector output_tensors;
for (const auto& output : get_outputs()) {
output_tensors.emplace_back(ov::make_tensor(get_tensor(output)));
}
m_model->evaluate(output_tensors, input_tensors);
}
std::vector<ov::SoPtr<ov::IVariableState>> query_state() const override {
OPENVINO_NOT_IMPLEMENTED;
}
std::vector<ov::ProfilingInfo> get_profiling_info() const override {
OPENVINO_NOT_IMPLEMENTED;
}
private:
void allocate_tensor_impl(ov::SoPtr<ov::ITensor>& tensor,
const ov::element::Type& element_type,
const ov::Shape& shape,
bool has_context,
ov::SoPtr<ov::IRemoteContext> context) {
if (!tensor || tensor->get_element_type() != element_type) {
if (has_context) {
tensor = context->create_tensor(element_type, shape, {});
} else {
tensor = ov::SoPtr<ov::ITensor>(ov::make_tensor(element_type, shape), nullptr);
}
} else {
tensor->set_shape(shape);
}
}
std::shared_ptr<const ov::Model> m_model;
};
std::shared_ptr<ov::ISyncInferRequest> MockCompiledModel::create_sync_infer_request() const {
return std::make_shared<MockInferRequest>(std::dynamic_pointer_cast<const MockCompiledModel>(shared_from_this()));
}
class MockRemoteTensor : public ov::IRemoteTensor {
ov::AnyMap m_properties;
std::string m_dev_name;
public:
MockRemoteTensor(const std::string& name, const ov::AnyMap& props) : m_properties(props), m_dev_name(name) {}
const ov::AnyMap& get_properties() const override {
return m_properties;
}
const std::string& get_device_name() const override {
return m_dev_name;
}
void set_shape(ov::Shape shape) override {
OPENVINO_NOT_IMPLEMENTED;
}
const ov::element::Type& get_element_type() const override {
OPENVINO_NOT_IMPLEMENTED;
}
const ov::Shape& get_shape() const override {
OPENVINO_NOT_IMPLEMENTED;
}
const ov::Strides& get_strides() const override {
OPENVINO_NOT_IMPLEMENTED;
}
};
class MockRemoteContext : public ov::IRemoteContext {
ov::AnyMap m_property = {{"IS_DEFAULT", true}};
std::string m_dev_name;
public:
MockRemoteContext(const std::string& dev_name) : m_dev_name(dev_name) {}
const std::string& get_device_name() const override {
return m_dev_name;
}
const ov::AnyMap& get_property() const override {
return m_property;
}
ov::SoPtr<ov::IRemoteTensor> create_tensor(const ov::element::Type& type,
const ov::Shape& shape,
const ov::AnyMap& params = {}) override {
auto remote_tensor = std::make_shared<MockRemoteTensor>(m_dev_name, m_property);
return {remote_tensor, nullptr};
}
};
class MockCustomRemoteContext : public ov::IRemoteContext {
ov::AnyMap m_property = {{"IS_DEFAULT", false}};
std::string m_dev_name;
public:
MockCustomRemoteContext(const std::string& dev_name) : m_dev_name(dev_name) {}
const std::string& get_device_name() const override {
return m_dev_name;
}
const ov::AnyMap& get_property() const override {
return m_property;
}
ov::SoPtr<ov::IRemoteTensor> create_tensor(const ov::element::Type& type,
const ov::Shape& shape,
const ov::AnyMap& params = {}) override {
auto remote_tensor = std::make_shared<MockRemoteTensor>(m_dev_name, m_property);
return {remote_tensor, nullptr};
}
};
class MockPluginBase : public ov::IPlugin {
public:
MockPluginBase(const std::string& name, const std::unordered_set<std::string>& supported_ops)
: m_supported_ops(supported_ops) {
set_device_name(name);
}
virtual const ov::Version& get_const_version() = 0;
std::shared_ptr<ov::ICompiledModel> compile_model(const std::shared_ptr<const ov::Model>& model,
const ov::AnyMap& properties) const override {
OPENVINO_ASSERT(model);
if (!support_model(model, query_model(model, properties)))
OPENVINO_THROW("Unsupported model");
return std::make_shared<MockCompiledModel>(model, shared_from_this(), properties);
}
std::shared_ptr<ov::ICompiledModel> compile_model(const std::string& model_path,
const ov::AnyMap& properties) const override {
OPENVINO_NOT_IMPLEMENTED;
}
std::shared_ptr<ov::ICompiledModel> compile_model(const std::shared_ptr<const ov::Model>& model,
const ov::AnyMap& properties,
const ov::SoPtr<ov::IRemoteContext>& context) const override {
if (!support_model(model, query_model(model, properties)))
OPENVINO_THROW("Unsupported model");
return std::make_shared<MockCompiledModel>(model, shared_from_this(), properties, context);
}
void set_property(const ov::AnyMap& properties) override {
OPENVINO_NOT_IMPLEMENTED;
}
ov::Any get_property(const std::string& name, const ov::AnyMap& arguments) const override {
OPENVINO_NOT_IMPLEMENTED;
}
ov::SoPtr<ov::IRemoteContext> create_context(const ov::AnyMap& remote_properties) const override {
if (remote_properties.find("CUSTOM_CTX") == remote_properties.end())
return std::make_shared<MockRemoteContext>(get_device_name());
return std::make_shared<MockCustomRemoteContext>(get_device_name());
}
ov::SoPtr<ov::IRemoteContext> get_default_context(const ov::AnyMap& remote_properties) const override {
return std::make_shared<MockRemoteContext>(get_device_name());
}
std::shared_ptr<ov::ICompiledModel> import_model(std::istream& model, const ov::AnyMap& properties) const override {
std::string xmlString, xmlInOutString;
ov::Tensor weights;
ov::pass::StreamSerialize::DataHeader hdr = {};
model.read(reinterpret_cast<char*>(&hdr), sizeof hdr);
model.seekg(hdr.custom_data_offset);
xmlInOutString.resize(hdr.custom_data_size);
model.read(const_cast<char*>(xmlInOutString.c_str()), hdr.custom_data_size);
// read blob content
model.seekg(hdr.consts_offset);
if (hdr.consts_size) {
weights = ov::Tensor(ov::element::i8, ov::Shape{hdr.consts_size});
char* data = static_cast<char*>(weights.data());
model.read(data, hdr.consts_size);
}
// read XML content
model.seekg(hdr.model_offset);
xmlString.resize(hdr.model_size);
model.read(const_cast<char*>(xmlString.c_str()), hdr.model_size);
ov::Core core;
auto ov_model = core.read_model(xmlString, weights);
return compile_model(ov_model, properties);
}
std::shared_ptr<ov::ICompiledModel> import_model(std::istream& model,
const ov::SoPtr<ov::IRemoteContext>& context,
const ov::AnyMap& properties) const override {
std::string xmlString, xmlInOutString;
ov::Tensor weights;
ov::pass::StreamSerialize::DataHeader hdr = {};
model.read(reinterpret_cast<char*>(&hdr), sizeof hdr);
model.seekg(hdr.custom_data_offset);
xmlInOutString.resize(hdr.custom_data_size);
model.read(const_cast<char*>(xmlInOutString.c_str()), hdr.custom_data_size);
// read blob content
model.seekg(hdr.consts_offset);
if (hdr.consts_size) {
weights = ov::Tensor(ov::element::i8, ov::Shape{hdr.consts_size});
char* data = static_cast<char*>(weights.data());
model.read(data, hdr.consts_size);
}
// read XML content
model.seekg(hdr.model_offset);
xmlString.resize(hdr.model_size);
model.read(const_cast<char*>(xmlString.c_str()), hdr.model_size);
ov::Core core;
auto ov_model = core.read_model(xmlString, weights);
return compile_model(ov_model, properties, context);
}
ov::SupportedOpsMap query_model(const std::shared_ptr<const ov::Model>& model,
const ov::AnyMap& properties) const override {
OPENVINO_ASSERT(model);
ov::SupportedOpsMap res;
auto device_id = properties.count(ov::device::id.name())
? properties.at(ov::device::id.name()).as<std::string>()
: m_default_device_id;
for (const auto& op : model->get_ordered_ops()) {
if (m_supported_ops.find(op->get_type_info().name) == m_supported_ops.end())
continue;
res[op->get_friendly_name()] = get_device_name() + "." + device_id;
}
return res;
}
protected:
std::string m_default_device_id = "0";
std::unordered_set<std::string> m_supported_ops;
bool m_profiling = false;
bool m_loaded_from_cache{false};
};
class MockPluginReshape : public MockPluginBase {
public:
MockPluginReshape(const std::string& name)
: MockPluginBase(name, {"Parameter", "Result", "Add", "Constant", "Reshape"}) {}
const ov::Version& get_const_version() override {
static const ov::Version version = {CI_BUILD_NUMBER, "openvino_mock_reshape_plugin"};
return version;
}
void set_property(const ov::AnyMap& properties) override {
for (const auto& it : properties) {
if (it.first == ov::num_streams.name())
num_streams = it.second.as<int32_t>();
else if (it.first == ov::enable_profiling.name())
m_profiling = it.second.as<bool>();
else if (it.first == ov::internal::exclusive_async_requests.name())
exclusive_async_requests = it.second.as<bool>();
else if (it.first == ov::device::id.name())
continue;
else
OPENVINO_THROW(get_device_name(), " set config: " + it.first);
}
}
ov::Any get_property(const std::string& name, const ov::AnyMap& arguments) const override {
const static std::vector<std::string> device_ids = {"0", "1", "2"};
const static std::vector<ov::PropertyName> roProperties{
RO_property(ov::supported_properties.name()),
RO_property(ov::available_devices.name()),
RO_property(ov::loaded_from_cache.name()),
RO_property(ov::device::uuid.name()),
RO_property(METRIC_KEY(IMPORT_EXPORT_SUPPORT)),
};
// the whole config is RW before network is loaded.
const static std::vector<ov::PropertyName> rwProperties{
RW_property(ov::num_streams.name()),
RW_property(ov::enable_profiling.name()),
};
std::string device_id;
if (arguments.find(ov::device::id.name()) != arguments.end()) {
device_id = arguments.find(ov::device::id.name())->second.as<std::string>();
}
if (name == ov::supported_properties) {
std::vector<ov::PropertyName> supportedProperties;
supportedProperties.reserve(roProperties.size() + rwProperties.size());
supportedProperties.insert(supportedProperties.end(), roProperties.begin(), roProperties.end());
supportedProperties.insert(supportedProperties.end(), rwProperties.begin(), rwProperties.end());
return decltype(ov::supported_properties)::value_type(supportedProperties);
} else if (name == ov::internal::supported_properties) {
return decltype(ov::internal::supported_properties)::value_type(
{ov::PropertyName{ov::internal::caching_properties.name(), ov::PropertyMutability::RO},
ov::PropertyName{ov::internal::exclusive_async_requests.name(), ov::PropertyMutability::RW}});
} else if (name == ov::internal::exclusive_async_requests) {
return decltype(ov::internal::exclusive_async_requests)::value_type{exclusive_async_requests};
} else if (name == ov::device::uuid) {
ov::device::UUID uuid;
for (size_t i = 0; i < uuid.MAX_UUID_SIZE; i++) {
if (device_id == device_ids[0])
uuid.uuid[i] = static_cast<uint8_t>(i);
else if (device_id == device_ids[1])
uuid.uuid[i] = static_cast<uint8_t>(i * 2);
else if (device_id == device_ids[2])
uuid.uuid[i] = static_cast<uint8_t>(i * 3);
}
return decltype(ov::device::uuid)::value_type{uuid};
} else if (name == ov::available_devices) {
return decltype(ov::available_devices)::value_type(device_ids);
} else if (name == ov::device::capabilities) {
std::vector<std::string> capabilities;
capabilities.push_back(ov::device::capability::EXPORT_IMPORT);
return decltype(ov::device::capabilities)::value_type(capabilities);
} else if (name == "SUPPORTED_CONFIG_KEYS") { // TODO: Remove this key
std::vector<std::string> configs;
for (const auto& property : rwProperties) {
configs.emplace_back(property);
}
return configs;
} else if (METRIC_KEY(IMPORT_EXPORT_SUPPORT) == name) {
return true;
} else if (ov::internal::caching_properties == name) {
std::vector<ov::PropertyName> caching_properties = {ov::device::uuid};
return decltype(ov::internal::caching_properties)::value_type(caching_properties);
} else if (name == "SUPPORTED_METRICS") { // TODO: Remove this key
std::vector<std::string> configs;
for (const auto& property : roProperties) {
configs.emplace_back(property);
}
return configs;
} else if (name == ov::loaded_from_cache.name()) {
return m_loaded_from_cache;
} else if (name == ov::enable_profiling.name()) {
return decltype(ov::enable_profiling)::value_type{m_profiling};
} else if (name == ov::streams::num.name()) {
return decltype(ov::streams::num)::value_type{num_streams};
}
OPENVINO_THROW("Unsupported property: ", name);
}
private:
int32_t num_streams{0};
bool exclusive_async_requests = false;
};
class MockPluginSubtract : public MockPluginBase {
public:
MockPluginSubtract(const std::string& name)
: MockPluginBase(name, {"Parameter", "Result", "Add", "Constant", "Subtract"}) {}
const ov::Version& get_const_version() override {
static const ov::Version version = {CI_BUILD_NUMBER, "openvino_mock_subtract_plugin"};
return version;
}
void set_property(const ov::AnyMap& properties) override {
for (const auto& it : properties) {
if (it.first == ov::enable_profiling.name())
m_profiling = it.second.as<bool>();
else if (it.first == ov::device::id.name())
continue;
else
OPENVINO_THROW(get_device_name(), " set config: " + it.first);
}
}
ov::Any get_property(const std::string& name, const ov::AnyMap& arguments) const override {
const static std::vector<std::string> device_ids = {"0", "1"};
const static std::vector<ov::PropertyName> roProperties{
RO_property(ov::supported_properties.name()),
RO_property(ov::available_devices.name()),
RO_property(ov::loaded_from_cache.name()),
RO_property(ov::device::uuid.name()),
RO_property(METRIC_KEY(IMPORT_EXPORT_SUPPORT)),
};
// the whole config is RW before network is loaded.
const static std::vector<ov::PropertyName> rwProperties{
RW_property(ov::num_streams.name()),
RW_property(ov::enable_profiling.name()),
};
std::string device_id;
if (arguments.find(ov::device::id.name()) != arguments.end()) {
device_id = arguments.find(ov::device::id.name())->second.as<std::string>();
}
if (name == ov::supported_properties) {
std::vector<ov::PropertyName> supportedProperties;
supportedProperties.reserve(roProperties.size() + rwProperties.size());
supportedProperties.insert(supportedProperties.end(), roProperties.begin(), roProperties.end());
supportedProperties.insert(supportedProperties.end(), rwProperties.begin(), rwProperties.end());
return decltype(ov::supported_properties)::value_type(supportedProperties);
} else if (name == ov::internal::supported_properties) {
return decltype(ov::internal::supported_properties)::value_type(
{ov::PropertyName{ov::internal::caching_properties.name(), ov::PropertyMutability::RO}});
} else if (name == ov::device::uuid) {
ov::device::UUID uuid;
for (size_t i = 0; i < uuid.MAX_UUID_SIZE; i++) {
if (device_id == device_ids[0])
uuid.uuid[i] = static_cast<uint8_t>(i * 2);
else if (device_id == device_ids[1])
uuid.uuid[i] = static_cast<uint8_t>(i * 4);
else if (device_id == device_ids[2])
uuid.uuid[i] = static_cast<uint8_t>(i * 5);
}
return decltype(ov::device::uuid)::value_type{uuid};
} else if (name == ov::available_devices) {
return decltype(ov::available_devices)::value_type(device_ids);
} else if (name == ov::device::capabilities) {
std::vector<std::string> capabilities;
capabilities.push_back(ov::device::capability::EXPORT_IMPORT);
return decltype(ov::device::capabilities)::value_type(capabilities);
} else if (name == ov::loaded_from_cache.name()) {
return m_loaded_from_cache;
} else if (name == ov::enable_profiling.name()) {
return decltype(ov::enable_profiling)::value_type{m_profiling};
} else if (name == "SUPPORTED_CONFIG_KEYS") { // TODO: Remove this key
std::vector<std::string> configs;
for (const auto& property : rwProperties) {
configs.emplace_back(property);
}
return configs;
} else if (METRIC_KEY(IMPORT_EXPORT_SUPPORT) == name) {
return true;
} else if (ov::internal::caching_properties == name) {
std::vector<ov::PropertyName> caching_properties = {ov::device::uuid};
return decltype(ov::internal::caching_properties)::value_type(caching_properties);
} else if (name == "SUPPORTED_METRICS") { // TODO: Remove this key
std::vector<std::string> configs;
for (const auto& property : roProperties) {
configs.emplace_back(property);
}
return configs;
}
OPENVINO_THROW("Unsupported property: ", name);
}
};
void ov::hetero::tests::HeteroTests::reg_plugin(std::shared_ptr<ov::IPlugin>& plugin) {
std::string library_path = get_mock_engine_path();
if (!m_so)
m_so = ov::util::load_shared_object(library_path.c_str());
if (auto mock_plugin = std::dynamic_pointer_cast<MockPluginBase>(plugin))
mock_plugin->set_version(mock_plugin->get_const_version());
std::function<void(ov::IPlugin*)> injectProxyEngine = make_std_function<void(ov::IPlugin*)>(m_so, "InjectPlugin");
injectProxyEngine(plugin.get());
core.register_plugin(library_path, plugin->get_device_name());
m_mock_plugins.emplace_back(plugin);
}
template <typename T>
void ov::hetero::tests::HeteroTests::reg_plugin_type(const std::string& device_name) {
auto plugin = std::dynamic_pointer_cast<ov::IPlugin>(std::make_shared<T>(device_name));
reg_plugin(plugin);
}
void ov::hetero::tests::HeteroTests::SetUp() {
if (m_mock_plugins.empty()) {
reg_plugin_type<MockPluginReshape>("MOCK0");
reg_plugin_type<MockPluginSubtract>("MOCK1");
}
}