mirror of
https://github.com/opencv/opencv.git
synced 2025-06-08 01:53:19 +08:00
dnn: use inheritance for OpenVINO net impl
This commit is contained in:
parent
b26fc6f31b
commit
ca7f964104
@ -52,6 +52,11 @@
|
|||||||
|
|
||||||
namespace cv {
|
namespace cv {
|
||||||
namespace dnn {
|
namespace dnn {
|
||||||
|
|
||||||
|
namespace accessor {
|
||||||
|
class DnnNetAccessor; // forward declaration
|
||||||
|
}
|
||||||
|
|
||||||
CV__DNN_INLINE_NS_BEGIN
|
CV__DNN_INLINE_NS_BEGIN
|
||||||
//! @addtogroup dnn
|
//! @addtogroup dnn
|
||||||
//! @{
|
//! @{
|
||||||
@ -840,8 +845,12 @@ CV__DNN_INLINE_NS_BEGIN
|
|||||||
*/
|
*/
|
||||||
CV_WRAP int64 getPerfProfile(CV_OUT std::vector<double>& timings);
|
CV_WRAP int64 getPerfProfile(CV_OUT std::vector<double>& timings);
|
||||||
|
|
||||||
private:
|
|
||||||
struct Impl;
|
struct Impl;
|
||||||
|
inline Impl* getImpl() const { return impl.get(); }
|
||||||
|
inline Impl& getImplRef() const { CV_DbgAssert(impl); return *impl.get(); }
|
||||||
|
friend class accessor::DnnNetAccessor;
|
||||||
|
protected:
|
||||||
Ptr<Impl> impl;
|
Ptr<Impl> impl;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -156,6 +156,18 @@ static inline std::string toString(const Mat& blob, const std::string& name = st
|
|||||||
|
|
||||||
|
|
||||||
CV__DNN_INLINE_NS_END
|
CV__DNN_INLINE_NS_END
|
||||||
|
|
||||||
|
namespace accessor {
|
||||||
|
class DnnNetAccessor
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static inline Ptr<Net::Impl>& getImplPtrRef(Net& net)
|
||||||
|
{
|
||||||
|
return net.impl;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
}} // namespace
|
}} // namespace
|
||||||
|
|
||||||
#endif // __OPENCV_DNN_COMMON_HPP__
|
#endif // __OPENCV_DNN_COMMON_HPP__
|
||||||
|
@ -36,11 +36,7 @@ bool getParam_DNN_OPENCL_ALLOW_ALL_DEVICES()
|
|||||||
int getParam_DNN_BACKEND_DEFAULT()
|
int getParam_DNN_BACKEND_DEFAULT()
|
||||||
{
|
{
|
||||||
static int PARAM_DNN_BACKEND_DEFAULT = (int)utils::getConfigurationParameterSizeT("OPENCV_DNN_BACKEND_DEFAULT",
|
static int PARAM_DNN_BACKEND_DEFAULT = (int)utils::getConfigurationParameterSizeT("OPENCV_DNN_BACKEND_DEFAULT",
|
||||||
#ifdef HAVE_INF_ENGINE
|
|
||||||
(size_t)DNN_BACKEND_INFERENCE_ENGINE
|
|
||||||
#else
|
|
||||||
(size_t)DNN_BACKEND_OPENCV
|
(size_t)DNN_BACKEND_OPENCV
|
||||||
#endif
|
|
||||||
);
|
);
|
||||||
return PARAM_DNN_BACKEND_DEFAULT;
|
return PARAM_DNN_BACKEND_DEFAULT;
|
||||||
}
|
}
|
||||||
|
@ -988,14 +988,6 @@ InferenceEngine::DataPtr ngraphDataOutputNode(
|
|||||||
return w.dataPtr;
|
return w.dataPtr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void forwardNgraph(const std::vector<Ptr<BackendWrapper> >& outBlobsWrappers,
|
|
||||||
Ptr<BackendNode>& node, bool isAsync)
|
|
||||||
{
|
|
||||||
CV_Assert(!node.empty());
|
|
||||||
Ptr<InfEngineNgraphNode> ieNode = node.dynamicCast<InfEngineNgraphNode>();
|
|
||||||
CV_Assert(!ieNode.empty());
|
|
||||||
ieNode->net->forward(outBlobsWrappers, isAsync);
|
|
||||||
}
|
|
||||||
|
|
||||||
void InfEngineNgraphNet::reset()
|
void InfEngineNgraphNet::reset()
|
||||||
{
|
{
|
||||||
@ -1192,12 +1184,6 @@ void InfEngineNgraphNet::forward(const std::vector<Ptr<BackendWrapper> >& outBlo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
|
||||||
void forwardNgraph(const std::vector<Ptr<BackendWrapper> >& outBlobsWrappers,
|
|
||||||
Ptr<BackendNode>& node, bool isAsync)
|
|
||||||
{
|
|
||||||
CV_Assert(false && "nGraph is not enabled in this OpenCV build");
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}}
|
}}
|
||||||
|
@ -158,9 +158,6 @@ private:
|
|||||||
|
|
||||||
#endif // HAVE_DNN_NGRAPH
|
#endif // HAVE_DNN_NGRAPH
|
||||||
|
|
||||||
void forwardNgraph(const std::vector<Ptr<BackendWrapper> >& outBlobsWrappers,
|
|
||||||
Ptr<BackendNode>& node, bool isAsync);
|
|
||||||
|
|
||||||
}} // namespace cv::dnn
|
}} // namespace cv::dnn
|
||||||
|
|
||||||
|
|
||||||
|
@ -112,6 +112,30 @@ struct LayerData
|
|||||||
|
|
||||||
return layerInstance;
|
return layerInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void resetAllocation()
|
||||||
|
{
|
||||||
|
if (id == 0)
|
||||||
|
return; // skip "input" layer (assertion in Net::Impl::allocateLayers)
|
||||||
|
|
||||||
|
layerInstance.release();
|
||||||
|
outputBlobs.clear();
|
||||||
|
inputBlobs.clear();
|
||||||
|
internals.clear();
|
||||||
|
|
||||||
|
outputBlobsWrappers.clear();
|
||||||
|
inputBlobsWrappers.clear();
|
||||||
|
internalBlobsWrappers.clear();
|
||||||
|
|
||||||
|
backendNodes.clear();
|
||||||
|
|
||||||
|
skip = false;
|
||||||
|
flag = 0;
|
||||||
|
|
||||||
|
#ifdef HAVE_CUDA
|
||||||
|
cudaD2HBackgroundTransfers.clear();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -75,11 +75,7 @@ Ptr<BackendWrapper> wrapMat(int backendId, int targetId, cv::Mat& m)
|
|||||||
}
|
}
|
||||||
else if (backendId == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
|
else if (backendId == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_DNN_NGRAPH
|
CV_Assert(0 && "Internal error: DNN_BACKEND_INFERENCE_ENGINE_NGRAPH must be implemented through inheritance");
|
||||||
return Ptr<BackendWrapper>(new NgraphBackendWrapper(targetId, m));
|
|
||||||
#else
|
|
||||||
CV_Error(Error::StsNotImplemented, "This OpenCV version is built without support of OpenVINO / Inference Engine + nGraph");
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else if (backendId == DNN_BACKEND_WEBNN)
|
else if (backendId == DNN_BACKEND_WEBNN)
|
||||||
{
|
{
|
||||||
|
@ -120,7 +120,7 @@ Net Net::quantize(InputArrayOfArrays calibData, int inputsDtype, int outputsDtyp
|
|||||||
CV_TRACE_FUNCTION();
|
CV_TRACE_FUNCTION();
|
||||||
CV_Assert(impl);
|
CV_Assert(impl);
|
||||||
CV_Assert(!empty());
|
CV_Assert(!empty());
|
||||||
return impl->quantize(calibData, inputsDtype, outputsDtype, perChannel);
|
return impl->quantize(*this, calibData, inputsDtype, outputsDtype, perChannel);
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXIT drop from inference API
|
// FIXIT drop from inference API
|
||||||
@ -146,7 +146,7 @@ void Net::setPreferableBackend(int backendId)
|
|||||||
CV_TRACE_FUNCTION();
|
CV_TRACE_FUNCTION();
|
||||||
CV_TRACE_ARG(backendId);
|
CV_TRACE_ARG(backendId);
|
||||||
CV_Assert(impl);
|
CV_Assert(impl);
|
||||||
return impl->setPreferableBackend(backendId);
|
return impl->setPreferableBackend(*this, backendId);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Net::setPreferableTarget(int targetId)
|
void Net::setPreferableTarget(int targetId)
|
||||||
|
@ -30,6 +30,12 @@ std::string detail::NetImplBase::getDumpFileNameBase() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Net::Impl::~Impl()
|
||||||
|
{
|
||||||
|
// nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Net::Impl::Impl()
|
Net::Impl::Impl()
|
||||||
{
|
{
|
||||||
// allocate fake net input layer
|
// allocate fake net input layer
|
||||||
@ -46,9 +52,8 @@ Net::Impl::Impl()
|
|||||||
netWasQuantized = false;
|
netWasQuantized = false;
|
||||||
fusion = true;
|
fusion = true;
|
||||||
isAsync = false;
|
isAsync = false;
|
||||||
preferableBackend = DNN_BACKEND_DEFAULT;
|
preferableBackend = (Backend)getParam_DNN_BACKEND_DEFAULT();
|
||||||
preferableTarget = DNN_TARGET_CPU;
|
preferableTarget = DNN_TARGET_CPU;
|
||||||
skipInfEngineInit = false;
|
|
||||||
hasDynamicShapes = false;
|
hasDynamicShapes = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,22 +91,10 @@ void Net::Impl::clear()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Net::Impl::setUpNet(const std::vector<LayerPin>& blobsToKeep_)
|
void Net::Impl::validateBackendAndTarget()
|
||||||
{
|
{
|
||||||
CV_TRACE_FUNCTION();
|
CV_TRACE_FUNCTION();
|
||||||
|
|
||||||
if (dumpLevel && networkDumpCounter == 0)
|
|
||||||
{
|
|
||||||
dumpNetworkToFile();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (preferableBackend == DNN_BACKEND_DEFAULT)
|
|
||||||
preferableBackend = (Backend)getParam_DNN_BACKEND_DEFAULT();
|
|
||||||
#ifdef HAVE_INF_ENGINE
|
|
||||||
if (preferableBackend == DNN_BACKEND_INFERENCE_ENGINE)
|
|
||||||
preferableBackend = DNN_BACKEND_INFERENCE_ENGINE_NGRAPH; // = getInferenceEngineBackendTypeParam();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
CV_Assert(preferableBackend != DNN_BACKEND_OPENCV ||
|
CV_Assert(preferableBackend != DNN_BACKEND_OPENCV ||
|
||||||
preferableTarget == DNN_TARGET_CPU ||
|
preferableTarget == DNN_TARGET_CPU ||
|
||||||
preferableTarget == DNN_TARGET_OPENCL ||
|
preferableTarget == DNN_TARGET_OPENCL ||
|
||||||
@ -109,19 +102,6 @@ void Net::Impl::setUpNet(const std::vector<LayerPin>& blobsToKeep_)
|
|||||||
CV_Assert(preferableBackend != DNN_BACKEND_HALIDE ||
|
CV_Assert(preferableBackend != DNN_BACKEND_HALIDE ||
|
||||||
preferableTarget == DNN_TARGET_CPU ||
|
preferableTarget == DNN_TARGET_CPU ||
|
||||||
preferableTarget == DNN_TARGET_OPENCL);
|
preferableTarget == DNN_TARGET_OPENCL);
|
||||||
#ifdef HAVE_INF_ENGINE
|
|
||||||
if (preferableBackend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
|
|
||||||
{
|
|
||||||
CV_Assert(
|
|
||||||
(preferableTarget == DNN_TARGET_CPU && (!isArmComputePlugin() || preferableBackend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)) ||
|
|
||||||
preferableTarget == DNN_TARGET_OPENCL ||
|
|
||||||
preferableTarget == DNN_TARGET_OPENCL_FP16 ||
|
|
||||||
preferableTarget == DNN_TARGET_MYRIAD ||
|
|
||||||
preferableTarget == DNN_TARGET_HDDL ||
|
|
||||||
preferableTarget == DNN_TARGET_FPGA
|
|
||||||
);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_WEBNN
|
#ifdef HAVE_WEBNN
|
||||||
if (preferableBackend == DNN_BACKEND_WEBNN)
|
if (preferableBackend == DNN_BACKEND_WEBNN)
|
||||||
{
|
{
|
||||||
@ -136,6 +116,20 @@ void Net::Impl::setUpNet(const std::vector<LayerPin>& blobsToKeep_)
|
|||||||
CV_Assert(preferableBackend != DNN_BACKEND_TIMVX ||
|
CV_Assert(preferableBackend != DNN_BACKEND_TIMVX ||
|
||||||
preferableTarget == DNN_TARGET_NPU);
|
preferableTarget == DNN_TARGET_NPU);
|
||||||
|
|
||||||
|
CV_Assert(preferableBackend != DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && "Inheritance internal error");
|
||||||
|
}
|
||||||
|
|
||||||
|
void Net::Impl::setUpNet(const std::vector<LayerPin>& blobsToKeep_)
|
||||||
|
{
|
||||||
|
CV_TRACE_FUNCTION();
|
||||||
|
|
||||||
|
if (dumpLevel && networkDumpCounter == 0)
|
||||||
|
{
|
||||||
|
dumpNetworkToFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
validateBackendAndTarget();
|
||||||
|
|
||||||
if (!netWasAllocated || this->blobsToKeep != blobsToKeep_)
|
if (!netWasAllocated || this->blobsToKeep != blobsToKeep_)
|
||||||
{
|
{
|
||||||
if (preferableBackend == DNN_BACKEND_OPENCV && IS_DNN_OPENCL_TARGET(preferableTarget))
|
if (preferableBackend == DNN_BACKEND_OPENCV && IS_DNN_OPENCL_TARGET(preferableTarget))
|
||||||
@ -813,12 +807,10 @@ void Net::Impl::forwardLayer(LayerData& ld)
|
|||||||
{
|
{
|
||||||
forwardHalide(ld.outputBlobsWrappers, node);
|
forwardHalide(ld.outputBlobsWrappers, node);
|
||||||
}
|
}
|
||||||
#ifdef HAVE_INF_ENGINE
|
|
||||||
else if (preferableBackend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
|
else if (preferableBackend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
|
||||||
{
|
{
|
||||||
forwardNgraph(ld.outputBlobsWrappers, node, isAsync);
|
CV_Assert(preferableBackend != DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && "Inheritance internal error");
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
else if (preferableBackend == DNN_BACKEND_WEBNN)
|
else if (preferableBackend == DNN_BACKEND_WEBNN)
|
||||||
{
|
{
|
||||||
forwardWebnn(ld.outputBlobsWrappers, node, isAsync);
|
forwardWebnn(ld.outputBlobsWrappers, node, isAsync);
|
||||||
@ -844,7 +836,7 @@ void Net::Impl::forwardLayer(LayerData& ld)
|
|||||||
#endif
|
#endif
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CV_Error(Error::StsNotImplemented, "Unknown backend identifier");
|
CV_Error(Error::StsNotImplemented, cv::format("Unknown backend identifier: %d", preferableBackend));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1369,30 +1361,7 @@ Mat Net::Impl::getBlob(String outputName) const
|
|||||||
AsyncArray Net::Impl::getBlobAsync(const LayerPin& pin)
|
AsyncArray Net::Impl::getBlobAsync(const LayerPin& pin)
|
||||||
{
|
{
|
||||||
CV_TRACE_FUNCTION();
|
CV_TRACE_FUNCTION();
|
||||||
#ifdef HAVE_INF_ENGINE
|
|
||||||
if (!pin.valid())
|
|
||||||
CV_Error(Error::StsObjectNotFound, "Requested blob not found");
|
|
||||||
|
|
||||||
LayerData& ld = layers[pin.lid];
|
|
||||||
if ((size_t)pin.oid >= ld.outputBlobs.size())
|
|
||||||
{
|
|
||||||
CV_Error(Error::StsOutOfRange, format("Layer \"%s\" produce only %d outputs, "
|
|
||||||
"the #%d was requested",
|
|
||||||
ld.name.c_str(), (int)ld.outputBlobs.size(), (int)pin.oid));
|
|
||||||
}
|
|
||||||
if (preferableTarget != DNN_TARGET_CPU)
|
|
||||||
{
|
|
||||||
CV_Assert(!ld.outputBlobsWrappers.empty() && !ld.outputBlobsWrappers[pin.oid].empty());
|
|
||||||
// Transfer data to CPU if it's require.
|
|
||||||
ld.outputBlobsWrappers[pin.oid]->copyToHost();
|
|
||||||
}
|
|
||||||
CV_Assert(preferableBackend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH);
|
|
||||||
|
|
||||||
Ptr<NgraphBackendWrapper> wrapper = ld.outputBlobsWrappers[pin.oid].dynamicCast<NgraphBackendWrapper>();
|
|
||||||
return std::move(wrapper->futureMat);
|
|
||||||
#else
|
|
||||||
CV_Error(Error::StsNotImplemented, "DNN: OpenVINO/nGraph backend is required");
|
CV_Error(Error::StsNotImplemented, "DNN: OpenVINO/nGraph backend is required");
|
||||||
#endif // HAVE_INF_ENGINE
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -38,7 +38,12 @@ struct Net::Impl : public detail::NetImplBase
|
|||||||
typedef std::map<int, LayerShapes> LayersShapesMap;
|
typedef std::map<int, LayerShapes> LayersShapesMap;
|
||||||
typedef std::map<int, LayerData> MapIdToLayerData;
|
typedef std::map<int, LayerData> MapIdToLayerData;
|
||||||
|
|
||||||
|
virtual ~Impl();
|
||||||
Impl();
|
Impl();
|
||||||
|
Impl(const Impl&) = delete;
|
||||||
|
|
||||||
|
// Inheritance support
|
||||||
|
Ptr<Net::Impl> basePtr_;
|
||||||
|
|
||||||
Ptr<DataLayer> netInputLayer;
|
Ptr<DataLayer> netInputLayer;
|
||||||
std::vector<LayerPin> blobsToKeep;
|
std::vector<LayerPin> blobsToKeep;
|
||||||
@ -49,7 +54,7 @@ struct Net::Impl : public detail::NetImplBase
|
|||||||
int preferableBackend;
|
int preferableBackend;
|
||||||
int preferableTarget;
|
int preferableTarget;
|
||||||
String halideConfigFile;
|
String halideConfigFile;
|
||||||
bool skipInfEngineInit;
|
// bool skipInfEngineInit;
|
||||||
bool hasDynamicShapes;
|
bool hasDynamicShapes;
|
||||||
// Map host data to backend specific wrapper.
|
// Map host data to backend specific wrapper.
|
||||||
std::map<void*, Ptr<BackendWrapper>> backendWrappers;
|
std::map<void*, Ptr<BackendWrapper>> backendWrappers;
|
||||||
@ -59,19 +64,22 @@ struct Net::Impl : public detail::NetImplBase
|
|||||||
bool netWasAllocated;
|
bool netWasAllocated;
|
||||||
bool netWasQuantized;
|
bool netWasQuantized;
|
||||||
bool fusion;
|
bool fusion;
|
||||||
bool isAsync;
|
bool isAsync; // FIXIT: drop
|
||||||
std::vector<int64> layersTimings;
|
std::vector<int64> layersTimings;
|
||||||
|
|
||||||
|
|
||||||
bool empty() const;
|
virtual bool empty() const;
|
||||||
void setPreferableBackend(int backendId);
|
virtual void setPreferableBackend(Net& net, int backendId);
|
||||||
void setPreferableTarget(int targetId);
|
virtual void setPreferableTarget(int targetId);
|
||||||
|
|
||||||
// FIXIT use inheritance
|
// FIXIT use inheritance
|
||||||
Ptr<BackendWrapper> wrap(Mat& host);
|
virtual Ptr<BackendWrapper> wrap(Mat& host);
|
||||||
|
|
||||||
|
|
||||||
void clear();
|
virtual void clear();
|
||||||
|
|
||||||
|
|
||||||
|
virtual void validateBackendAndTarget();
|
||||||
|
|
||||||
void setUpNet(const std::vector<LayerPin>& blobsToKeep_ = std::vector<LayerPin>());
|
void setUpNet(const std::vector<LayerPin>& blobsToKeep_ = std::vector<LayerPin>());
|
||||||
|
|
||||||
@ -118,7 +126,7 @@ struct Net::Impl : public detail::NetImplBase
|
|||||||
|
|
||||||
void setInputsNames(const std::vector<String>& inputBlobNames);
|
void setInputsNames(const std::vector<String>& inputBlobNames);
|
||||||
void setInputShape(const String& inputName, const MatShape& shape);
|
void setInputShape(const String& inputName, const MatShape& shape);
|
||||||
void setInput(InputArray blob, const String& name, double scalefactor, const Scalar& mean);
|
virtual void setInput(InputArray blob, const String& name, double scalefactor, const Scalar& mean);
|
||||||
Mat getParam(int layer, int numParam) const;
|
Mat getParam(int layer, int numParam) const;
|
||||||
void setParam(int layer, int numParam, const Mat& blob);
|
void setParam(int layer, int numParam, const Mat& blob);
|
||||||
std::vector<Ptr<Layer>> getLayerInputs(int layerId) const;
|
std::vector<Ptr<Layer>> getLayerInputs(int layerId) const;
|
||||||
@ -130,8 +138,7 @@ struct Net::Impl : public detail::NetImplBase
|
|||||||
int getLayersCount(const String& layerType) const;
|
int getLayersCount(const String& layerType) const;
|
||||||
|
|
||||||
|
|
||||||
// FIXIT use inheritance
|
virtual void initBackend(const std::vector<LayerPin>& blobsToKeep_);
|
||||||
void initBackend(const std::vector<LayerPin>& blobsToKeep_);
|
|
||||||
|
|
||||||
void setHalideScheduler(const String& scheduler);
|
void setHalideScheduler(const String& scheduler);
|
||||||
#ifdef HAVE_HALIDE
|
#ifdef HAVE_HALIDE
|
||||||
@ -139,11 +146,6 @@ struct Net::Impl : public detail::NetImplBase
|
|||||||
void initHalideBackend();
|
void initHalideBackend();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_DNN_NGRAPH
|
|
||||||
void addNgraphOutputs(LayerData& ld);
|
|
||||||
void initNgraphBackend(const std::vector<LayerPin>& blobsToKeep_);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_WEBNN
|
#ifdef HAVE_WEBNN
|
||||||
void addWebnnOutputs(LayerData& ld);
|
void addWebnnOutputs(LayerData& ld);
|
||||||
void initWebnnBackend(const std::vector<LayerPin>& blobsToKeep_);
|
void initWebnnBackend(const std::vector<LayerPin>& blobsToKeep_);
|
||||||
@ -183,11 +185,11 @@ struct Net::Impl : public detail::NetImplBase
|
|||||||
// TODO add getter
|
// TODO add getter
|
||||||
void enableFusion(bool fusion_);
|
void enableFusion(bool fusion_);
|
||||||
|
|
||||||
void fuseLayers(const std::vector<LayerPin>& blobsToKeep_);
|
virtual void fuseLayers(const std::vector<LayerPin>& blobsToKeep_);
|
||||||
|
|
||||||
void allocateLayers(const std::vector<LayerPin>& blobsToKeep_);
|
void allocateLayers(const std::vector<LayerPin>& blobsToKeep_);
|
||||||
|
|
||||||
void forwardLayer(LayerData& ld);
|
virtual void forwardLayer(LayerData& ld);
|
||||||
|
|
||||||
void forwardToLayer(LayerData& ld, bool clearFlags = true);
|
void forwardToLayer(LayerData& ld, bool clearFlags = true);
|
||||||
|
|
||||||
@ -243,22 +245,17 @@ struct Net::Impl : public detail::NetImplBase
|
|||||||
Mat getBlob(String outputName) const;
|
Mat getBlob(String outputName) const;
|
||||||
|
|
||||||
#ifdef CV_CXX11
|
#ifdef CV_CXX11
|
||||||
AsyncArray getBlobAsync(const LayerPin& pin);
|
virtual AsyncArray getBlobAsync(const LayerPin& pin);
|
||||||
|
|
||||||
AsyncArray getBlobAsync(String outputName);
|
AsyncArray getBlobAsync(String outputName);
|
||||||
#endif // CV_CXX11
|
#endif // CV_CXX11
|
||||||
|
|
||||||
#ifdef HAVE_INF_ENGINE
|
|
||||||
static
|
|
||||||
Net createNetworkFromModelOptimizer(InferenceEngine::CNNNetwork& ieNet);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
string dump(bool forceAllocation = false) const;
|
string dump(bool forceAllocation = false) const;
|
||||||
|
|
||||||
void dumpNetworkToFile() const;
|
void dumpNetworkToFile() const;
|
||||||
|
|
||||||
// FIXIT drop from inference API
|
// FIXIT drop from inference API
|
||||||
Net quantize(InputArrayOfArrays calibData, int inputsDtype, int outputsDtype, bool perChannel) /*const*/;
|
Net quantize(Net& net, InputArrayOfArrays calibData, int inputsDtype, int outputsDtype, bool perChannel) /*const*/;
|
||||||
void getInputDetails(std::vector<float>& scales, std::vector<int>& zeropoints) /*const*/;
|
void getInputDetails(std::vector<float>& scales, std::vector<int>& zeropoints) /*const*/;
|
||||||
void getOutputDetails(std::vector<float>& scales, std::vector<int>& zeropoints) /*const*/;
|
void getOutputDetails(std::vector<float>& scales, std::vector<int>& zeropoints) /*const*/;
|
||||||
|
|
||||||
|
@ -109,11 +109,7 @@ void Net::Impl::initBackend(const std::vector<LayerPin>& blobsToKeep_)
|
|||||||
}
|
}
|
||||||
else if (preferableBackend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
|
else if (preferableBackend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_DNN_NGRAPH
|
CV_Assert(0 && "Inheritance must be used with OpenVINO backend");
|
||||||
initNgraphBackend(blobsToKeep_);
|
|
||||||
#else
|
|
||||||
CV_Error(Error::StsNotImplemented, "This OpenCV version is built without support of OpenVINO");
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else if (preferableBackend == DNN_BACKEND_WEBNN)
|
else if (preferableBackend == DNN_BACKEND_WEBNN)
|
||||||
{
|
{
|
||||||
@ -154,26 +150,30 @@ void Net::Impl::initBackend(const std::vector<LayerPin>& blobsToKeep_)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Net::Impl::setPreferableBackend(int backendId)
|
void Net::Impl::setPreferableBackend(Net& net, int backendId)
|
||||||
{
|
{
|
||||||
if (backendId == DNN_BACKEND_DEFAULT)
|
if (backendId == DNN_BACKEND_DEFAULT)
|
||||||
backendId = (Backend)getParam_DNN_BACKEND_DEFAULT();
|
backendId = (Backend)getParam_DNN_BACKEND_DEFAULT();
|
||||||
|
|
||||||
|
if (backendId == DNN_BACKEND_INFERENCE_ENGINE)
|
||||||
|
backendId = DNN_BACKEND_INFERENCE_ENGINE_NGRAPH; // = getInferenceEngineBackendTypeParam();
|
||||||
|
|
||||||
if (netWasQuantized && backendId != DNN_BACKEND_OPENCV && backendId != DNN_BACKEND_TIMVX)
|
if (netWasQuantized && backendId != DNN_BACKEND_OPENCV && backendId != DNN_BACKEND_TIMVX)
|
||||||
{
|
{
|
||||||
CV_LOG_WARNING(NULL, "DNN: Only default and TIMVX backends support quantized networks");
|
CV_LOG_WARNING(NULL, "DNN: Only default and TIMVX backends support quantized networks");
|
||||||
backendId = DNN_BACKEND_OPENCV;
|
backendId = DNN_BACKEND_OPENCV;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_INF_ENGINE
|
|
||||||
if (backendId == DNN_BACKEND_INFERENCE_ENGINE)
|
|
||||||
backendId = DNN_BACKEND_INFERENCE_ENGINE_NGRAPH;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (preferableBackend != backendId)
|
if (preferableBackend != backendId)
|
||||||
{
|
{
|
||||||
preferableBackend = backendId;
|
preferableBackend = backendId;
|
||||||
clear();
|
clear();
|
||||||
|
#ifdef HAVE_INF_ENGINE
|
||||||
|
if (backendId == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
|
||||||
|
{
|
||||||
|
switchToOpenVINOBackend(net);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,11 +17,205 @@ CV__DNN_INLINE_NS_BEGIN
|
|||||||
|
|
||||||
#ifdef HAVE_INF_ENGINE
|
#ifdef HAVE_INF_ENGINE
|
||||||
|
|
||||||
|
// TODO: use "string" target specifier
|
||||||
|
class NetImplOpenVINO CV_FINAL : public Net::Impl
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef Net::Impl Base;
|
||||||
|
|
||||||
|
// this default constructor is used with OpenVINO native loader
|
||||||
|
// TODO: dedicated Impl?
|
||||||
|
NetImplOpenVINO()
|
||||||
|
: Net::Impl()
|
||||||
|
{
|
||||||
|
preferableBackend = DNN_BACKEND_INFERENCE_ENGINE_NGRAPH;
|
||||||
|
}
|
||||||
|
|
||||||
|
// constructor to derive execution implementation from the loaded network
|
||||||
|
explicit NetImplOpenVINO(const Ptr<Net::Impl>& basePtr)
|
||||||
|
: Net::Impl()
|
||||||
|
{
|
||||||
|
basePtr_ = basePtr;
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
void init()
|
||||||
|
{
|
||||||
|
CV_TRACE_FUNCTION();
|
||||||
|
CV_Assert(basePtr_);
|
||||||
|
Net::Impl& base = *basePtr_;
|
||||||
|
CV_Assert(!base.netWasAllocated);
|
||||||
|
CV_Assert(!base.netWasQuantized);
|
||||||
|
netInputLayer = base.netInputLayer;
|
||||||
|
blobsToKeep = base.blobsToKeep;
|
||||||
|
layers = base.layers;
|
||||||
|
for (MapIdToLayerData::iterator it = layers.begin(); it != layers.end(); it++)
|
||||||
|
{
|
||||||
|
LayerData& ld = it->second;
|
||||||
|
ld.resetAllocation();
|
||||||
|
}
|
||||||
|
layerNameToId = base.layerNameToId;
|
||||||
|
outputNameToId = base.outputNameToId;
|
||||||
|
//blobManager = base.blobManager;
|
||||||
|
preferableBackend = DNN_BACKEND_INFERENCE_ENGINE_NGRAPH; //base.preferableBackend;
|
||||||
|
preferableTarget = base.preferableTarget;
|
||||||
|
hasDynamicShapes = base.hasDynamicShapes;
|
||||||
|
CV_Assert(base.backendWrappers.empty()); //backendWrappers = base.backendWrappers;
|
||||||
|
lastLayerId = base.lastLayerId;
|
||||||
|
netWasAllocated = base.netWasAllocated;
|
||||||
|
netWasQuantized = base.netWasQuantized;
|
||||||
|
fusion = base.fusion;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//bool isAsync; // FIXIT: drop
|
||||||
|
|
||||||
|
|
||||||
|
bool empty() const override
|
||||||
|
{
|
||||||
|
return Base::empty();
|
||||||
|
}
|
||||||
|
void setPreferableBackend(Net& net, int backendId) override
|
||||||
|
{
|
||||||
|
if (backendId == DNN_BACKEND_INFERENCE_ENGINE || backendId == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
|
||||||
|
return; // no-op
|
||||||
|
if (!basePtr_)
|
||||||
|
CV_Error(Error::StsError, "DNN: Can't switch backend of network created by OpenVINO");
|
||||||
|
Ptr<Net::Impl>& impl_ptr_ref = accessor::DnnNetAccessor::getImplPtrRef(net);
|
||||||
|
impl_ptr_ref = basePtr_;
|
||||||
|
return basePtr_->setPreferableBackend(net, backendId);
|
||||||
|
}
|
||||||
|
void setPreferableTarget(int targetId) override
|
||||||
|
{
|
||||||
|
if (preferableTarget != targetId)
|
||||||
|
{
|
||||||
|
preferableTarget = targetId;
|
||||||
|
clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ptr<BackendWrapper> wrap(Mat& host) override
|
||||||
|
{
|
||||||
|
return Ptr<BackendWrapper>(new NgraphBackendWrapper(preferableTarget, host));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void clear() override
|
||||||
|
{
|
||||||
|
Base::clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void validateBackendAndTarget() override
|
||||||
|
{
|
||||||
|
CV_TRACE_FUNCTION();
|
||||||
|
|
||||||
|
CV_Assert(preferableBackend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH);
|
||||||
|
CV_Check((int)preferableTarget,
|
||||||
|
preferableTarget == DNN_TARGET_CPU ||
|
||||||
|
preferableTarget == DNN_TARGET_OPENCL ||
|
||||||
|
preferableTarget == DNN_TARGET_OPENCL_FP16 ||
|
||||||
|
preferableTarget == DNN_TARGET_MYRIAD ||
|
||||||
|
preferableTarget == DNN_TARGET_HDDL ||
|
||||||
|
preferableTarget == DNN_TARGET_FPGA,
|
||||||
|
"Unknown OpenVINO target"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//void setUpNet(const std::vector<LayerPin>& blobsToKeep_ = std::vector<LayerPin>()) override;
|
||||||
|
|
||||||
|
|
||||||
|
//void setInput(InputArray blob, const String& name, double scalefactor, const Scalar& mean) override;
|
||||||
|
|
||||||
|
void addNgraphOutputs(LayerData& ld);
|
||||||
|
|
||||||
|
void initBackend(const std::vector<LayerPin>& blobsToKeep_) override;
|
||||||
|
|
||||||
|
void fuseLayers(const std::vector<LayerPin>& blobsToKeep_) override;
|
||||||
|
|
||||||
|
//void allocateLayers(const std::vector<LayerPin>& blobsToKeep_) override;
|
||||||
|
|
||||||
|
void forwardLayer(LayerData& ld) override;
|
||||||
|
|
||||||
|
AsyncArray getBlobAsync(const LayerPin& pin) override;
|
||||||
|
|
||||||
|
//string dump(bool forceAllocation = false) const override;
|
||||||
|
|
||||||
|
static
|
||||||
|
Net createNetworkFromModelOptimizer(InferenceEngine::CNNNetwork& ieNet);
|
||||||
|
|
||||||
|
}; // NetImplOpenVINO
|
||||||
|
|
||||||
|
|
||||||
|
void NetImplOpenVINO::forwardLayer(LayerData& ld)
|
||||||
|
{
|
||||||
|
CV_TRACE_FUNCTION();
|
||||||
|
|
||||||
|
Ptr<Layer> layer = ld.layerInstance;
|
||||||
|
|
||||||
|
if (!ld.skip)
|
||||||
|
{
|
||||||
|
auto it = ld.backendNodes.find(preferableBackend);
|
||||||
|
if (ld.id == 0 || // input layer
|
||||||
|
it == ld.backendNodes.end() // non-supported layer or its mode
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return Base::forwardLayer(ld);
|
||||||
|
}
|
||||||
|
|
||||||
|
CV_Assert(it != ld.backendNodes.end());
|
||||||
|
const Ptr<BackendNode>& node = it->second;
|
||||||
|
CV_Assert(!node.empty());
|
||||||
|
Ptr<InfEngineNgraphNode> ieNode = node.dynamicCast<InfEngineNgraphNode>();
|
||||||
|
CV_Assert(!ieNode.empty());
|
||||||
|
CV_Assert(ieNode->net);
|
||||||
|
|
||||||
|
TickMeter tm;
|
||||||
|
tm.start();
|
||||||
|
|
||||||
|
ieNode->net->forward(ld.outputBlobsWrappers, isAsync);
|
||||||
|
|
||||||
|
tm.stop();
|
||||||
|
int64 t = tm.getTimeTicks();
|
||||||
|
layersTimings[ld.id] = (t > 0) ? t : t + 1; // zero for skipped layers only
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
layersTimings[ld.id] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ld.flag = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
AsyncArray NetImplOpenVINO::getBlobAsync(const LayerPin& pin)
|
||||||
|
{
|
||||||
|
CV_TRACE_FUNCTION();
|
||||||
|
if (!pin.valid())
|
||||||
|
CV_Error(Error::StsObjectNotFound, "Requested blob not found");
|
||||||
|
|
||||||
|
LayerData& ld = layers[pin.lid];
|
||||||
|
if ((size_t)pin.oid >= ld.outputBlobs.size())
|
||||||
|
{
|
||||||
|
CV_Error(Error::StsOutOfRange, format("Layer \"%s\" produce only %d outputs, "
|
||||||
|
"the #%d was requested",
|
||||||
|
ld.name.c_str(), (int)ld.outputBlobs.size(), (int)pin.oid));
|
||||||
|
}
|
||||||
|
if (preferableTarget != DNN_TARGET_CPU)
|
||||||
|
{
|
||||||
|
CV_Assert(!ld.outputBlobsWrappers.empty() && !ld.outputBlobsWrappers[pin.oid].empty());
|
||||||
|
// Transfer data to CPU if it's require.
|
||||||
|
ld.outputBlobsWrappers[pin.oid]->copyToHost();
|
||||||
|
}
|
||||||
|
CV_Assert(preferableBackend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH);
|
||||||
|
|
||||||
|
Ptr<NgraphBackendWrapper> wrapper = ld.outputBlobsWrappers[pin.oid].dynamicCast<NgraphBackendWrapper>();
|
||||||
|
return std::move(wrapper->futureMat);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/** mark input pins as outputs from other subnetworks
|
/** mark input pins as outputs from other subnetworks
|
||||||
* FIXIT must be done by DNN engine not ngraph.
|
* FIXIT must be done by DNN engine not ngraph.
|
||||||
*/
|
*/
|
||||||
void Net::Impl::addNgraphOutputs(LayerData& ld)
|
void NetImplOpenVINO::addNgraphOutputs(LayerData& ld)
|
||||||
{
|
{
|
||||||
CV_TRACE_FUNCTION();
|
CV_TRACE_FUNCTION();
|
||||||
|
|
||||||
@ -59,7 +253,7 @@ void Net::Impl::addNgraphOutputs(LayerData& ld)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Net::Impl::initNgraphBackend(const std::vector<LayerPin>& blobsToKeep_)
|
void NetImplOpenVINO::initBackend(const std::vector<LayerPin>& blobsToKeep_)
|
||||||
{
|
{
|
||||||
CV_TRACE_FUNCTION();
|
CV_TRACE_FUNCTION();
|
||||||
CV_CheckEQ(preferableBackend, DNN_BACKEND_INFERENCE_ENGINE_NGRAPH, "");
|
CV_CheckEQ(preferableBackend, DNN_BACKEND_INFERENCE_ENGINE_NGRAPH, "");
|
||||||
@ -92,7 +286,7 @@ void Net::Impl::initNgraphBackend(const std::vector<LayerPin>& blobsToKeep_)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (skipInfEngineInit)
|
if (!basePtr_) // model is loaded by OpenVINO
|
||||||
{
|
{
|
||||||
Ptr<BackendNode> node = layers[lastLayerId].backendNodes[preferableBackend];
|
Ptr<BackendNode> node = layers[lastLayerId].backendNodes[preferableBackend];
|
||||||
CV_Assert(!node.empty());
|
CV_Assert(!node.empty());
|
||||||
@ -399,10 +593,104 @@ void Net::Impl::initNgraphBackend(const std::vector<LayerPin>& blobsToKeep_)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//} // Net::Impl
|
|
||||||
|
#if 0
|
||||||
|
#define printf_(args) printf args
|
||||||
|
#else
|
||||||
|
#define printf_(args)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void NetImplOpenVINO::fuseLayers(const std::vector<LayerPin>& blobsToKeep_)
|
||||||
|
{
|
||||||
|
CV_TRACE_FUNCTION();
|
||||||
|
|
||||||
|
if(!fusion)
|
||||||
|
return;
|
||||||
|
|
||||||
|
CV_Check((int)preferableBackend, preferableBackend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH, "");
|
||||||
|
|
||||||
|
#if 0 // FIXIT mode without fusion is broken due to unsupported layers and handling of "custom" nodes
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// scan through all the layers. If there is convolution layer followed by the activation layer,
|
||||||
|
// we try to embed this activation into the convolution and disable separate execution of the activation
|
||||||
|
|
||||||
|
// FIXIT replace by layersToKeep to avoid hacks like "LayerPin(lid, 0)"
|
||||||
|
std::set<LayerPin> pinsToKeep(blobsToKeep_.begin(),
|
||||||
|
blobsToKeep_.end());
|
||||||
|
for (MapIdToLayerData::const_iterator it = layers.begin(); it != layers.end(); it++)
|
||||||
|
{
|
||||||
|
int lid = it->first;
|
||||||
|
LayerData& ld = layers[lid];
|
||||||
|
if (ld.skip)
|
||||||
|
{
|
||||||
|
printf_(("skipped %s: %s\n", ld.layerInstance->name.c_str(), ld.layerInstance->type.c_str()));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
printf_(("analyzing %s: %s\n", ld.layerInstance->name.c_str(), ld.layerInstance->type.c_str()));
|
||||||
|
|
||||||
|
// the optimization #1. try to fuse batch norm, scaling and/or activation layers
|
||||||
|
// with the current layer if they follow it. Normally, the are fused with the convolution layer,
|
||||||
|
// but some of them (like activation) may be fused with fully-connected, elemwise (+) and
|
||||||
|
// some other layers.
|
||||||
|
Ptr<Layer>& currLayer = ld.layerInstance;
|
||||||
|
if (ld.consumers.size() == 1 && pinsToKeep.count(LayerPin(lid, 0)) == 0)
|
||||||
|
{
|
||||||
|
LayerData* nextData = &layers[ld.consumers[0].lid];
|
||||||
|
LayerPin lpNext(ld.consumers[0].lid, 0);
|
||||||
|
while (nextData)
|
||||||
|
{
|
||||||
|
if (preferableBackend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && pinsToKeep.count(lpNext) != 0)
|
||||||
|
{
|
||||||
|
CV_LOG_DEBUG(NULL, "DNN/IE: skip fusing with 'output' node: " << nextData->name << "@" << nextData->type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* we use `tryFuse` member of convolution layer to fuse eltwise later
|
||||||
|
* it's not intended to be fused here; hence, we stop when we encounter eltwise
|
||||||
|
*/
|
||||||
|
Ptr<Layer> nextLayer = nextData->layerInstance;
|
||||||
|
if (currLayer->tryFuse(nextLayer))
|
||||||
|
{
|
||||||
|
printf_(("\tfused with %s\n", nextLayer->name.c_str()));
|
||||||
|
nextData->skip = true;
|
||||||
|
ld.outputBlobs = layers[lpNext.lid].outputBlobs;
|
||||||
|
ld.outputBlobsWrappers = layers[lpNext.lid].outputBlobsWrappers;
|
||||||
|
if (nextData->consumers.size() == 1)
|
||||||
|
{
|
||||||
|
int nextLayerId = nextData->consumers[0].lid;
|
||||||
|
nextData = &layers[nextLayerId];
|
||||||
|
lpNext = LayerPin(nextLayerId, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nextData = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void switchToOpenVINOBackend(Net& net)
|
||||||
|
{
|
||||||
|
CV_TRACE_FUNCTION();
|
||||||
|
CV_LOG_INFO(NULL, "DNN: switching to OpenVINO backend...");
|
||||||
|
Ptr<Net::Impl>& impl_ptr_ref = accessor::DnnNetAccessor::getImplPtrRef(net);
|
||||||
|
Ptr<NetImplOpenVINO> openvino_impl_ptr = makePtr<NetImplOpenVINO>(impl_ptr_ref);
|
||||||
|
impl_ptr_ref = openvino_impl_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*static*/
|
/*static*/
|
||||||
Net Net::Impl::createNetworkFromModelOptimizer(InferenceEngine::CNNNetwork& ieNet)
|
Net NetImplOpenVINO::createNetworkFromModelOptimizer(InferenceEngine::CNNNetwork& ieNet)
|
||||||
{
|
{
|
||||||
CV_TRACE_FUNCTION();
|
CV_TRACE_FUNCTION();
|
||||||
|
|
||||||
@ -418,6 +706,10 @@ Net Net::Impl::createNetworkFromModelOptimizer(InferenceEngine::CNNNetwork& ieNe
|
|||||||
}
|
}
|
||||||
|
|
||||||
Net cvNet;
|
Net cvNet;
|
||||||
|
Ptr<NetImplOpenVINO> openvino_impl_ptr = makePtr<NetImplOpenVINO>();
|
||||||
|
NetImplOpenVINO& openvino_impl = *openvino_impl_ptr;
|
||||||
|
accessor::DnnNetAccessor::getImplPtrRef(cvNet) = openvino_impl_ptr;
|
||||||
|
|
||||||
cvNet.setInputsNames(inputsNames);
|
cvNet.setInputsNames(inputsNames);
|
||||||
|
|
||||||
// set empty input to determine input shapes
|
// set empty input to determine input shapes
|
||||||
@ -432,7 +724,7 @@ Net Net::Impl::createNetworkFromModelOptimizer(InferenceEngine::CNNNetwork& ieNe
|
|||||||
{
|
{
|
||||||
auto fake_node = std::make_shared<ngraph::op::Parameter>(ngraph::element::f32, ngraph::Shape {});
|
auto fake_node = std::make_shared<ngraph::op::Parameter>(ngraph::element::f32, ngraph::Shape {});
|
||||||
Ptr<InfEngineNgraphNode> backendNodeNGraph(new InfEngineNgraphNode(fake_node));
|
Ptr<InfEngineNgraphNode> backendNodeNGraph(new InfEngineNgraphNode(fake_node));
|
||||||
backendNodeNGraph->net = Ptr<InfEngineNgraphNet>(new InfEngineNgraphNet(*(cvNet.impl), ieNet));
|
backendNodeNGraph->net = Ptr<InfEngineNgraphNet>(new InfEngineNgraphNet(openvino_impl, ieNet));
|
||||||
backendNode = backendNodeNGraph;
|
backendNode = backendNodeNGraph;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -450,7 +742,7 @@ Net Net::Impl::createNetworkFromModelOptimizer(InferenceEngine::CNNNetwork& ieNe
|
|||||||
LayerParams lp;
|
LayerParams lp;
|
||||||
int lid = cvNet.addLayer(it.first, "", lp);
|
int lid = cvNet.addLayer(it.first, "", lp);
|
||||||
|
|
||||||
LayerData& ld = cvNet.impl->layers[lid];
|
LayerData& ld = openvino_impl.layers[lid];
|
||||||
|
|
||||||
{
|
{
|
||||||
Ptr<Layer> cvLayer(new NgraphBackendLayer(ieNet));
|
Ptr<Layer> cvLayer(new NgraphBackendLayer(ieNet));
|
||||||
@ -498,7 +790,6 @@ Net Net::Impl::createNetworkFromModelOptimizer(InferenceEngine::CNNNetwork& ieNe
|
|||||||
|
|
||||||
cvNet.setPreferableBackend(DNN_BACKEND_INFERENCE_ENGINE_NGRAPH);
|
cvNet.setPreferableBackend(DNN_BACKEND_INFERENCE_ENGINE_NGRAPH);
|
||||||
|
|
||||||
cvNet.impl->skipInfEngineInit = true;
|
|
||||||
return cvNet;
|
return cvNet;
|
||||||
}
|
}
|
||||||
#endif // HAVE_INF_ENGINE
|
#endif // HAVE_INF_ENGINE
|
||||||
@ -516,7 +807,7 @@ Net Net::readFromModelOptimizer(const String& xml, const String& bin)
|
|||||||
InferenceEngine::Core& ie = getCore("");
|
InferenceEngine::Core& ie = getCore("");
|
||||||
InferenceEngine::CNNNetwork ieNet = ie.ReadNetwork(xml, bin);
|
InferenceEngine::CNNNetwork ieNet = ie.ReadNetwork(xml, bin);
|
||||||
|
|
||||||
return Impl::createNetworkFromModelOptimizer(ieNet);
|
return NetImplOpenVINO::createNetworkFromModelOptimizer(ieNet);
|
||||||
#endif // HAVE_INF_ENGINE
|
#endif // HAVE_INF_ENGINE
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -560,7 +851,7 @@ Net Net::readFromModelOptimizer(
|
|||||||
CV_Error(Error::StsError, std::string("DNN: IE failed to load model: ") + e.what());
|
CV_Error(Error::StsError, std::string("DNN: IE failed to load model: ") + e.what());
|
||||||
}
|
}
|
||||||
|
|
||||||
return Impl::createNetworkFromModelOptimizer(ieNet);
|
return NetImplOpenVINO::createNetworkFromModelOptimizer(ieNet);
|
||||||
#endif // HAVE_INF_ENGINE
|
#endif // HAVE_INF_ENGINE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ void getQuantizationParams(const Mat& src, std::vector<float>& scales, std::vect
|
|||||||
}
|
}
|
||||||
|
|
||||||
// FIXIT drop from inference API
|
// FIXIT drop from inference API
|
||||||
Net Net::Impl::quantize(InputArrayOfArrays calibData, int inputsDtype, int outputsDtype, bool perChannel)
|
Net Net::Impl::quantize(Net& net, InputArrayOfArrays calibData, int inputsDtype, int outputsDtype, bool perChannel)
|
||||||
{
|
{
|
||||||
// Net can be quantized only once.
|
// Net can be quantized only once.
|
||||||
if (netWasQuantized)
|
if (netWasQuantized)
|
||||||
@ -47,7 +47,8 @@ Net Net::Impl::quantize(InputArrayOfArrays calibData, int inputsDtype, int outpu
|
|||||||
int prefTarget = preferableTarget;
|
int prefTarget = preferableTarget;
|
||||||
|
|
||||||
// Disable fusions and use CPU backend to quantize net
|
// Disable fusions and use CPU backend to quantize net
|
||||||
setPreferableBackend(DNN_BACKEND_OPENCV);
|
// FIXIT: we should not modify original network!
|
||||||
|
setPreferableBackend(net, DNN_BACKEND_OPENCV);
|
||||||
setPreferableTarget(DNN_TARGET_CPU);
|
setPreferableTarget(DNN_TARGET_CPU);
|
||||||
enableFusion(false);
|
enableFusion(false);
|
||||||
|
|
||||||
@ -163,7 +164,7 @@ Net Net::Impl::quantize(InputArrayOfArrays calibData, int inputsDtype, int outpu
|
|||||||
Net::Impl& dstNet = *(dstNet_.impl);
|
Net::Impl& dstNet = *(dstNet_.impl);
|
||||||
dstNet.netWasQuantized = true;
|
dstNet.netWasQuantized = true;
|
||||||
dstNet.setInputsNames(netInputLayer->outNames);
|
dstNet.setInputsNames(netInputLayer->outNames);
|
||||||
dstNet.setPreferableBackend(prefBackend);
|
dstNet.setPreferableBackend(dstNet_, prefBackend);
|
||||||
dstNet.setPreferableTarget(prefTarget);
|
dstNet.setPreferableTarget(prefTarget);
|
||||||
dstNet.enableFusion(originalFusion);
|
dstNet.enableFusion(originalFusion);
|
||||||
|
|
||||||
@ -253,7 +254,7 @@ Net Net::Impl::quantize(InputArrayOfArrays calibData, int inputsDtype, int outpu
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Restore FP32 Net's backend, target and fusion
|
// Restore FP32 Net's backend, target and fusion
|
||||||
setPreferableBackend(prefBackend);
|
setPreferableBackend(net, prefBackend);
|
||||||
setPreferableTarget(prefTarget);
|
setPreferableTarget(prefTarget);
|
||||||
enableFusion(originalFusion);
|
enableFusion(originalFusion);
|
||||||
return dstNet_;
|
return dstNet_;
|
||||||
|
@ -73,6 +73,8 @@ void infEngineBlobsToMats(const std::vector<InferenceEngine::Blob::Ptr>& blobs,
|
|||||||
|
|
||||||
CV__DNN_INLINE_NS_BEGIN
|
CV__DNN_INLINE_NS_BEGIN
|
||||||
|
|
||||||
|
void switchToOpenVINOBackend(Net& net);
|
||||||
|
|
||||||
namespace openvino {
|
namespace openvino {
|
||||||
|
|
||||||
// TODO: use std::string as parameter
|
// TODO: use std::string as parameter
|
||||||
|
Loading…
Reference in New Issue
Block a user