提交 fbde0c6c 编写于 作者: A Alexander Alekhin

dnn(ie): fix handling of 1D and non-32F outputs of InferenceEngine

上级 602e7c83
......@@ -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
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册