From 0e1ef8f8e1ef57cf1fd9abf5a839b68bb5253d5f Mon Sep 17 00:00:00 2001 From: Lubov Batanina Date: Tue, 6 Aug 2019 22:20:26 +0300 Subject: [PATCH] Merge pull request #15184 from l-bat:IE_R2 Support new IE API (#15184) * Add support OpenVINO R2 for layers * Add Core API * Fix tests * Fix expectNoFallbacksFromIE for ONNX nets * Remove deprecated API * Remove td * Remove TargetDevice * Fix Async * Add test * Fix detectMyriadX * Fix test * Fix warning --- modules/dnn/src/dnn.cpp | 34 +++-- modules/dnn/src/layers/blank_layer.cpp | 11 +- modules/dnn/src/layers/concat_layer.cpp | 2 +- modules/dnn/src/layers/convolution_layer.cpp | 25 ++-- modules/dnn/src/layers/normalize_bbox_layer.cpp | 12 +- modules/dnn/src/layers/pooling_layer.cpp | 2 + modules/dnn/src/layers/scale_layer.cpp | 11 +- modules/dnn/src/layers/slice_layer.cpp | 10 +- modules/dnn/src/layers/softmax_layer.cpp | 3 +- modules/dnn/src/op_inf_engine.cpp | 179 +++++++++++++++--------- modules/dnn/src/op_inf_engine.hpp | 12 +- modules/dnn/test/test_ie_models.cpp | 40 ++++-- modules/dnn/test/test_misc.cpp | 36 +++++ 13 files changed, 247 insertions(+), 130 deletions(-) diff --git a/modules/dnn/src/dnn.cpp b/modules/dnn/src/dnn.cpp index 9e232c4..eae7347 100644 --- a/modules/dnn/src/dnn.cpp +++ b/modules/dnn/src/dnn.cpp @@ -713,21 +713,23 @@ struct DataLayer : public Layer CV_Assert(numChannels <= 4); // Scale - auto weights = InferenceEngine::make_shared_blob(InferenceEngine::Precision::FP32, - {numChannels}); + InferenceEngine::TensorDesc td(InferenceEngine::Precision::FP32, {numChannels}, + InferenceEngine::Layout::C); + auto weights = InferenceEngine::make_shared_blob(td); weights->allocate(); - weights->set(std::vector(numChannels, scaleFactors[0])); + + float* weight_buf = weights->buffer().as(); + std::fill(weight_buf, weight_buf + numChannels, scaleFactors[0]); // Mean subtraction - auto biases = InferenceEngine::make_shared_blob(InferenceEngine::Precision::FP32, - {numChannels}); + auto biases = InferenceEngine::make_shared_blob(td); biases->allocate(); - std::vector biasesVec(numChannels); + float* bias_buf = biases->buffer().as(); + for (int i = 0; i < numChannels; ++i) { - biasesVec[i] = -means[0][i] * scaleFactors[0]; + bias_buf[i] = -means[0][i] * scaleFactors[0]; } - biases->set(biasesVec); InferenceEngine::Builder::Layer ieLayer = InferenceEngine::Builder::ScaleShiftLayer(name); addConstantData("weights", weights, ieLayer); @@ -1473,7 +1475,11 @@ struct Net::Impl for (int i = 0; i < ld.outputBlobsWrappers.size(); ++i) { InferenceEngine::DataPtr dataPtr = infEngineDataNode(ld.outputBlobsWrappers[i]); +#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LE(2019010000) dataPtr->name = netInputLayer->outNames.empty() ? ld.name : netInputLayer->outNames[i]; +#else + dataPtr->setName(netInputLayer->outNames.empty() ? ld.name : netInputLayer->outNames[i]); +#endif } } else @@ -1481,7 +1487,11 @@ struct Net::Impl for (int i = 0; i < ld.outputBlobsWrappers.size(); ++i) { InferenceEngine::DataPtr dataPtr = infEngineDataNode(ld.outputBlobsWrappers[i]); +#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LE(2019010000) dataPtr->name = ld.name; +#else + dataPtr->setName(ld.name); +#endif } } } @@ -1502,7 +1512,11 @@ struct Net::Impl for (int i = 0; i < ld.inputBlobsWrappers.size(); ++i) { InferenceEngine::DataPtr dataPtr = infEngineDataNode(ld.inputBlobsWrappers[i]); +#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LE(2019010000) dataPtr->name = netInputLayer->outNames[i]; +#else + dataPtr->setName(netInputLayer->outNames[i]); +#endif } } else @@ -1510,7 +1524,11 @@ struct Net::Impl for (int i = 0; i < ld.outputBlobsWrappers.size(); ++i) { InferenceEngine::DataPtr dataPtr = infEngineDataNode(ld.outputBlobsWrappers[i]); +#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LE(2019010000) dataPtr->name = ld.name; +#else + dataPtr->setName(ld.name); +#endif } } ieNode->net->addBlobs(ld.inputBlobsWrappers); diff --git a/modules/dnn/src/layers/blank_layer.cpp b/modules/dnn/src/layers/blank_layer.cpp index 8865462..ef44ed7 100644 --- a/modules/dnn/src/layers/blank_layer.cpp +++ b/modules/dnn/src/layers/blank_layer.cpp @@ -111,7 +111,8 @@ public: virtual Ptr initInfEngine(const std::vector >& inputs) CV_OVERRIDE { InferenceEngine::DataPtr input = infEngineDataNode(inputs[0]); - CV_Assert(!input->dims.empty()); + std::vector dims = input->getDims(); + CV_Assert(!dims.empty()); InferenceEngine::Builder::Layer ieLayer(name); ieLayer.setName(name); @@ -122,12 +123,10 @@ public: else { ieLayer.setType("Split"); - ieLayer.getParameters()["axis"] = input->dims.size() - 1; - ieLayer.getParameters()["out_sizes"] = input->dims[0]; + ieLayer.getParameters()["axis"] = dims.size() - 1; + ieLayer.getParameters()["out_sizes"] = dims[0]; } - std::vector shape(input->dims); - std::reverse(shape.begin(), shape.end()); - ieLayer.setInputPorts({InferenceEngine::Port(shape)}); + ieLayer.setInputPorts({InferenceEngine::Port(dims)}); ieLayer.setOutputPorts(std::vector(1)); return Ptr(new InfEngineBackendNode(ieLayer)); } diff --git a/modules/dnn/src/layers/concat_layer.cpp b/modules/dnn/src/layers/concat_layer.cpp index d7bef15..929d6bd 100644 --- a/modules/dnn/src/layers/concat_layer.cpp +++ b/modules/dnn/src/layers/concat_layer.cpp @@ -304,7 +304,7 @@ public: InferenceEngine::DataPtr input = infEngineDataNode(inputs[0]); InferenceEngine::Builder::ConcatLayer ieLayer(name); - ieLayer.setAxis(clamp(axis, input->dims.size())); + ieLayer.setAxis(clamp(axis, input->getDims().size())); ieLayer.setInputPorts(std::vector(inputs.size())); return Ptr(new InfEngineBackendNode(ieLayer)); } diff --git a/modules/dnn/src/layers/convolution_layer.cpp b/modules/dnn/src/layers/convolution_layer.cpp index caa4718..cec7bf1 100644 --- a/modules/dnn/src/layers/convolution_layer.cpp +++ b/modules/dnn/src/layers/convolution_layer.cpp @@ -465,15 +465,14 @@ public: virtual Ptr initInfEngine(const std::vector > &inputs) CV_OVERRIDE { InferenceEngine::DataPtr input = infEngineDataNode(inputs[0]); - CV_Assert(input->dims.size() == 4 || input->dims.size() == 5); - - const int inpCn = input->dims[input->dims.size() - 2]; // NOTE: input->dims are reversed (WHIO or WHDIO) + std::vector dims = input->getDims(); + CV_Assert(dims.size() == 4 || dims.size() == 5); + const int inpCn = dims[1]; const int outCn = blobs[0].size[0]; const int inpGroupCn = blobs[0].size[1]; const int group = inpCn / inpGroupCn; - - InferenceEngine::Layout layout = (input->dims.size() == 4) ? InferenceEngine::Layout::OIHW : - InferenceEngine::Layout::NCDHW; + InferenceEngine::Layout layout = (dims.size() == 4) ? InferenceEngine::Layout::OIHW : + InferenceEngine::Layout::NCDHW; auto ieWeights = wrapToInfEngineBlob(blobs[0], layout); if (fusedWeights) @@ -485,9 +484,10 @@ public: } else { - ieWeights = InferenceEngine::make_shared_blob( - InferenceEngine::Precision::FP32, layout, - ieWeights->dims()); + ieWeights = InferenceEngine::make_shared_blob({ + InferenceEngine::Precision::FP32, + ieWeights->getTensorDesc().getDims(), layout + }); ieWeights->allocate(); Mat newWeights = infEngineBlobToMat(ieWeights).reshape(1, outCn); @@ -1877,9 +1877,10 @@ public: auto ieWeights = wrapToInfEngineBlob(blobs[0], layout); if (fusedWeights) { - ieWeights = InferenceEngine::make_shared_blob( - InferenceEngine::Precision::FP32, layout, - ieWeights->dims()); + ieWeights = InferenceEngine::make_shared_blob({ + InferenceEngine::Precision::FP32, + ieWeights->getTensorDesc().getDims(), layout + }); ieWeights->allocate(); int inpCn = blobs[0].size[0]; diff --git a/modules/dnn/src/layers/normalize_bbox_layer.cpp b/modules/dnn/src/layers/normalize_bbox_layer.cpp index 09fac59..b6b973d 100644 --- a/modules/dnn/src/layers/normalize_bbox_layer.cpp +++ b/modules/dnn/src/layers/normalize_bbox_layer.cpp @@ -261,7 +261,8 @@ public: virtual Ptr initInfEngine(const std::vector >& inputs) CV_OVERRIDE { InferenceEngine::DataPtr input = infEngineDataNode(inputs[0]); - if (input->dims.size() == 4) + std::vector dims = input->getDims(); + if (dims.size() == 4) { InferenceEngine::Builder::NormalizeLayer ieLayer(name); @@ -270,13 +271,14 @@ public: ieLayer.setEpsilon(epsilon); InferenceEngine::Builder::Layer l = ieLayer; - const int numChannels = input->dims[2]; // NOTE: input->dims are reversed (whcn) + const int numChannels = dims[1]; InferenceEngine::Blob::Ptr weights; if (blobs.empty()) { - weights = InferenceEngine::make_shared_blob(InferenceEngine::Precision::FP32, - InferenceEngine::Layout::C, - {(size_t)numChannels}); + weights = InferenceEngine::make_shared_blob({ + InferenceEngine::Precision::FP32, + {(size_t)numChannels}, InferenceEngine::Layout::C + }); weights->allocate(); Mat weightsMat = infEngineBlobToMat(weights).reshape(1, numChannels); diff --git a/modules/dnn/src/layers/pooling_layer.cpp b/modules/dnn/src/layers/pooling_layer.cpp index 08436ee..060bf96 100644 --- a/modules/dnn/src/layers/pooling_layer.cpp +++ b/modules/dnn/src/layers/pooling_layer.cpp @@ -166,9 +166,11 @@ public: if (kernel_size.size() == 3) return preferableTarget == DNN_TARGET_CPU; if (preferableTarget == DNN_TARGET_MYRIAD) { +#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LE(INF_ENGINE_RELEASE_2019R1) if (type == MAX && (pad_l == 1 && pad_t == 1) && stride == Size(2, 2) ) { return !isMyriadX(); } +#endif return type == MAX || type == AVE; } else diff --git a/modules/dnn/src/layers/scale_layer.cpp b/modules/dnn/src/layers/scale_layer.cpp index 5e22519..4486a0f 100644 --- a/modules/dnn/src/layers/scale_layer.cpp +++ b/modules/dnn/src/layers/scale_layer.cpp @@ -207,12 +207,13 @@ public: } else { - auto weights = InferenceEngine::make_shared_blob(InferenceEngine::Precision::FP32, - {numChannels}); + auto weights = InferenceEngine::make_shared_blob({ + InferenceEngine::Precision::FP32, {(size_t)numChannels}, + InferenceEngine::Layout::C + }); weights->allocate(); - - std::vector ones(numChannels, 1); - weights->set(ones); + float* buf = weights->buffer().as(); + std::fill(buf, buf + numChannels, 1); addConstantData("weights", weights, l); } if (hasBias) diff --git a/modules/dnn/src/layers/slice_layer.cpp b/modules/dnn/src/layers/slice_layer.cpp index 7640d46..4305551 100644 --- a/modules/dnn/src/layers/slice_layer.cpp +++ b/modules/dnn/src/layers/slice_layer.cpp @@ -301,14 +301,14 @@ public: { std::vector outShape(numDims); for (int i = 0; i < numDims; ++i) - outShape[numDims - 1 - i] = sliceRanges[0][i].size(); + outShape[i] = sliceRanges[0][i].size(); ieLayer.getInputPorts()[1].setParameter("type", "weights"); - // Fake blob which will be moved to inputs (as weights). - auto shapeSource = InferenceEngine::make_shared_blob( - InferenceEngine::Precision::FP32, - InferenceEngine::Layout::ANY, outShape); + auto shapeSource = InferenceEngine::make_shared_blob({ + InferenceEngine::Precision::FP32, outShape, + InferenceEngine::Layout::ANY + }); shapeSource->allocate(); addConstantData("weights", shapeSource, ieLayer); } diff --git a/modules/dnn/src/layers/softmax_layer.cpp b/modules/dnn/src/layers/softmax_layer.cpp index 0c19f01..47d6ed9 100644 --- a/modules/dnn/src/layers/softmax_layer.cpp +++ b/modules/dnn/src/layers/softmax_layer.cpp @@ -315,7 +315,8 @@ public: InferenceEngine::DataPtr input = infEngineDataNode(inputs[0]); InferenceEngine::Builder::SoftMaxLayer ieLayer(name); - ieLayer.setAxis(clamp(axisRaw, input->dims.size())); + ieLayer.setAxis(clamp(axisRaw, input->getDims().size())); + return Ptr(new InfEngineBackendNode(ieLayer)); } #endif // HAVE_INF_ENGINE diff --git a/modules/dnn/src/op_inf_engine.cpp b/modules/dnn/src/op_inf_engine.cpp index d464b88..74fbb85 100644 --- a/modules/dnn/src/op_inf_engine.cpp +++ b/modules/dnn/src/op_inf_engine.cpp @@ -45,13 +45,13 @@ infEngineWrappers(const std::vector >& ptrs) InfEngineBackendNet::InfEngineBackendNet() : netBuilder("") { hasNetOwner = false; - targetDevice = InferenceEngine::TargetDevice::eCPU; + device_name = "CPU"; } InfEngineBackendNet::InfEngineBackendNet(InferenceEngine::CNNNetwork& net) : netBuilder(""), cnn(net) { hasNetOwner = true; - targetDevice = InferenceEngine::TargetDevice::eCPU; + device_name = "CPU"; } void InfEngineBackendNet::connect(const std::vector >& inputs, @@ -66,16 +66,13 @@ void InfEngineBackendNet::connect(const std::vector >& input for (size_t i = 0; i < inpWrappers.size(); ++i) { const auto& inp = inpWrappers[i]; - const std::string& inpName = inp->dataPtr->name; + const std::string& inpName = inp->dataPtr->getName(); int inpId; it = layers.find(inpName); if (it == layers.end()) { InferenceEngine::Builder::InputLayer inpLayer(!inpName.empty() ? inpName : kDefaultInpLayerName); - - std::vector shape(inp->blob->dims()); - std::reverse(shape.begin(), shape.end()); - + std::vector shape(inp->blob->getTensorDesc().getDims()); inpLayer.setPort(InferenceEngine::Port(shape)); inpId = netBuilder.addLayer(inpLayer); @@ -89,7 +86,11 @@ void InfEngineBackendNet::connect(const std::vector >& input } CV_Assert(!outputs.empty()); InferenceEngine::DataPtr dataPtr = infEngineDataNode(outputs[0]); +#if INF_ENGINE_VER_MAJOR_LE(INF_ENGINE_RELEASE_2019R1) dataPtr->name = layerName; +#else + dataPtr->setName(layerName); +#endif } void InfEngineBackendNet::init(int targetId) @@ -115,21 +116,22 @@ void InfEngineBackendNet::init(int targetId) switch (targetId) { - case DNN_TARGET_CPU: - targetDevice = InferenceEngine::TargetDevice::eCPU; - break; - case DNN_TARGET_OPENCL: case DNN_TARGET_OPENCL_FP16: - targetDevice = InferenceEngine::TargetDevice::eGPU; - break; - case DNN_TARGET_MYRIAD: - targetDevice = InferenceEngine::TargetDevice::eMYRIAD; - break; - case DNN_TARGET_FPGA: - targetDevice = InferenceEngine::TargetDevice::eFPGA; - break; - default: - CV_Error(Error::StsError, format("Unknown target identifier: %d", targetId)); - } + case DNN_TARGET_CPU: + device_name = "CPU"; + break; + case DNN_TARGET_OPENCL: + case DNN_TARGET_OPENCL_FP16: + device_name = "GPU"; + break; + case DNN_TARGET_MYRIAD: + device_name = "MYRIAD"; + break; + case DNN_TARGET_FPGA: + device_name = "FPGA"; + break; + default: + CV_Error(Error::StsNotImplemented, "Unknown target"); + }; for (const auto& name : requestedOutputs) { @@ -141,14 +143,14 @@ void InfEngineBackendNet::init(int targetId) const std::string& name = it.first; auto blobIt = allBlobs.find(name); CV_Assert(blobIt != allBlobs.end()); - it.second->setPrecision(blobIt->second->precision()); + it.second->setPrecision(blobIt->second->getTensorDesc().getPrecision()); } for (const auto& it : cnn.getOutputsInfo()) { const std::string& name = it.first; auto blobIt = allBlobs.find(name); CV_Assert(blobIt != allBlobs.end()); - it.second->setPrecision(blobIt->second->precision()); // Should be always FP32 + it.second->setPrecision(blobIt->second->getTensorDesc().getPrecision()); // Should be always FP32 } initPlugin(cnn); @@ -223,16 +225,13 @@ static InferenceEngine::Layout estimateLayout(const Mat& m) static InferenceEngine::DataPtr wrapToInfEngineDataNode(const Mat& m, const std::string& name = "") { - std::vector reversedShape(&m.size[0], &m.size[0] + m.dims); - std::reverse(reversedShape.begin(), reversedShape.end()); + std::vector shape(&m.size[0], &m.size[0] + m.dims); if (m.type() == CV_32F) - return InferenceEngine::DataPtr( - new InferenceEngine::Data(name, reversedShape, InferenceEngine::Precision::FP32, estimateLayout(m)) - ); + 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, reversedShape, InferenceEngine::Precision::U8, estimateLayout(m)) - ); + return InferenceEngine::DataPtr(new InferenceEngine::Data(name, + {InferenceEngine::Precision::U8, shape, estimateLayout(m)})); else CV_Error(Error::StsNotImplemented, format("Unsupported data type %d", m.type())); } @@ -241,33 +240,33 @@ InferenceEngine::Blob::Ptr wrapToInfEngineBlob(const Mat& m, const std::vector(InferenceEngine::Precision::FP32, - layout, shape, (float*)m.data); + return InferenceEngine::make_shared_blob( + {InferenceEngine::Precision::FP32, shape, layout}, (float*)m.data); else if (m.type() == CV_8U) - return InferenceEngine::make_shared_blob(InferenceEngine::Precision::U8, - layout, shape, (uint8_t*)m.data); + return InferenceEngine::make_shared_blob( + {InferenceEngine::Precision::U8, shape, layout}, (uint8_t*)m.data); else CV_Error(Error::StsNotImplemented, format("Unsupported data type %d", m.type())); } InferenceEngine::Blob::Ptr wrapToInfEngineBlob(const Mat& m, InferenceEngine::Layout layout) { - std::vector reversedShape(&m.size[0], &m.size[0] + m.dims); - std::reverse(reversedShape.begin(), reversedShape.end()); - return wrapToInfEngineBlob(m, reversedShape, layout); + std::vector shape(&m.size[0], &m.size[0] + m.dims); + return wrapToInfEngineBlob(m, shape, layout); } InferenceEngine::Blob::Ptr cloneBlob(const InferenceEngine::Blob::Ptr& blob) { - InferenceEngine::Precision precision = blob->precision(); InferenceEngine::Blob::Ptr copy; + auto description = blob->getTensorDesc(); + InferenceEngine::Precision precision = description.getPrecision(); if (precision == InferenceEngine::Precision::FP32) { - copy = InferenceEngine::make_shared_blob(precision, blob->layout(), blob->dims()); + copy = InferenceEngine::make_shared_blob(description); } else if (precision == InferenceEngine::Precision::U8) { - copy = InferenceEngine::make_shared_blob(precision, blob->layout(), blob->dims()); + copy = InferenceEngine::make_shared_blob(description); } else CV_Error(Error::StsNotImplemented, "Unsupported blob precision"); @@ -296,10 +295,8 @@ InfEngineBackendWrapper::InfEngineBackendWrapper(Ptr wrapper) Ptr ieWrapper = wrapper.dynamicCast(); CV_Assert(!ieWrapper.empty()); InferenceEngine::DataPtr srcData = ieWrapper->dataPtr; - dataPtr = InferenceEngine::DataPtr( - new InferenceEngine::Data(srcData->name, srcData->dims, srcData->precision, - srcData->layout) - ); + + dataPtr = InferenceEngine::DataPtr(new InferenceEngine::Data(srcData->getName(), srcData->getTensorDesc())); blob = ieWrapper->blob; } @@ -323,12 +320,19 @@ void InfEngineBackendWrapper::setHostDirty() } -static std::map& getSharedPlugins() +#if INF_ENGINE_VER_MAJOR_LE(INF_ENGINE_RELEASE_2019R1) +static std::map& getSharedPlugins() { - static std::map sharedPlugins; + static std::map sharedPlugins; return sharedPlugins; } - +#else +static InferenceEngine::Core& getCore() +{ + static InferenceEngine::Core core; + return core; +} +#endif #if !defined(OPENCV_DNN_IE_VPU_TYPE_DEFAULT) static bool detectMyriadX_() @@ -361,24 +365,29 @@ static bool detectMyriadX_() InferenceEngine::CNNNetwork cnn = InferenceEngine::CNNNetwork( InferenceEngine::Builder::convertToICNNNetwork(builder.build())); - InferenceEngine::TargetDevice device = InferenceEngine::TargetDevice::eMYRIAD; +#if INF_ENGINE_VER_MAJOR_LE(INF_ENGINE_RELEASE_2019R1) InferenceEngine::InferenceEnginePluginPtr enginePtr; { AutoLock lock(getInitializationMutex()); auto& sharedPlugins = getSharedPlugins(); - auto pluginIt = sharedPlugins.find(device); + auto pluginIt = sharedPlugins.find("MYRIAD"); if (pluginIt != sharedPlugins.end()) { enginePtr = pluginIt->second; } else { auto dispatcher = InferenceEngine::PluginDispatcher({""}); - enginePtr = dispatcher.getSuitablePlugin(device); - sharedPlugins[device] = enginePtr; + enginePtr = dispatcher.getPluginByDevice("MYRIAD"); + sharedPlugins["MYRIAD"] = enginePtr; } } auto plugin = InferenceEngine::InferencePlugin(enginePtr); try { auto netExec = plugin.LoadNetwork(cnn, {{"VPU_PLATFORM", "VPU_2480"}}); +#else + try + { + auto netExec = getCore().LoadNetwork(cnn, "MYRIAD", {{"VPU_PLATFORM", "VPU_2480"}}); +#endif auto infRequest = netExec.CreateInferRequest(); } catch(...) { return false; @@ -387,38 +396,41 @@ static bool detectMyriadX_() } #endif // !defined(OPENCV_DNN_IE_VPU_TYPE_DEFAULT) -void InfEngineBackendNet::initPlugin(InferenceEngine::ICNNNetwork& net) +void InfEngineBackendNet::initPlugin(InferenceEngine::CNNNetwork& net) { CV_Assert(!isInitialized()); try { AutoLock lock(getInitializationMutex()); +#if INF_ENGINE_VER_MAJOR_LE(INF_ENGINE_RELEASE_2019R1) auto& sharedPlugins = getSharedPlugins(); - auto pluginIt = sharedPlugins.find(targetDevice); + auto pluginIt = sharedPlugins.find(device_name); if (pluginIt != sharedPlugins.end()) { enginePtr = pluginIt->second; } else +#endif { +#if INF_ENGINE_VER_MAJOR_LE(INF_ENGINE_RELEASE_2019R1) auto dispatcher = InferenceEngine::PluginDispatcher({""}); - if (targetDevice == InferenceEngine::TargetDevice::eFPGA) + if (device_name == "FPGA") enginePtr = dispatcher.getPluginByDevice("HETERO:FPGA,CPU"); else - enginePtr = dispatcher.getSuitablePlugin(targetDevice); - sharedPlugins[targetDevice] = enginePtr; - + enginePtr = dispatcher.getPluginByDevice(device_name); + sharedPlugins[device_name] = enginePtr; +#else + isInit = true; +#endif std::vector candidates; - std::string param_pluginPath = utils::getConfigurationParameterString("OPENCV_DNN_IE_EXTRA_PLUGIN_PATH", ""); if (!param_pluginPath.empty()) { candidates.push_back(param_pluginPath); } - if (targetDevice == InferenceEngine::TargetDevice::eCPU || - targetDevice == InferenceEngine::TargetDevice::eFPGA) + if (device_name == "CPU" || device_name == "FPGA") { std::string suffixes[] = {"_avx2", "_sse4", ""}; bool haveFeature[] = { @@ -448,7 +460,12 @@ void InfEngineBackendNet::initPlugin(InferenceEngine::ICNNNetwork& net) { InferenceEngine::IExtensionPtr extension = InferenceEngine::make_so_pointer(libName); + +#if INF_ENGINE_VER_MAJOR_LE(INF_ENGINE_RELEASE_2019R1) enginePtr->AddExtension(extension, 0); +#else + getCore().AddExtension(extension, "CPU"); +#endif CV_LOG_INFO(NULL, "DNN-IE: Loaded extension plugin: " << libName); found = true; break; @@ -462,14 +479,24 @@ void InfEngineBackendNet::initPlugin(InferenceEngine::ICNNNetwork& net) // Some of networks can work without a library of extra layers. #ifndef _WIN32 // Limit the number of CPU threads. +#if INF_ENGINE_VER_MAJOR_LE(INF_ENGINE_RELEASE_2019R1) enginePtr->SetConfig({{ InferenceEngine::PluginConfigParams::KEY_CPU_THREADS_NUM, format("%d", getNumThreads()), }}, 0); +#else + if (device_name == "CPU") + getCore().SetConfig({{ + InferenceEngine::PluginConfigParams::KEY_CPU_THREADS_NUM, format("%d", getNumThreads()), + }}, device_name); +#endif #endif } +#if INF_ENGINE_VER_MAJOR_LE(INF_ENGINE_RELEASE_2019R1) plugin = InferenceEngine::InferencePlugin(enginePtr); - netExec = plugin.LoadNetwork(net, {}); +#else + netExec = getCore().LoadNetwork(net, device_name); +#endif } catch (const std::exception& ex) { @@ -479,7 +506,11 @@ void InfEngineBackendNet::initPlugin(InferenceEngine::ICNNNetwork& net) bool InfEngineBackendNet::isInitialized() { +#if INF_ENGINE_VER_MAJOR_LE(INF_ENGINE_RELEASE_2019R1) return (bool)enginePtr; +#else + return isInit; +#endif } void InfEngineBackendNet::addBlobs(const std::vector >& ptrs) @@ -487,7 +518,7 @@ void InfEngineBackendNet::addBlobs(const std::vector >& auto wrappers = infEngineWrappers(ptrs); for (const auto& wrapper : wrappers) { - std::string name = wrapper->dataPtr->name; + std::string name = wrapper->dataPtr->getName(); name = name.empty() ? kDefaultInpLayerName : name; allBlobs.insert({name, wrapper->blob}); } @@ -502,7 +533,7 @@ void InfEngineBackendNet::InfEngineReqWrapper::makePromises(const std::vectorfutureMat = outProms[i].getArrayResult(); - outsNames[i] = outs[i]->dataPtr->name; + outsNames[i] = outs[i]->dataPtr->getName(); } } @@ -626,11 +657,12 @@ void InfEngineBackendNet::forward(const std::vector >& outBl Mat infEngineBlobToMat(const InferenceEngine::Blob::Ptr& blob) { // NOTE: Inference Engine sizes are reversed. - std::vector dims = blob->dims(); - std::vector size(dims.rbegin(), dims.rend()); + std::vector dims = blob->getTensorDesc().getDims(); + std::vector size(dims.begin(), dims.end()); + auto precision = blob->getTensorDesc().getPrecision(); int type = -1; - switch (blob->precision()) + switch (precision) { case InferenceEngine::Precision::FP32: type = CV_32F; break; case InferenceEngine::Precision::U8: type = CV_8U; break; @@ -684,7 +716,10 @@ void InfEngineBackendLayer::forward(InputArrayOfArrays inputs, OutputArrayOfArra InferenceEngine::Blob::Ptr convertFp16(const InferenceEngine::Blob::Ptr& blob) { - auto halfs = InferenceEngine::make_shared_blob(InferenceEngine::Precision::FP16, blob->layout(), blob->dims()); + auto halfs = InferenceEngine::make_shared_blob({ + InferenceEngine::Precision::FP16, blob->getTensorDesc().getDims(), + blob->getTensorDesc().getLayout() + }); halfs->allocate(); Mat floatsData(1, blob->size(), CV_32F, blob->buffer()); Mat halfsData(1, blob->size(), CV_16SC1, halfs->buffer()); @@ -731,7 +766,11 @@ void resetMyriadDevice() { #ifdef HAVE_INF_ENGINE AutoLock lock(getInitializationMutex()); - getSharedPlugins().erase(InferenceEngine::TargetDevice::eMYRIAD); +#if INF_ENGINE_VER_MAJOR_LE(INF_ENGINE_RELEASE_2019R1) + getSharedPlugins().erase("MYRIAD"); +#else + getCore().UnregisterPlugin("MYRIAD"); +#endif #endif // HAVE_INF_ENGINE } diff --git a/modules/dnn/src/op_inf_engine.hpp b/modules/dnn/src/op_inf_engine.hpp index f131d17..12a0b7e 100644 --- a/modules/dnn/src/op_inf_engine.hpp +++ b/modules/dnn/src/op_inf_engine.hpp @@ -92,18 +92,22 @@ public: void forward(const std::vector >& outBlobsWrappers, bool isAsync); - void initPlugin(InferenceEngine::ICNNNetwork& net); + void initPlugin(InferenceEngine::CNNNetwork& net); void addBlobs(const std::vector >& ptrs); private: InferenceEngine::Builder::Network netBuilder; - InferenceEngine::InferenceEnginePluginPtr enginePtr; - InferenceEngine::InferencePlugin plugin; InferenceEngine::ExecutableNetwork netExec; InferenceEngine::BlobMap allBlobs; - InferenceEngine::TargetDevice targetDevice; + std::string device_name; +#if INF_ENGINE_VER_MAJOR_LE(2019010000) + InferenceEngine::InferenceEnginePluginPtr enginePtr; + InferenceEngine::InferencePlugin plugin; +#else + bool isInit = false; +#endif struct InfEngineReqWrapper { diff --git a/modules/dnn/test/test_ie_models.cpp b/modules/dnn/test/test_ie_models.cpp index 2698370..08c3247 100644 --- a/modules/dnn/test/test_ie_models.cpp +++ b/modules/dnn/test/test_ie_models.cpp @@ -136,13 +136,10 @@ static const std::vector getOpenVINOTestModelsList() static inline void genData(const std::vector& dims, Mat& m, Blob::Ptr& dataPtr) { - std::vector reversedDims(dims.begin(), dims.end()); - std::reverse(reversedDims.begin(), reversedDims.end()); - - m.create(reversedDims, CV_32F); + m.create(std::vector(dims.begin(), dims.end()), CV_32F); randu(m, -1, 1); - dataPtr = make_shared_blob(Precision::FP32, dims, (float*)m.data); + dataPtr = make_shared_blob({Precision::FP32, dims, Layout::ANY}, (float*)m.data); } void runIE(Target target, const std::string& xmlPath, const std::string& binPath, @@ -154,32 +151,42 @@ void runIE(Target target, const std::string& xmlPath, const std::string& binPath CNNNetwork net = reader.getNetwork(); + std::string device_name; + +#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GT(2019010000) + Core ie; +#else InferenceEnginePluginPtr enginePtr; InferencePlugin plugin; +#endif ExecutableNetwork netExec; InferRequest infRequest; + try { - auto dispatcher = InferenceEngine::PluginDispatcher({""}); switch (target) { case DNN_TARGET_CPU: - enginePtr = dispatcher.getSuitablePlugin(TargetDevice::eCPU); + device_name = "CPU"; break; case DNN_TARGET_OPENCL: case DNN_TARGET_OPENCL_FP16: - enginePtr = dispatcher.getSuitablePlugin(TargetDevice::eGPU); + device_name = "GPU"; break; case DNN_TARGET_MYRIAD: - enginePtr = dispatcher.getSuitablePlugin(TargetDevice::eMYRIAD); + device_name = "MYRIAD"; break; case DNN_TARGET_FPGA: - enginePtr = dispatcher.getPluginByDevice("HETERO:FPGA,CPU"); + device_name = "FPGA"; break; default: CV_Error(Error::StsNotImplemented, "Unknown target"); }; +#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LE(2019010000) + auto dispatcher = InferenceEngine::PluginDispatcher({""}); + enginePtr = dispatcher.getPluginByDevice(device_name); +#endif if (target == DNN_TARGET_CPU || target == DNN_TARGET_FPGA) { std::string suffixes[] = {"_avx2", "_sse4", ""}; @@ -202,16 +209,23 @@ void runIE(Target target, const std::string& xmlPath, const std::string& binPath try { IExtensionPtr extension = make_so_pointer(libName); +#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GT(2019010000) + ie.AddExtension(extension, device_name); +#else enginePtr->AddExtension(extension, 0); +#endif break; } catch(...) {} } // Some of networks can work without a library of extra layers. } +#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GT(2019010000) + netExec = ie.LoadNetwork(net, device_name); +#else plugin = InferencePlugin(enginePtr); - netExec = plugin.LoadNetwork(net, {}); +#endif infRequest = netExec.CreateInferRequest(); } catch (const std::exception& ex) @@ -224,7 +238,7 @@ void runIE(Target target, const std::string& xmlPath, const std::string& binPath BlobMap inputBlobs; for (auto& it : net.getInputsInfo()) { - genData(it.second->getDims(), inputsMap[it.first], inputBlobs[it.first]); + genData(it.second->getTensorDesc().getDims(), inputsMap[it.first], inputBlobs[it.first]); } infRequest.SetInput(inputBlobs); @@ -233,7 +247,7 @@ void runIE(Target target, const std::string& xmlPath, const std::string& binPath BlobMap outputBlobs; for (auto& it : net.getOutputsInfo()) { - genData(it.second->dims, outputsMap[it.first], outputBlobs[it.first]); + genData(it.second->getTensorDesc().getDims(), outputsMap[it.first], outputBlobs[it.first]); } infRequest.SetOutput(outputBlobs); diff --git a/modules/dnn/test/test_misc.cpp b/modules/dnn/test/test_misc.cpp index ccc14f0..6d2dab1 100644 --- a/modules/dnn/test/test_misc.cpp +++ b/modules/dnn/test/test_misc.cpp @@ -467,6 +467,42 @@ INSTANTIATE_TEST_CASE_P(/**/, Async, Combine( Values(CV_32F, CV_8U), testing::ValuesIn(getAvailableTargets(DNN_BACKEND_INFERENCE_ENGINE)) )); + +typedef testing::TestWithParam Test_Model_Optimizer; +TEST_P(Test_Model_Optimizer, forward_two_nets) +{ + const int target = GetParam(); + + const std::string suffix = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? "_fp16" : ""; + const std::string& model = findDataFile("dnn/layers/layer_convolution" + suffix + ".bin"); + const std::string& proto = findDataFile("dnn/layers/layer_convolution" + suffix + ".xml"); + + Net net0 = readNet(model, proto); + net0.setPreferableTarget(target); + + Net net1 = readNet(model, proto); + net1.setPreferableTarget(target); + + // Generate inputs. + int blobSize[] = {2, 6, 75, 113}; + Mat input(4, &blobSize[0], CV_32F); + randu(input, 0, 255); + + net0.setInput(input); + Mat ref0 = net0.forward().clone(); + + net1.setInput(input); + Mat ref1 = net1.forward(); + + net0.setInput(input); + Mat ref2 = net0.forward(); + + normAssert(ref0, ref2, 0, 0); +} +INSTANTIATE_TEST_CASE_P(/**/, Test_Model_Optimizer, + testing::ValuesIn(getAvailableTargets(DNN_BACKEND_INFERENCE_ENGINE)) +); + #endif // HAVE_INF_ENGINE }} // namespace -- 2.7.4