Merge pull request #22957 from dkurt:new_openvino_api

Switch to new OpenVINO API after 2022.1 release

* Pass Layer_Test_Convolution_DLDT.Accuracy/0 test

* Pass test Test_Caffe_layers.Softmax

* Failed 136 tests

* Fix Concat. Failed 120 tests

* Custom nGraph ops. 19 failed tests

* Set and get properties from Core

* Read model from buffer

* Change MaxPooling layer output names. Restore reshape

* Cosmetic changes

* Cosmetic changes

* Override getOutputsInfo

* Fixes for OpenVINO < 2022.1

* Async inference for 2021.4 and less

* Compile model with config

* Fix serialize for 2022.1

* Asynchronous inference with 2022.1

* Handle 1d outputs

* Work with model with dynamic output shape

* Fixes with 1d output for old API

* Control outputs by nGraph function for all OpenVINO versions

* Refer inputs in PrePostProcessor by indices

* Fix cycled dependency between InfEngineNgraphNode and InfEngineNgraphNet.
Add InferRequest callback only for async inference. Do not capture InferRequest object.

* Fix tests thresholds

* Fix HETERO:GPU,CPU plugin issues with unsupported layer
This commit is contained in:
Dmitry Kurtaev 2022-12-23 19:58:41 +03:00 committed by GitHub
parent 9012e6dd9b
commit 8681686d8f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 571 additions and 205 deletions

View File

@ -35,6 +35,7 @@ static bool DNN_IE_SERIALIZE = utils::getConfigurationParameterBool("OPENCV_DNN_
static std::string kDefaultInpLayerName = "opencv_ngraph_empty_inp_layer_name";
static constexpr const char* kOpenCVLayersType = "opencv_ngraph_layer";
#if INF_ENGINE_VER_MAJOR_LT(INF_ENGINE_RELEASE_2022_1)
static std::string shapesToStr(const std::vector<Mat>& mats)
{
std::ostringstream shapes;
@ -62,6 +63,7 @@ static void strToShapes(const std::string& str, std::vector<std::vector<size_t>
ss >> shapes[i][j];
}
}
#endif // OpenVINO < 2022.1
static std::vector<Ptr<NgraphBackendWrapper> >
ngraphWrappers(const std::vector<Ptr<BackendWrapper> >& ptrs)
@ -76,6 +78,61 @@ ngraphWrappers(const std::vector<Ptr<BackendWrapper> >& ptrs)
return wrappers;
}
#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2022_1)
class NgraphCustomOp: public ov::op::Op {
public:
OPENVINO_OP(kOpenCVLayersType);
NgraphCustomOp(const ngraph::OutputVector& inputs, Ptr<Layer>& cvLayer, const std::vector<Mat>& outputs, const std::vector<Mat>& internals):
Op(inputs), cvLayer(cvLayer), outputs(outputs), internals(internals)
{
constructor_validate_and_infer_types();
}
void validate_and_infer_types() override
{
set_output_size(outputs.size());
for (int i = 0; i < outputs.size(); ++i)
{
ov::PartialShape shape;
for (int j = 0; j < outputs[i].dims; ++j) {
shape.push_back(outputs[i].size[j]);
}
set_output_type(i, get_input_element_type(0), shape);
}
}
std::shared_ptr<ngraph::Node> clone_with_new_inputs(const ngraph::OutputVector& new_args) const override
{
return std::make_shared<NgraphCustomOp>(new_args, cvLayer, outputs, internals);
}
bool has_evaluate() const {
return true;
}
bool evaluate(ov::TensorVector& outputs, const ov::TensorVector& inputs) const override {
std::vector<Mat> inpMats, outMats;
infEngineBlobsToMats(inputs, inpMats);
infEngineBlobsToMats(outputs, outMats);
try
{
cvLayer->forward(inpMats, outMats, internals);
return true;
}
catch (...)
{
return false;
}
}
Ptr<Layer>& cvLayer;
std::vector<Mat> outputs, internals;
};
#else
class NgraphCustomOp: public ngraph::op::Op {
public:
const ngraph::NodeTypeInfo& get_type_info() const override
@ -324,7 +381,7 @@ public:
#endif
};
#endif // OpenVINO >= 2022.1
InfEngineNgraphNode::InfEngineNgraphNode(std::shared_ptr<ngraph::Node>&& _node)
: BackendNode(DNN_BACKEND_INFERENCE_ENGINE_NGRAPH), node(std::move(_node)) {}
@ -337,15 +394,6 @@ InfEngineNgraphNode::InfEngineNgraphNode(const std::vector<Ptr<BackendNode> >& n
std::vector<Mat>& outputs, std::vector<Mat>& internals)
: BackendNode(DNN_BACKEND_INFERENCE_ENGINE_NGRAPH), cvLayer(cvLayer_)
{
std::ostringstream oss;
oss << (size_t)cvLayer.get();
std::map<std::string, InferenceEngine::Parameter> params = {
{"impl", oss.str()},
{"outputs", shapesToStr(outputs)},
{"internals", shapesToStr(internals)}
};
#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2020_3)
ngraph::OutputVector inp_nodes;
#else
@ -353,7 +401,19 @@ InfEngineNgraphNode::InfEngineNgraphNode(const std::vector<Ptr<BackendNode> >& n
#endif
for (const auto& node : nodes)
inp_nodes.emplace_back(node.dynamicCast<InfEngineNgraphNode>()->node);
#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2022_1)
node = std::make_shared<NgraphCustomOp>(inp_nodes, cvLayer, outputs, internals);
#else
std::ostringstream oss;
oss << (size_t)cvLayer.get();
std::map<std::string, InferenceEngine::Parameter> params = {
{"impl", oss.str()},
{"outputs", shapesToStr(outputs)},
{"internals", shapesToStr(internals)}
};
node = std::make_shared<NgraphCustomOp>(inp_nodes, params);
#endif
CV_Assert(!cvLayer->name.empty());
setName(cvLayer->name);
@ -383,7 +443,7 @@ void InfEngineNgraphNet::addOutput(const Ptr<InfEngineNgraphNode>& node)
CV_Assert(node);
CV_Assert(node->node);
const std::string& name = node->node->get_friendly_name();
requestedOutputs.insert({name, node});
requestedOutputs.insert({name, node.get()});
}
void InfEngineNgraphNet::setNodePtr(std::shared_ptr<ngraph::Node>* ptr) {
@ -457,6 +517,9 @@ void InfEngineNgraphNet::createNet(Target targetId) {
CV_LOG_DEBUG(NULL, "DNN/NGRAPH: Add 'Result' output: " << output_node_it->first);
CV_Assert(output_node_it->second);
auto out = std::make_shared<ngraph::op::Result>(output_node_it->second->node);
#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2022_1)
out->set_friendly_name(output_node_it->first + (output_node_it->second->node->get_output_size() == 1 ? "" : ".0"));
#endif
outs.push_back(out);
}
CV_Assert_N(!inputs_vec.empty(), !outs.empty());
@ -504,12 +567,20 @@ void InfEngineNgraphNet::createNet(Target targetId) {
}
}
#if INF_ENGINE_VER_MAJOR_LT(INF_ENGINE_RELEASE_2022_1)
static inline
InferenceEngine::Layout estimateLayout(size_t dims);
#endif
void InfEngineNgraphNet::init(Target targetId)
{
if (!hasNetOwner)
{
if (targetId == DNN_TARGET_OPENCL_FP16)
{
#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2022_1)
ov::pass::ConvertFP32ToFP16().run_on_model(ngraph_function);
#else
auto nodes = ngraph_function->get_ordered_ops();
for (auto& node : nodes)
{
@ -533,6 +604,7 @@ void InfEngineNgraphNet::init(Target targetId)
}
}
ngraph_function->validate_nodes_and_infer_types();
#endif // OpenVINO >= 2022.1
}
cnn = InferenceEngine::CNNNetwork(ngraph_function);
@ -580,20 +652,45 @@ void InfEngineNgraphNet::init(Target targetId)
CV_Error(Error::StsNotImplemented, "Unknown target");
};
if (!hasNetOwner) {
for (size_t i = 0; i < ngraph_function->get_output_size(); ++i) {
auto node = ngraph_function->output(i).get_node();
for (size_t j = 0; j < node->get_input_size(); ++j) {
std::string name = node->input_value(j).get_node()->get_friendly_name();
auto iter = requestedOutputs.find(name);
if (iter != requestedOutputs.end()) {
requestedOutputs.erase(iter);
cnn.addOutput(name);
}
}
#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2022_1)
auto model = cnn.getFunction();
ov::preprocess::PrePostProcessor ppp(model);
int i = 0;
for (const auto& inp : model->inputs()) { // TODO: not sure why but ngraph_function->inputs() here causes segfault.
const std::string& name = inp.get_node()->get_friendly_name();
auto blobIt = allBlobs.find(name);
CV_Assert(blobIt != allBlobs.end());
auto srcT = blobIt->second.get_element_type();
if (srcT != inp.get_node()->get_element_type()) {
ppp.input(i++).tensor().set_element_type(srcT);
}
}
i = 0;
for (const auto& it : model->outputs())
{
const std::string& name = it.get_node()->get_friendly_name();
auto blobIt = allBlobs.find(name);
CV_Assert(blobIt != allBlobs.end());
const auto& src = blobIt->second;
// A workaround for single dimension output for which OpenCV allocates 2d Mat.
// For example, face-detection-0105 with Result of shape {200} while output blob is {200, 1}
auto outShape = it.get_partial_shape().get_max_shape();
if (outShape != src.get_shape()) {
size_t sz = std::accumulate(outShape.begin(), outShape.end(), 1, std::multiplies<size_t>());
CV_Assert(sz == src.get_size());
allBlobs[name] = ov::Tensor(src.get_element_type(), outShape, src.data());
}
ppp.output(i++).tensor().set_element_type(ov::element::f32); // Should be always FP32
}
ppp.build();
#else
for (const auto& it : cnn.getInputsInfo())
{
const std::string& name = it.first;
@ -607,8 +704,16 @@ void InfEngineNgraphNet::init(Target targetId)
const std::string& name = it.first;
auto blobIt = allBlobs.find(name);
CV_Assert(blobIt != allBlobs.end());
InferenceEngine::TensorDesc& desc = blobIt->second->getTensorDesc();
auto outShape = it.second->getDims();
if (outShape != desc.getDims()) {
desc.reshape(outShape, estimateLayout(outShape.size()));
}
it.second->setPrecision(blobIt->second->getTensorDesc().getPrecision()); // Should be always FP32
}
#endif // OpenVINO >= 2022.1
initPlugin(cnn);
}
@ -660,6 +765,9 @@ void InfEngineNgraphNet::initPlugin(InferenceEngine::CNNNetwork& net)
const std::string& libName = candidates[i];
try
{
#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2022_1)
ie.add_extension(libName);
#else
InferenceEngine::IExtensionPtr extension =
#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2021_4)
std::make_shared<InferenceEngine::Extension>(libName);
@ -668,6 +776,7 @@ void InfEngineNgraphNet::initPlugin(InferenceEngine::CNNNetwork& net)
#endif
ie.AddExtension(extension, "CPU");
#endif
CV_LOG_INFO(NULL, "DNN-IE: Loaded extension plugin: " << libName);
found = true;
break;
@ -678,6 +787,7 @@ void InfEngineNgraphNet::initPlugin(InferenceEngine::CNNNetwork& net)
{
CV_LOG_WARNING(NULL, "DNN-IE: Can't load extension plugin (extra layers for some networks). Specify path via OPENCV_DNN_IE_EXTRA_PLUGIN_PATH parameter");
}
#if INF_ENGINE_VER_MAJOR_LT(INF_ENGINE_RELEASE_2022_1)
// Some of networks can work without a library of extra layers.
// OpenCV fallbacks as extensions.
try
@ -688,12 +798,17 @@ void InfEngineNgraphNet::initPlugin(InferenceEngine::CNNNetwork& net)
{
CV_LOG_INFO(NULL, "DNN-IE: Can't register OpenCV custom layers nGraph extension: " << e.what());
}
#endif // OpenVINO < 2022.1
#ifndef _WIN32
// Limit the number of CPU threads.
if (device_name == "CPU")
#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2022_1)
ie.set_property(device_name, ov::inference_num_threads(getNumThreads()));
#else
ie.SetConfig({{
InferenceEngine::PluginConfigParams::KEY_CPU_THREADS_NUM, format("%d", getNumThreads()),
}}, device_name);
#endif // OpenVINO >= 2022.1
#endif
#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2021_2)
if (device_name.find("GPU") == 0)
@ -706,9 +821,13 @@ void InfEngineNgraphNet::initPlugin(InferenceEngine::CNNNetwork& net)
if (!cache_path.empty() && cache_path != "disabled")
{
CV_LOG_INFO(NULL, "OpenCV/nGraph: using GPU kernels cache: " << cache_path);
#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2022_1)
ie.set_property(device_name, ov::cache_dir(cache_path));
#else
ie.SetConfig({{
InferenceEngine::PluginConfigParams::KEY_CACHE_DIR, cache_path,
}}, device_name);
#endif // OpenVINO >= 2022.1
}
}
#endif
@ -716,9 +835,9 @@ void InfEngineNgraphNet::initPlugin(InferenceEngine::CNNNetwork& net)
std::map<std::string, std::string> config;
if (device_name == "MYRIAD" || device_name == "HDDL") {
#if INF_ENGINE_VER_MAJOR_GT(INF_ENGINE_RELEASE_2020_4)
config.emplace("MYRIAD_DETECT_NETWORK_BATCH", CONFIG_VALUE(NO));
config.emplace("MYRIAD_DETECT_NETWORK_BATCH", "NO");
#else
config.emplace("VPU_DETECT_NETWORK_BATCH", CONFIG_VALUE(NO));
config.emplace("VPU_DETECT_NETWORK_BATCH", "NO");
#endif
}
@ -757,16 +876,17 @@ bool NgraphBackendLayer::getMemoryShapes(const std::vector<MatShape> &inputs,
std::vector<MatShape> &outputs,
std::vector<MatShape> &internals) const
{
InferenceEngine::ICNNNetwork::InputShapes inShapes = t_net.getInputShapes();
InferenceEngine::ICNNNetwork::InputShapes::iterator itr;
auto ngraphFunction = t_net.getFunction();
bool equal_flag = true;
size_t i = 0;
for (itr = inShapes.begin(); itr != inShapes.end(); ++itr)
std::map<std::string, std::vector<size_t> > inShapes;
int i = 0;
for (const auto& inp : ngraphFunction->get_parameters())
{
InferenceEngine::SizeVector currentInShape(inputs[i].begin(), inputs[i].end());
if (itr->second != currentInShape)
std::vector<size_t> oldShape = inp->get_shape();
std::vector<size_t> newShape(inputs[i].begin(), inputs[i].end());
inShapes.insert({inp->get_friendly_name(), newShape});
if (oldShape != newShape)
{
itr->second = currentInShape;
equal_flag = false;
}
i++;
@ -777,7 +897,18 @@ bool NgraphBackendLayer::getMemoryShapes(const std::vector<MatShape> &inputs,
InferenceEngine::CNNNetwork curr_t_net(t_net);
curr_t_net.reshape(inShapes);
}
#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2022_1)
std::vector<size_t> dims;
for (const auto& it : ngraphFunction->outputs()) {
if (it.get_node()->get_friendly_name() == name) {
dims = it.get_partial_shape().get_max_shape();
}
}
if (dims.empty())
CV_Error(Error::StsError, format("Unable find result with name %s", name.c_str()));
#else
std::vector<size_t> dims = t_net.getOutputsInfo()[name]->getDims();
#endif
outputs.push_back(MatShape(dims.begin(), dims.end()));
return false;
}
@ -795,6 +926,21 @@ void NgraphBackendLayer::forward(InputArrayOfArrays inputs, OutputArrayOfArrays
CV_Error(Error::StsInternal, "Choose Inference Engine as a preferable backend.");
}
#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2022_1)
ov::Tensor wrapToNgraphBlob(const Mat& m) {
std::vector<size_t> shape = getShape<size_t>(m);
if (m.type() == CV_32F)
return ov::Tensor(ov::element::f32, shape, m.data);
else if (m.type() == CV_8U)
return ov::Tensor(ov::element::u8, shape, m.data);
else if (m.type() == CV_32SC1)
return ov::Tensor(ov::element::i32, shape, m.data);
else
CV_Error(Error::StsNotImplemented, format("Unsupported data type %s", typeToString(m.type()).c_str()));
}
#else
static InferenceEngine::Layout estimateLayout(int dims)
{
@ -823,19 +969,6 @@ InferenceEngine::Layout estimateLayout(const Mat& m)
return estimateLayout(m.dims);
}
static InferenceEngine::DataPtr wrapToInfEngineDataNode(const Mat& m, const std::string& name = "")
{
std::vector<size_t> shape = getShape<size_t>(m);
if (m.type() == CV_32F)
return InferenceEngine::DataPtr(new InferenceEngine::Data(name,
{InferenceEngine::Precision::FP32, shape, estimateLayout(m)}));
else if (m.type() == CV_8U)
return InferenceEngine::DataPtr(new InferenceEngine::Data(name,
{InferenceEngine::Precision::U8, shape, estimateLayout(m)}));
else
CV_Error(Error::StsNotImplemented, format("Unsupported data type %s", typeToString(m.type()).c_str()));
}
InferenceEngine::Blob::Ptr wrapToNgraphBlob(const Mat& m, const std::vector<size_t>& shape,
InferenceEngine::Layout layout)
{
@ -845,6 +978,9 @@ InferenceEngine::Blob::Ptr wrapToNgraphBlob(const Mat& m, const std::vector<size
else if (m.type() == CV_8U)
return InferenceEngine::make_shared_blob<uint8_t>(
{InferenceEngine::Precision::U8, shape, layout}, (uint8_t*)m.data);
else if (m.type() == CV_32SC1)
return InferenceEngine::make_shared_blob<int32_t>(
{InferenceEngine::Precision::I32, shape, layout}, (int32_t*)m.data);
else
CV_Error(Error::StsNotImplemented, format("Unsupported data type %s", typeToString(m.type()).c_str()));
}
@ -855,12 +991,15 @@ InferenceEngine::Blob::Ptr wrapToNgraphBlob(const Mat& m, InferenceEngine::Layou
return wrapToNgraphBlob(m, shape, layout);
}
InferenceEngine::Blob::Ptr wrapToNgraphBlob(const Mat& m) { return wrapToNgraphBlob(m, estimateLayout(m)); }
#endif // OpenVINO >= 2022.1
NgraphBackendWrapper::NgraphBackendWrapper(int targetId, const cv::Mat& m)
: BackendWrapper(DNN_BACKEND_INFERENCE_ENGINE_NGRAPH, targetId)
, host((Mat*)&m)
{
dataPtr = wrapToInfEngineDataNode(m);
blob = wrapToNgraphBlob(m, estimateLayout(m));
blob = wrapToNgraphBlob(m);
}
NgraphBackendWrapper::NgraphBackendWrapper(Ptr<BackendWrapper> wrapper)
@ -868,8 +1007,7 @@ NgraphBackendWrapper::NgraphBackendWrapper(Ptr<BackendWrapper> wrapper)
{
Ptr<NgraphBackendWrapper> ieWrapper = wrapper.dynamicCast<NgraphBackendWrapper>();
CV_Assert(!ieWrapper.empty());
InferenceEngine::DataPtr srcData = ieWrapper->dataPtr;
dataPtr = InferenceEngine::DataPtr(new InferenceEngine::Data(srcData->getName(), srcData->getTensorDesc()));
name = ieWrapper->name;
blob = ieWrapper->blob;
}
@ -895,6 +1033,12 @@ void NgraphBackendWrapper::setHostDirty()
//CV_Error(Error::StsNotImplemented, "");
}
#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2022_1)
ov::Tensor copyBlob(const ov::Tensor& blob)
{
return ov::Tensor(blob.get_element_type(), blob.get_shape());
}
#else
InferenceEngine::Blob::Ptr copyBlob(const InferenceEngine::Blob::Ptr& blob)
{
InferenceEngine::Blob::Ptr copy;
@ -918,88 +1062,13 @@ InferenceEngine::Blob::Ptr copyBlob(const InferenceEngine::Blob::Ptr& blob)
return copy;
}
InferenceEngine::DataPtr ngraphDataNode(const Ptr<BackendWrapper>& ptr)
{
CV_Assert(!ptr.empty());
Ptr<NgraphBackendWrapper> p = ptr.dynamicCast<NgraphBackendWrapper>();
CV_Assert(!p.empty());
return p->dataPtr;
}
static
InferenceEngine::Blob::Ptr reallocateBlob(Mat &m, const InferenceEngine::TensorDesc& description)
{
auto dims = description.getDims();
auto layout = estimateLayout(dims.size());
MatShape matShape(dims.begin(), dims.end());
if (description.getPrecision() == InferenceEngine::Precision::FP32)
{
m.create(matShape, CV_32FC1);
return InferenceEngine::make_shared_blob<float>(
{description.getPrecision(), dims, layout}, (float*)m.data);
}
else if (description.getPrecision() == InferenceEngine::Precision::I32)
{
m.create(matShape, CV_32SC1);
return InferenceEngine::make_shared_blob<int>(
{description.getPrecision(), dims, layout}, (int*)m.data);
}
else if (description.getPrecision() == InferenceEngine::Precision::U8)
{
m.create(matShape, CV_8UC1);
return InferenceEngine::make_shared_blob<uchar>(
{description.getPrecision(), dims, layout}, (uchar*)m.data);
}
std::ostringstream msg;
msg << "Unsupported IE precision: " << description.getPrecision();
CV_Error(Error::StsNotImplemented, msg.str());
}
InferenceEngine::DataPtr ngraphDataOutputNode(
const Ptr<BackendWrapper>& ptr,
const InferenceEngine::TensorDesc& description,
const std::string name)
{
CV_Assert(!ptr.empty());
Ptr<NgraphBackendWrapper> p = ptr.dynamicCast<NgraphBackendWrapper>();
CV_Assert(!p.empty());
NgraphBackendWrapper& w = *p;
const InferenceEngine::TensorDesc& blobDesc = w.blob.get()->getTensorDesc();
auto dims = description.getDims();
bool reallocate = false;
if (blobDesc.getPrecision() != description.getPrecision())
{
reallocate = true;
CV_LOG_WARNING(NULL, "Reallocate output '" << name << "' blob due to wrong precision: " << blobDesc.getPrecision() << " => " << description.getPrecision() << " ndims=" << dims.size());
}
if (dims.size() != blobDesc.getDims().size())
{
reallocate = true;
CV_LOG_WARNING(NULL, "Reallocate output '" << name << "' blob due to wrong dims: " << blobDesc.getDims().size() << " => " << dims.size());
}
if (reallocate)
{
auto layout = estimateLayout(dims.size());
w.dataPtr = InferenceEngine::DataPtr(new InferenceEngine::Data(name,
{description.getPrecision(), dims, layout}));
w.blob = reallocateBlob(*w.host, description);
}
return w.dataPtr;
}
#endif // OpenVINO < 2022.1
void InfEngineNgraphNet::reset()
{
allBlobs.clear();
infRequests.clear();
isInit = false;
outputsDesc.clear();
for (const auto& it : cnn.getOutputsInfo())
{
const std::string& name = it.first;
outputsDesc.insert({name, it.second->getTensorDesc()});
}
}
void InfEngineNgraphNet::addBlobs(const std::vector<cv::Ptr<BackendWrapper> >& ptrs)
@ -1007,7 +1076,7 @@ void InfEngineNgraphNet::addBlobs(const std::vector<cv::Ptr<BackendWrapper> >& p
auto wrappers = ngraphWrappers(ptrs);
for (const auto& wrapper : wrappers)
{
std::string name = wrapper->dataPtr->getName();
std::string name = wrapper->name;
name = name.empty() ? kDefaultInpLayerName : name;
allBlobs.insert({name, wrapper->blob});
}
@ -1022,27 +1091,10 @@ void InfEngineNgraphNet::NgraphReqWrapper::makePromises(const std::vector<Ptr<Ba
for (int i = 0; i < outs.size(); ++i)
{
outs[i]->futureMat = outProms[i].getArrayResult();
outsNames[i] = outs[i]->dataPtr->getName();
outsNames[i] = outs[i]->name;
}
}
Mat ngraphBlobToMat(const InferenceEngine::Blob::Ptr& blob)
{
std::vector<size_t> dims = blob->getTensorDesc().getDims();
std::vector<int> size(dims.begin(), dims.end());
auto precision = blob->getTensorDesc().getPrecision();
int type = -1;
switch (precision)
{
case InferenceEngine::Precision::FP32: type = CV_32F; break;
case InferenceEngine::Precision::U8: type = CV_8U; break;
default:
CV_Error(Error::StsNotImplemented, "Unsupported blob precision");
}
return Mat(size, type, (void*)blob->buffer());
}
void InfEngineNgraphNet::forward(const std::vector<Ptr<BackendWrapper> >& outBlobsWrappers, bool isAsync)
{
CV_LOG_DEBUG(NULL, "InfEngineNgraphNet::forward(" << (isAsync ? "async" : "sync") << ")");
@ -1070,6 +1122,25 @@ void InfEngineNgraphNet::forward(const std::vector<Ptr<BackendWrapper> >& outBlo
}
infRequests.push_back(reqWrapper);
#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2022_1)
int i = 0;
for (const auto& it : netExec.inputs())
{
const std::string& name = it.get_node()->get_friendly_name();
auto blobIt = allBlobs.find(name);
CV_Assert(blobIt != allBlobs.end());
reqWrapper->req.set_input_tensor(i++, isAsync ? copyBlob(blobIt->second) : blobIt->second);
}
i = 0;
for (const auto& it : netExec.outputs())
{
const std::string& name = it.get_node()->get_friendly_name();
auto blobIt = allBlobs.find(name);
CV_Assert(blobIt != allBlobs.end());
reqWrapper->req.set_output_tensor(i++, isAsync ? copyBlob(blobIt->second) : blobIt->second);
}
#else
InferenceEngine::BlobMap inpBlobs, outBlobs;
for (const auto& it : cnn.getInputsInfo())
{
@ -1087,6 +1158,53 @@ void InfEngineNgraphNet::forward(const std::vector<Ptr<BackendWrapper> >& outBlo
}
reqWrapper->req.SetInput(inpBlobs);
reqWrapper->req.SetOutput(outBlobs);
#endif
#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2022_1)
if (isAsync) {
bool* isReady = &reqWrapper->isReady;
auto* promises = &reqWrapper->outProms;
auto* req = &reqWrapper->req;
reqWrapper->req.set_callback([isReady, promises, req](std::exception_ptr ex) {
CV_LOG_DEBUG(NULL, "DNN(nGraph): completionCallback(" << (int)status << ")");
size_t processedOutputs = 0;
try
{
for (; processedOutputs < promises->size(); ++processedOutputs)
{
Mat m = infEngineBlobToMat(req->get_output_tensor(processedOutputs));
try
{
(*promises)[processedOutputs].setValue(m.clone());
}
catch (...)
{
try {
(*promises)[processedOutputs].setException(std::current_exception());
} catch(...) {
CV_LOG_ERROR(NULL, "DNN: Exception occurred during async inference exception propagation");
}
}
}
}
catch (...)
{
std::exception_ptr e = std::current_exception();
for (; processedOutputs < promises->size(); ++processedOutputs)
{
try {
(*promises)[processedOutputs].setException(e);
} catch(...) {
CV_LOG_ERROR(NULL, "DNN: Exception occurred during async inference exception propagation");
}
}
}
*isReady = true;
});
}
#else // OpenVINO >= 2022.1
#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2021_4)
InferenceEngine::InferRequest infRequest = reqWrapper->req;
@ -1125,7 +1243,7 @@ void InfEngineNgraphNet::forward(const std::vector<Ptr<BackendWrapper> >& outBlo
for (; processedOutputs < wrapper.outProms.size(); ++processedOutputs)
{
const std::string& name = wrapper.outsNames[processedOutputs];
Mat m = ngraphBlobToMat(wrapper.req.GetBlob(name));
Mat m = infEngineBlobToMat(wrapper.req.GetBlob(name));
try
{
@ -1157,8 +1275,34 @@ void InfEngineNgraphNet::forward(const std::vector<Ptr<BackendWrapper> >& outBlo
wrapper.isReady = true;
}
);
#endif // OpenVINO >= 2022.1
}
#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2022_1)
if (isAsync)
{
// Copy actual data to infer request's input blobs.
int i = 0;
for (const auto& it : cnn.getFunction()->get_parameters())
{
const std::string& name = it->get_friendly_name();
auto blobIt = allBlobs.find(name);
Mat srcMat = infEngineBlobToMat(blobIt->second);
Mat dstMat = infEngineBlobToMat(reqWrapper->req.get_input_tensor(i++));
srcMat.copyTo(dstMat);
}
// Set promises to output blobs wrappers.
reqWrapper->makePromises(outBlobsWrappers);
reqWrapper->isReady = false;
reqWrapper->req.start_async();
}
else
{
reqWrapper->req.infer();
}
#else
if (isAsync)
{
// Copy actual data to infer request's input blobs.
@ -1166,8 +1310,8 @@ void InfEngineNgraphNet::forward(const std::vector<Ptr<BackendWrapper> >& outBlo
{
const std::string& name = it.first;
auto blobIt = allBlobs.find(name);
Mat srcMat = ngraphBlobToMat(blobIt->second);
Mat dstMat = ngraphBlobToMat(reqWrapper->req.GetBlob(name));
Mat srcMat = infEngineBlobToMat(blobIt->second);
Mat dstMat = infEngineBlobToMat(reqWrapper->req.GetBlob(name));
srcMat.copyTo(dstMat);
}
@ -1181,6 +1325,7 @@ void InfEngineNgraphNet::forward(const std::vector<Ptr<BackendWrapper> >& outBlo
{
reqWrapper->req.Infer();
}
#endif // OpenVINO >= 2022.1
}
#endif

View File

@ -68,7 +68,11 @@ public:
std::unordered_map<std::string, std::shared_ptr<ngraph::Node>* > all_nodes;
InferenceEngine::ExecutableNetwork netExec;
#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2022_1)
std::map<std::string, ov::Tensor> allBlobs;
#else
InferenceEngine::BlobMap allBlobs;
#endif
std::string device_name;
bool isInit = false;
@ -87,9 +91,7 @@ public:
InferenceEngine::CNNNetwork cnn;
bool hasNetOwner;
std::unordered_map<std::string, Ptr<InfEngineNgraphNode> > requestedOutputs;
std::map<std::string, InferenceEngine::TensorDesc> outputsDesc;
std::unordered_map<std::string, InfEngineNgraphNode*> requestedOutputs;
};
class InfEngineNgraphNode : public BackendNode
@ -123,17 +125,15 @@ public:
virtual void setHostDirty() CV_OVERRIDE;
Mat* host;
InferenceEngine::DataPtr dataPtr;
std::string name;
#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2022_1)
ov::Tensor blob;
#else
InferenceEngine::Blob::Ptr blob;
#endif
AsyncArray futureMat;
};
InferenceEngine::DataPtr ngraphDataNode(const Ptr<BackendWrapper>& ptr);
InferenceEngine::DataPtr ngraphDataOutputNode(
const Ptr<BackendWrapper>& ptr,
const InferenceEngine::TensorDesc& description,
const std::string name);
// This is a fake class to run networks from Model Optimizer. Objects of that
// class simulate responses of layers are imported by OpenCV and supported by
// Inference Engine. The main difference is that they do not perform forward pass.

View File

@ -403,8 +403,7 @@ public:
virtual Ptr<BackendNode> initNgraph(const std::vector<Ptr<BackendWrapper> >& inputs,
const std::vector<Ptr<BackendNode> >& nodes) CV_OVERRIDE
{
InferenceEngine::DataPtr data = ngraphDataNode(inputs[0]);
const int numDims = data->getDims().size();
const int numDims = nodes[0].dynamicCast<InfEngineNgraphNode>()->node->get_shape().size();
const int cAxis = normalize_axis(axis, numDims);
std::vector<size_t> maxDims(numDims, 0);
@ -412,16 +411,17 @@ public:
ngraph::OutputVector inp_nodes;
for (int i = 0; i < nodes.size(); ++i)
{
inp_nodes.push_back(nodes[i].dynamicCast<InfEngineNgraphNode>()->node);
auto inp = nodes[i].dynamicCast<InfEngineNgraphNode>()->node;
inp_nodes.push_back(inp);
std::vector<size_t> inpShape = ngraphDataNode(inputs[i])->getDims();
std::vector<size_t> inpShape = inp->get_shape();
for (int i = 0; i < numDims; ++i)
maxDims[i] = std::max(maxDims[i], inpShape[i]);
}
for (int i = 0; i < inp_nodes.size(); ++i)
{
bool needPadding = false;
std::vector<size_t> inpShape = ngraphDataNode(inputs[i])->getDims();
std::vector<size_t> inpShape = inp_nodes[i].get_shape();
std::vector<int64_t> begins(inpShape.size(), 0), ends(inpShape.size(), 0);
for (int j = 0; j < inpShape.size(); ++j)
{

View File

@ -6,6 +6,7 @@
#include "layers_common.hpp"
#include "../op_cuda.hpp"
#include "../op_cann.hpp"
#include "../ie_ngraph.hpp"
#include <opencv2/dnn/shape_utils.hpp>
@ -104,6 +105,12 @@ public:
return op == OPERATION::ADD || op == OPERATION::PROD || op == OPERATION::DIV ||
op == OPERATION::DIV || op == OPERATION::MAX || op == OPERATION::MIN;
#endif
if (backendId == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
return (op == OPERATION::ADD ||
op == OPERATION::PROD ||
op == OPERATION::GREATER_EQUAL ||
op == OPERATION::LESS_EQUAL
);
if (op == OPERATION::MAX || op == OPERATION::MIN || op == OPERATION::SUM ||
op == OPERATION::PROD || op == OPERATION::DIV)
return backendId == DNN_BACKEND_OPENCV || backendId == DNN_BACKEND_CUDA;
@ -743,6 +750,37 @@ public:
CV_Assert(inputs.size());
return inputs.size() * total(outputs[0]);
}
#ifdef HAVE_DNN_NGRAPH
virtual Ptr<BackendNode> initNgraph(const std::vector<Ptr<BackendWrapper> >& inputs, const std::vector<Ptr<BackendNode> >& nodes) CV_OVERRIDE
{
CV_Assert(inputs.size() == 2);
auto& inp0 = nodes[0].dynamicCast<InfEngineNgraphNode>()->node;
auto& inp1 = nodes[1].dynamicCast<InfEngineNgraphNode>()->node;
if (inp0->get_element_type() != inp1->get_element_type()) {
auto dtype = preferableTarget == DNN_TARGET_OPENCL_FP16 || preferableTarget == DNN_TARGET_MYRIAD ?
ngraph::element::f16 : ngraph::element::f32;
if (inp0->get_element_type() != dtype)
inp0 = std::make_shared<ngraph::op::v0::Convert>(inp0, dtype);
if (inp1->get_element_type() != dtype)
inp1 = std::make_shared<ngraph::op::v0::Convert>(inp1, dtype);
}
std::shared_ptr<ngraph::Node> node;
if (op == OPERATION::ADD)
node = std::make_shared<ngraph::op::v1::Add>(inp0, inp1);
else if (op == OPERATION::PROD)
node = std::make_shared<ngraph::op::v1::Multiply>(inp0, inp1);
else if (op == OPERATION::GREATER_EQUAL)
node = std::make_shared<ngraph::op::v1::GreaterEqual>(inp0, inp1);
else if (op == OPERATION::LESS_EQUAL)
node = std::make_shared<ngraph::op::v1::LessEqual>(inp0, inp1);
else
CV_Error(Error::StsNotImplemented, "Operation is not implemented for nGraph backend");
return Ptr<BackendNode>(new InfEngineNgraphNode(node));
}
#endif
};
Ptr<NaryEltwiseLayer> NaryEltwiseLayer::create(const LayerParams& params)

View File

@ -401,6 +401,24 @@ public:
#else
ngraph::op::v4::Interpolate::InterpolateAttrs attrs;
#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2022_1)
if (interpolation == "nearest") {
attrs.mode = ngraph::op::v4::Interpolate::InterpolateMode::NEAREST;
attrs.coordinate_transformation_mode = ngraph::op::v4::Interpolate::CoordinateTransformMode::HALF_PIXEL;
} else if (interpolation == "bilinear") {
attrs.mode = ngraph::op::v4::Interpolate::InterpolateMode::LINEAR_ONNX;
attrs.coordinate_transformation_mode = ngraph::op::v4::Interpolate::CoordinateTransformMode::ASYMMETRIC;
} else {
CV_Error(Error::StsNotImplemented, format("Unsupported interpolation: %s", interpolation.c_str()));
}
attrs.shape_calculation_mode = ngraph::op::v4::Interpolate::ShapeCalcMode::SIZES;
if (alignCorners) {
attrs.coordinate_transformation_mode = ngraph::op::v4::Interpolate::CoordinateTransformMode::ALIGN_CORNERS;
}
attrs.nearest_mode = ngraph::op::v4::Interpolate::NearestMode::ROUND_PREFER_FLOOR;
#else
if (interpolation == "nearest") {
attrs.mode = ngraph::op::v4::Interpolate::InterpolateMode::nearest;
attrs.coordinate_transformation_mode = ngraph::op::v4::Interpolate::CoordinateTransformMode::half_pixel;
@ -417,6 +435,7 @@ public:
}
attrs.nearest_mode = ngraph::op::v4::Interpolate::NearestMode::round_prefer_floor;
#endif // OpenVINO >= 2022.1
std::vector<int64_t> shape = {outHeight, outWidth};
auto out_shape = std::make_shared<ngraph::op::Constant>(ngraph::element::i64, ngraph::Shape{2}, shape.data());

View File

@ -275,19 +275,17 @@ void NetImplOpenVINO::initBackend(const std::vector<LayerPin>& blobsToKeep_)
(netInputLayer->outNames.size() == ld.outputBlobsWrappers.size()));
for (int i = 0; i < ld.outputBlobsWrappers.size(); ++i)
{
InferenceEngine::DataPtr dataPtr = ngraphDataNode(ld.outputBlobsWrappers[i]);
std::string outputName = netInputLayer->outNames.empty() ? ld.name : netInputLayer->outNames[i];
outputName = ld.outputBlobsWrappers.size() > 1 ? (outputName + "." + std::to_string(i)) : outputName;
dataPtr->setName(outputName);
ld.outputBlobsWrappers[i].dynamicCast<NgraphBackendWrapper>()->name = outputName;
}
}
else
{
for (int i = 0; i < ld.outputBlobsWrappers.size(); ++i)
{
InferenceEngine::DataPtr dataPtr = ngraphDataNode(ld.outputBlobsWrappers[i]);
std::string outputName = ld.outputBlobsWrappers.size() > 1 ? (ld.name + "." + std::to_string(i)) : ld.name;
dataPtr->setName(outputName);
ld.outputBlobsWrappers[i].dynamicCast<NgraphBackendWrapper>()->name = outputName;
}
}
}
@ -311,26 +309,7 @@ void NetImplOpenVINO::initBackend(const std::vector<LayerPin>& blobsToKeep_)
{
for (int i = 0; i < ld.inputBlobsWrappers.size(); ++i)
{
InferenceEngine::DataPtr dataPtr = ngraphDataNode(ld.inputBlobsWrappers[i]);
dataPtr->setName(netInputLayer->outNames[i]);
}
}
else
{
for (int i = 0; i < ld.outputBlobsWrappers.size(); ++i)
{
auto it = ienet.outputsDesc.find(ld.name);
if (it != ienet.outputsDesc.end())
{
const InferenceEngine::TensorDesc& descriptor = it->second;
InferenceEngine::DataPtr dataPtr = ngraphDataOutputNode(ld.outputBlobsWrappers[i], descriptor, ld.name);
dataPtr->setName(ld.name);
}
else
{
InferenceEngine::DataPtr dataPtr = ngraphDataNode(ld.outputBlobsWrappers[i]);
dataPtr->setName(ld.name);
}
ld.inputBlobsWrappers[i].dynamicCast<NgraphBackendWrapper>()->name = netInputLayer->outNames[i];
}
}
ienet.addBlobs(ld.inputBlobsWrappers);
@ -456,10 +435,10 @@ void NetImplOpenVINO::initBackend(const std::vector<LayerPin>& blobsToKeep_)
dynamicCast<NgraphBackendWrapper>();
CV_Assert(!inpWrapper.empty());
auto iter = std::find(inputNames.begin(), inputNames.end(),
inpWrapper->dataPtr->getName());
inpWrapper->name);
if (iter == inputNames.end())
{
inputNames.push_back(inpWrapper->dataPtr->getName());
inputNames.push_back(inpWrapper->name);
inputs.push_back(inpLd.outputBlobs[cons_inp]);
}
curr_pos = cons + 1;
@ -505,7 +484,12 @@ void NetImplOpenVINO::initBackend(const std::vector<LayerPin>& blobsToKeep_)
CV_LOG_DEBUG(NULL, "DNN/IE: bind output port " << lid << ":" << oid << " (" << ngraph_input_node->get_friendly_name() << ":" << ngraph_input_node->get_type_info().name << ")");
// Handle parameters from other subnets. Output port is not used in this case
#if INF_ENGINE_VER_MAJOR_GT(INF_ENGINE_RELEASE_2020_4)
if ((ngraph::op::is_parameter(ngraph_input_node) || ngraph::op::is_constant(ngraph_input_node)) &&
#else
if ((ngraph_input_node->is_parameter() || ngraph_input_node->is_constant()) &&
#endif
ngraph_input_node->get_output_size() == 1)
{
inputNodes[i] = Ptr<BackendNode>(new InfEngineNgraphNode(ngraph_input_node));
@ -702,14 +686,33 @@ Net NetImplOpenVINO::createNetworkFromModelOptimizer(InferenceEngine::CNNNetwork
CV_TRACE_REGION("register_inputs");
auto ngraphFunction = ieNet.getFunction();
CV_Assert(ngraphFunction);
std::vector<String> inputsNames;
std::vector<MatShape> inp_shapes;
for (auto& it : ieNet.getInputsInfo())
for (auto& it : ngraphFunction->get_parameters())
{
inputsNames.push_back(it.first);
std::vector<size_t> dims = it.second->getTensorDesc().getDims();
inputsNames.push_back(it->get_friendly_name());
std::vector<size_t> dims = it->get_shape();
inp_shapes.push_back(std::vector<int>(dims.begin(), dims.end()));
}
// nGraph models produce output "Result" layers which have "/sink_port" suffix in their names.
// Their inputs are actual model outputs and we change friendly name to it.
// By this workaround, we produce similar outputs names comparing to ieNet.getOutputsInfo()
for (int i = 0; i < ngraphFunction->get_output_size(); ++i) {
auto res = ngraphFunction->output(i);
#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2022_1)
const std::string& name = res.get_any_name();
#else
auto out = res.get_node()->input(0).get_source_output();
std::string name = out.get_node()->get_friendly_name();
if (out.get_node()->get_output_size() > 1)
name += "." + std::to_string(out.get_index());
#endif
if (res.get_node()->get_friendly_name() != name)
res.get_node()->set_friendly_name(name);
}
Net cvNet;
Ptr<NetImplOpenVINO> openvino_impl_ptr = makePtr<NetImplOpenVINO>();
@ -736,17 +739,15 @@ Net NetImplOpenVINO::createNetworkFromModelOptimizer(InferenceEngine::CNNNetwork
CV_TRACE_REGION_NEXT("register_outputs");
auto ngraphFunction = ieNet.getFunction();
CV_Assert(ngraphFunction);
std::vector<std::shared_ptr<ngraph::Node>> ngraphOperations = ngraphFunction->get_ops();
for (auto& it : ieNet.getOutputsInfo())
for (auto& it : ngraphFunction->get_results())
{
CV_TRACE_REGION("output");
const auto& outputName = it.first;
const auto& outputName = it->get_friendly_name();
LayerParams lp;
int lid = cvNet.addLayer(it.first, "", lp);
int lid = cvNet.addLayer(outputName, "", lp);
LayerData& ld = openvino_impl.layers[lid];
@ -835,10 +836,15 @@ Net openvino_readNetwork(
InferenceEngine::CNNNetwork ieNet;
try
{
#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2022_1)
ov::Tensor weights_blob(ov::element::u8, {bufferWeightsSize}, (void*)bufferWeightsPtr);
ieNet = ie.read_model(model, weights_blob);
#else
InferenceEngine::TensorDesc tensorDesc(InferenceEngine::Precision::U8, { bufferWeightsSize }, InferenceEngine::Layout::C);
InferenceEngine::Blob::CPtr weights_blob = InferenceEngine::make_shared_blob<uint8_t>(tensorDesc, (uint8_t*)bufferWeightsPtr, bufferWeightsSize);
ieNet = ie.ReadNetwork(model, weights_blob);
#endif
}
catch (const std::exception& e)
{

View File

@ -39,6 +39,86 @@ cv::String setInferenceEngineBackendType(const cv::String& newBackendType)
CV__DNN_INLINE_NS_END
#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2022_1)
namespace InferenceEngine {
CNNNetwork::CNNNetwork() {}
CNNNetwork::CNNNetwork(std::shared_ptr<ov::Model> model) : model(model) {}
std::shared_ptr<ov::Model> CNNNetwork::getFunction() const {
return model;
}
void CNNNetwork::serialize(const std::string& xmlPath, const std::string& binPath) {
ov::pass::Serialize(xmlPath, binPath).run_on_model(model);
}
void CNNNetwork::reshape(const std::map<std::string, std::vector<size_t> >& shapes) {
std::map<std::string, ov::PartialShape> partialShapes;
for (const auto& it : shapes) {
ov::PartialShape shape;
shape.insert(shape.begin(), it.second.begin(), it.second.end());
partialShapes.insert({it.first, shape});
}
model->reshape(partialShapes);
}
std::vector<std::string> Core::GetAvailableDevices() {
return get_available_devices();
}
void Core::UnregisterPlugin(const std::string& id) {
unload_plugin(id);
}
CNNNetwork Core::ReadNetwork(const std::string& xmlPath, const std::string& binPath) {
return read_model(xmlPath, binPath);
}
ExecutableNetwork Core::LoadNetwork(CNNNetwork net, const std::string& device,
const std::map<std::string, std::string>& config) {
ov::AnyMap props;
for (const auto& it : config) {
props.insert(it);
}
return compile_model(net.getFunction(), device, props);
}
ExecutableNetwork::ExecutableNetwork() {}
ExecutableNetwork::ExecutableNetwork(const ov::CompiledModel& copy) : CompiledModel(copy) {}
ov::InferRequest ExecutableNetwork::CreateInferRequest() { return create_infer_request(); }
} // namespace InferenceEngine
Mat infEngineBlobToMat(const ov::Tensor& blob)
{
std::vector<size_t> dims = blob.get_shape();
std::vector<int> size(dims.begin(), dims.end());
auto precision = blob.get_element_type();
int type = -1;
switch (precision)
{
case ov::element::f32: type = CV_32F; break;
case ov::element::u8: type = CV_8U; break;
default:
CV_Error(Error::StsNotImplemented, "Unsupported blob precision");
}
return Mat(size, type, blob.data());
}
void infEngineBlobsToMats(const ov::TensorVector& blobs,
std::vector<Mat>& mats)
{
mats.resize(blobs.size());
for (int i = 0; i < blobs.size(); ++i)
mats[i] = infEngineBlobToMat(blobs[i]);
}
#else
Mat infEngineBlobToMat(const InferenceEngine::Blob::Ptr& blob)
{
@ -65,7 +145,7 @@ void infEngineBlobsToMats(const std::vector<InferenceEngine::Blob::Ptr>& blobs,
for (int i = 0; i < blobs.size(); ++i)
mats[i] = infEngineBlobToMat(blobs[i]);
}
#endif // OpenVINO >= 2022.1
static bool init_IE_plugins()
{
@ -130,7 +210,11 @@ static bool detectArmPlugin_()
{
if (i->find("CPU") != std::string::npos)
{
#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2022_1)
const std::string name = ie.get_property(*i, ov::device::full_name);
#else
const std::string name = ie.GetMetric(*i, METRIC_KEY(FULL_DEVICE_NAME)).as<std::string>();
#endif
CV_LOG_INFO(NULL, "CPU plugin: " << name);
return name.find("arm_compute::NEON") != std::string::npos;
}
@ -150,7 +234,11 @@ static bool detectMyriadX_(const std::string& device)
{
if (i->find(device) != std::string::npos)
{
#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2022_1)
const std::string name = ie.get_property(*i, ov::device::full_name);
#else
const std::string name = ie.GetMetric(*i, METRIC_KEY(FULL_DEVICE_NAME)).as<std::string>();
#endif
CV_LOG_INFO(NULL, "Myriad device: " << name);
return name.find("MyriadX") != std::string::npos || name.find("Myriad X") != std::string::npos || name.find("HDDL") != std::string::npos;
}

View File

@ -19,11 +19,6 @@
#ifdef HAVE_INF_ENGINE
#define INF_ENGINE_RELEASE_2018R5 2018050000
#define INF_ENGINE_RELEASE_2019R1 2019010000
#define INF_ENGINE_RELEASE_2019R2 2019020000
#define INF_ENGINE_RELEASE_2019R3 2019030000
#define INF_ENGINE_RELEASE_2020_1 2020010000
#define INF_ENGINE_RELEASE_2020_2 2020020000
#define INF_ENGINE_RELEASE_2020_3 2020030000
#define INF_ENGINE_RELEASE_2020_4 2020040000
@ -31,6 +26,7 @@
#define INF_ENGINE_RELEASE_2021_2 2021020000
#define INF_ENGINE_RELEASE_2021_3 2021030000
#define INF_ENGINE_RELEASE_2021_4 2021040000
#define INF_ENGINE_RELEASE_2022_1 2022010000
#ifndef INF_ENGINE_RELEASE
#warning("IE version have not been provided via command-line. Using 2021.4 by default")
@ -48,7 +44,13 @@
#pragma GCC diagnostic ignored "-Wsuggest-override"
#endif
#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2022_1)
#include <openvino/openvino.hpp>
#include <openvino/pass/serialize.hpp>
#include <openvino/pass/convert_fp32_to_fp16.hpp>
#else
#include <inference_engine.hpp>
#endif
#if defined(__GNUC__) && __GNUC__ >= 5
//#pragma GCC diagnostic pop
@ -73,11 +75,17 @@ CV__DNN_INLINE_NS_END
Backend& getInferenceEngineBackendTypeParam();
#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2022_1)
Mat infEngineBlobToMat(const ov::Tensor& blob);
void infEngineBlobsToMats(const ov::TensorVector& blobs,
std::vector<Mat>& mats);
#else
Mat infEngineBlobToMat(const InferenceEngine::Blob::Ptr& blob);
void infEngineBlobsToMats(const std::vector<InferenceEngine::Blob::Ptr>& blobs,
std::vector<Mat>& mats);
#endif // OpenVINO >= 2022.1
CV__DNN_INLINE_NS_BEGIN
@ -90,6 +98,52 @@ bool isArmComputePlugin();
CV__DNN_INLINE_NS_END
// A series of wrappers for classes from OpenVINO API 2.0.
// Need just for less conditional compilation inserts.
#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2022_1)
namespace InferenceEngine {
class CNNNetwork {
public:
CNNNetwork();
CNNNetwork(std::shared_ptr<ov::Model> model);
std::shared_ptr<ov::Model> getFunction() const;
void serialize(const std::string& xmlPath, const std::string& binPath);
void reshape(const std::map<std::string, std::vector<size_t> >& shapes);
private:
std::shared_ptr<ov::Model> model = nullptr;
};
typedef ov::InferRequest InferRequest;
class ExecutableNetwork : public ov::CompiledModel {
public:
ExecutableNetwork();
ExecutableNetwork(const ov::CompiledModel& copy);
ov::InferRequest CreateInferRequest();
};
class Core : public ov::Core {
public:
std::vector<std::string> GetAvailableDevices();
void UnregisterPlugin(const std::string& id);
CNNNetwork ReadNetwork(const std::string& xmlPath, const std::string& binPath);
ExecutableNetwork LoadNetwork(CNNNetwork net, const std::string& device,
const std::map<std::string, std::string>& config);
};
}
#endif // OpenVINO >= 2022.1
InferenceEngine::Core& getCore(const std::string& id);

View File

@ -531,7 +531,7 @@ TEST_P(DNNTestNetwork, FastNeuralStyle_eccv16)
if (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD)
{
l1 = 0.4;
lInf = 7.45;
lInf = 7.46;
}
else if (target == DNN_TARGET_CUDA_FP16)
{

View File

@ -725,18 +725,21 @@ TEST_P(Test_Caffe_nets, FasterRCNN_vgg16)
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
#endif
double scoreDiff = 0.0;
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2022010000)
// Check 'backward_compatible_check || in_out_elements_equal' failed at core/src/op/reshape.cpp:427:
// While validating node 'v1::Reshape bbox_pred_reshape (bbox_pred[0]:f32{1,84}, Constant_265242[0]:i64{4}) -> (f32{?,?,?,?})' with friendly_name 'bbox_pred_reshape':
// Requested output shape {1,6300,4,1} is incompatible with input shape {1, 84}
if (target == DNN_TARGET_MYRIAD)
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
if (target == DNN_TARGET_OPENCL_FP16)
scoreDiff = 0.02;
#endif
static Mat ref = (Mat_<float>(3, 7) << 0, 2, 0.949398, 99.2454, 210.141, 601.205, 462.849,
0, 7, 0.997022, 481.841, 92.3218, 722.685, 175.953,
0, 12, 0.993028, 133.221, 189.377, 350.994, 563.166);
testFaster("faster_rcnn_vgg16.prototxt", "VGG16_faster_rcnn_final.caffemodel", ref);
testFaster("faster_rcnn_vgg16.prototxt", "VGG16_faster_rcnn_final.caffemodel", ref, scoreDiff);
}
TEST_P(Test_Caffe_nets, FasterRCNN_zf)

View File

@ -638,6 +638,11 @@ TEST_P(Test_Darknet_nets, YOLOv3)
double scoreDiff = 8e-5, iouDiff = 3e-4;
if (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD)
{
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2022010000)
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
scoreDiff = 0.009;
else
#endif
scoreDiff = 0.006;
iouDiff = 0.042;
}
@ -771,6 +776,7 @@ TEST_P(Test_Darknet_nets, YOLOv4)
// accuracy (batch 2)
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL_FP16)
{
scoreDiff = 0.008f;
iouDiff = 0.05f;
}
// accuracy

View File

@ -438,6 +438,9 @@ TEST_P(DNNTestOpenVINO, models)
{
auto dstIt = cvOutputsMap.find(srcIt.first);
CV_Assert(dstIt != cvOutputsMap.end());
dstIt->second.convertTo(dstIt->second, srcIt.second.type());
double normInf = cvtest::norm(srcIt.second, dstIt->second, cv::NORM_INF);
EXPECT_LE(normInf, eps) << "output=" << srcIt.first;
}

View File

@ -1292,7 +1292,7 @@ TEST_P(Layer_Test_Convolution_DLDT, Accuracy)
if (backendId == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
ASSERT_EQ(net.getLayer(outLayers[0])->type, "Convolution");
else
ASSERT_EQ(net.getLayer(outLayers[0])->type, "Add");
ASSERT_EQ(net.getLayer(outLayers[0])->type, "Result");
}
TEST_P(Layer_Test_Convolution_DLDT, setInput_uint8)

View File

@ -447,6 +447,10 @@ TEST_P(Test_Model, DetectionOutput)
{
if (backend == DNN_BACKEND_OPENCV)
scoreDiff = 4e-3;
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2022010000)
else if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
scoreDiff = 4e-2;
#endif
else
scoreDiff = 2e-2;
iouDiff = 1.8e-1;