mirror of
https://github.com/opencv/opencv.git
synced 2025-06-11 11:45:30 +08:00
dnn(ie): fix handling of 1D and non-32F outputs of InferenceEngine
This commit is contained in:
parent
602e7c83e2
commit
fbde0c6c96
@ -1944,7 +1944,10 @@ struct Net::Impl : public detail::NetImplBase
|
||||
|
||||
Ptr<InfEngineNgraphNode> ieNode = node.dynamicCast<InfEngineNgraphNode>();
|
||||
CV_Assert(!ieNode.empty());
|
||||
ieNode->net->reset();
|
||||
|
||||
CV_Assert(ieNode->net);
|
||||
InfEngineNgraphNet& ienet = *ieNode->net;
|
||||
ienet.reset();
|
||||
|
||||
for (it = layers.begin(); it != layers.end(); ++it)
|
||||
{
|
||||
@ -1961,16 +1964,26 @@ struct Net::Impl : public detail::NetImplBase
|
||||
{
|
||||
for (int i = 0; i < ld.outputBlobsWrappers.size(); ++i)
|
||||
{
|
||||
InferenceEngine::DataPtr dataPtr = ngraphDataNode(ld.outputBlobsWrappers[i]);
|
||||
dataPtr->setName(ld.name);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
ieNode->net->addBlobs(ld.inputBlobsWrappers);
|
||||
ieNode->net->addBlobs(ld.outputBlobsWrappers);
|
||||
ienet.addBlobs(ld.inputBlobsWrappers);
|
||||
ienet.addBlobs(ld.outputBlobsWrappers);
|
||||
ld.skip = true;
|
||||
}
|
||||
layers[lastLayerId].skip = false;
|
||||
ieNode->net->init((Target)preferableTarget);
|
||||
ienet.init((Target)preferableTarget);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -3719,8 +3732,8 @@ void Net::forward(OutputArrayOfArrays outputBlobs,
|
||||
matvec.push_back(impl->getBlob(pins[i]));
|
||||
}
|
||||
|
||||
std::vector<Mat> & outputvec = *(std::vector<Mat> *)outputBlobs.getObj();
|
||||
outputvec = matvec;
|
||||
outputBlobs.create((int)matvec.size(), 1, CV_32F/*FIXIT*/, -1); // allocate vector
|
||||
outputBlobs.assign(matvec);
|
||||
}
|
||||
|
||||
void Net::forward(std::vector<std::vector<Mat> >& outputBlobs,
|
||||
|
@ -789,21 +789,32 @@ void NgraphBackendLayer::forward(InputArrayOfArrays inputs, OutputArrayOfArrays
|
||||
}
|
||||
|
||||
|
||||
static InferenceEngine::Layout estimateLayout(const Mat& m)
|
||||
static InferenceEngine::Layout estimateLayout(int dims)
|
||||
{
|
||||
if (m.dims == 4)
|
||||
if (dims == 4)
|
||||
return InferenceEngine::Layout::NCHW;
|
||||
else if (m.dims == 3)
|
||||
else if (dims == 3)
|
||||
return InferenceEngine::Layout::CHW;
|
||||
else if (m.dims == 2)
|
||||
else if (dims == 2)
|
||||
return InferenceEngine::Layout::NC;
|
||||
else if (m.dims == 1)
|
||||
else if (dims == 1)
|
||||
return InferenceEngine::Layout::C;
|
||||
else if (m.dims == 5)
|
||||
else if (dims == 5)
|
||||
return InferenceEngine::Layout::NCDHW;
|
||||
else
|
||||
return InferenceEngine::Layout::ANY;
|
||||
}
|
||||
static inline
|
||||
InferenceEngine::Layout estimateLayout(size_t dims)
|
||||
{
|
||||
return estimateLayout((int)dims);
|
||||
}
|
||||
|
||||
static inline
|
||||
InferenceEngine::Layout estimateLayout(const Mat& m)
|
||||
{
|
||||
return estimateLayout(m.dims);
|
||||
}
|
||||
|
||||
static InferenceEngine::DataPtr wrapToInfEngineDataNode(const Mat& m, const std::string& name = "")
|
||||
{
|
||||
@ -839,6 +850,7 @@ InferenceEngine::Blob::Ptr wrapToNgraphBlob(const Mat& m, InferenceEngine::Layou
|
||||
|
||||
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));
|
||||
@ -890,7 +902,11 @@ InferenceEngine::Blob::Ptr copyBlob(const InferenceEngine::Blob::Ptr& blob)
|
||||
copy = InferenceEngine::make_shared_blob<uint8_t>(description);
|
||||
}
|
||||
else
|
||||
CV_Error(Error::StsNotImplemented, "Unsupported blob precision");
|
||||
{
|
||||
std::ostringstream msg;
|
||||
msg << precision;
|
||||
CV_Error_(Error::StsNotImplemented, ("Unsupported blob precision: %s", msg.str().c_str()));
|
||||
}
|
||||
copy->allocate();
|
||||
return copy;
|
||||
}
|
||||
@ -903,6 +919,66 @@ InferenceEngine::DataPtr ngraphDataNode(const Ptr<BackendWrapper>& ptr)
|
||||
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;
|
||||
}
|
||||
|
||||
void forwardNgraph(const std::vector<Ptr<BackendWrapper> >& outBlobsWrappers,
|
||||
Ptr<BackendNode>& node, bool isAsync)
|
||||
@ -918,6 +994,13 @@ 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)
|
||||
|
@ -54,7 +54,8 @@ public:
|
||||
void setNodePtr(std::shared_ptr<ngraph::Node>* ptr);
|
||||
|
||||
void reset();
|
||||
private:
|
||||
|
||||
//private:
|
||||
detail::NetImplBase& netImpl_;
|
||||
|
||||
void release();
|
||||
@ -89,6 +90,8 @@ private:
|
||||
bool hasNetOwner;
|
||||
std::vector<std::string> requestedOutputs;
|
||||
std::unordered_set<std::shared_ptr<ngraph::Node>> unconnectedNodes;
|
||||
|
||||
std::map<std::string, InferenceEngine::TensorDesc> outputsDesc;
|
||||
};
|
||||
|
||||
class InfEngineNgraphNode : public BackendNode
|
||||
@ -121,12 +124,17 @@ public:
|
||||
virtual void copyToHost() CV_OVERRIDE;
|
||||
virtual void setHostDirty() CV_OVERRIDE;
|
||||
|
||||
Mat* host;
|
||||
InferenceEngine::DataPtr dataPtr;
|
||||
InferenceEngine::Blob::Ptr blob;
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user