dnn: update network dump code, include ngraph serialization

This commit is contained in:
Alexander Alekhin 2020-05-26 12:45:55 +00:00
parent d5e8792f55
commit f0bef94a03
5 changed files with 91 additions and 26 deletions

View File

@ -1082,17 +1082,26 @@ static Ptr<BackendWrapper> wrapMat(int backendId, int targetId, cv::Mat& m)
static int g_networkId = 0; static int g_networkId = 0;
struct Net::Impl detail::NetImplBase::NetImplBase()
: networkId(CV_XADD(&g_networkId, 1))
, networkDumpCounter(0)
, dumpLevel(DNN_NETWORK_DUMP)
{
// nothing
}
std::string detail::NetImplBase::getDumpFileNameBase()
{
std::string dumpFileNameBase = cv::format("ocv_dnn_net_%05d_%02d", networkId, networkDumpCounter++);
return dumpFileNameBase;
}
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;
const int networkId; // network global identifier
int networkDumpCounter; // dump counter
Impl() Impl()
: networkId(CV_XADD(&g_networkId, 1))
, networkDumpCounter(0)
{ {
//allocate fake net input layer //allocate fake net input layer
netInputLayer = Ptr<DataLayer>(new DataLayer()); netInputLayer = Ptr<DataLayer>(new DataLayer());
@ -1256,7 +1265,7 @@ struct Net::Impl
{ {
CV_TRACE_FUNCTION(); CV_TRACE_FUNCTION();
if (DNN_NETWORK_DUMP > 0 && networkDumpCounter == 0) if (dumpLevel && networkDumpCounter == 0)
{ {
dumpNetworkToFile(); dumpNetworkToFile();
} }
@ -1339,7 +1348,7 @@ struct Net::Impl
netWasAllocated = true; netWasAllocated = true;
if (DNN_NETWORK_DUMP > 0) if (dumpLevel)
{ {
dumpNetworkToFile(); dumpNetworkToFile();
} }
@ -2043,7 +2052,7 @@ struct Net::Impl
} }
if (net.empty()) { if (net.empty()) {
net = Ptr<InfEngineNgraphNet>(new InfEngineNgraphNet()); net = Ptr<InfEngineNgraphNet>(new InfEngineNgraphNet(*this));
} }
if (!fused) { if (!fused) {
@ -2087,7 +2096,7 @@ struct Net::Impl
} }
} }
else { else {
net = Ptr<InfEngineNgraphNet>(new InfEngineNgraphNet()); net = Ptr<InfEngineNgraphNet>(new InfEngineNgraphNet(*this));
} }
if (!fused) if (!fused)
@ -3126,7 +3135,8 @@ struct Net::Impl
void dumpNetworkToFile() void dumpNetworkToFile()
{ {
#ifndef OPENCV_DNN_DISABLE_NETWORK_AUTO_DUMP #ifndef OPENCV_DNN_DISABLE_NETWORK_AUTO_DUMP
String dumpFileName = cv::format("ocv_dnn_net_%05d_%02d.dot", networkId, networkDumpCounter++); string dumpFileNameBase = getDumpFileNameBase();
string dumpFileName = dumpFileNameBase + ".dot";
try try
{ {
string dumpStr = dump(); string dumpStr = dump();
@ -3185,7 +3195,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(ieNet)); backendNodeNGraph->net = Ptr<InfEngineNgraphNet>(new InfEngineNgraphNet(*(cvNet.impl), ieNet));
backendNode = backendNodeNGraph; backendNode = backendNodeNGraph;
} }
else else

View File

@ -0,0 +1,34 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#ifndef __OPENCV_DNN_COMMON_HPP__
#define __OPENCV_DNN_COMMON_HPP__
#include <opencv2/dnn.hpp>
namespace cv { namespace dnn {
CV__DNN_EXPERIMENTAL_NS_BEGIN
#define IS_DNN_OPENCL_TARGET(id) (id == DNN_TARGET_OPENCL || id == DNN_TARGET_OPENCL_FP16)
Mutex& getInitializationMutex();
void initializeLayerFactory();
namespace detail {
struct NetImplBase
{
const int networkId; // network global identifier
int networkDumpCounter; // dump counter
int dumpLevel; // level of information dumps (initialized through OPENCV_DNN_NETWORK_DUMP parameter)
NetImplBase();
std::string getDumpFileNameBase();
};
} // namespace detail
CV__DNN_EXPERIMENTAL_NS_END
}} // namespace
#endif // __OPENCV_DNN_COMMON_HPP__

View File

@ -6,6 +6,9 @@
// Third party copyrights are property of their respective owners. // Third party copyrights are property of their respective owners.
#include "precomp.hpp" #include "precomp.hpp"
#include <fstream>
#include "ie_ngraph.hpp" #include "ie_ngraph.hpp"
#include <opencv2/dnn/shape_utils.hpp> #include <opencv2/dnn/shape_utils.hpp>
@ -22,6 +25,8 @@ namespace cv { namespace dnn {
#ifdef HAVE_DNN_NGRAPH #ifdef HAVE_DNN_NGRAPH
static bool DNN_IE_SERIALIZE = utils::getConfigurationParameterBool("OPENCV_DNN_IE_SERIALIZE", false);
// For networks with input layer which has an empty name, IE generates a name id[some_number]. // For networks with input layer which has an empty name, IE generates a name id[some_number].
// OpenCV lets users use an empty input name and to prevent unexpected naming, // OpenCV lets users use an empty input name and to prevent unexpected naming,
// we can use some predefined name. // we can use some predefined name.
@ -295,13 +300,16 @@ void InfEngineNgraphNode::setName(const std::string& name) {
node->set_friendly_name(name); node->set_friendly_name(name);
} }
InfEngineNgraphNet::InfEngineNgraphNet() InfEngineNgraphNet::InfEngineNgraphNet(detail::NetImplBase& netImpl)
: netImpl_(netImpl)
{ {
hasNetOwner = false; hasNetOwner = false;
device_name = "CPU"; device_name = "CPU";
} }
InfEngineNgraphNet::InfEngineNgraphNet(InferenceEngine::CNNNetwork& net) : cnn(net) InfEngineNgraphNet::InfEngineNgraphNet(detail::NetImplBase& netImpl, InferenceEngine::CNNNetwork& net)
: netImpl_(netImpl)
, cnn(net)
{ {
hasNetOwner = true; hasNetOwner = true;
device_name = "CPU"; device_name = "CPU";
@ -440,9 +448,27 @@ void InfEngineNgraphNet::init(Target targetId)
ngraph_function->validate_nodes_and_infer_types(); ngraph_function->validate_nodes_and_infer_types();
} }
cnn = InferenceEngine::CNNNetwork(ngraph_function); cnn = InferenceEngine::CNNNetwork(ngraph_function);
#ifdef _DEBUG // TODO
//cnn.serialize("/tmp/cnn.xml", "/tmp/cnn.bin"); if (DNN_IE_SERIALIZE)
{
#ifndef OPENCV_DNN_DISABLE_NETWORK_AUTO_DUMP
std::string dumpFileNameBase = netImpl_.getDumpFileNameBase();
try
{
cnn.serialize(dumpFileNameBase + "_ngraph.xml", dumpFileNameBase + "_ngraph.bin");
}
catch (const std::exception& e)
{
std::ofstream out((dumpFileNameBase + "_ngraph.error").c_str(), std::ios::out);
out << "Exception: " << e.what() << std::endl;
}
catch (...)
{
std::ofstream out((dumpFileNameBase + "_ngraph.error").c_str(), std::ios::out);
out << "Can't dump: unknown exception" << std::endl;
}
#endif #endif
}
} }
switch (targetId) switch (targetId)

View File

@ -34,8 +34,8 @@ class InfEngineNgraphNode;
class InfEngineNgraphNet class InfEngineNgraphNet
{ {
public: public:
InfEngineNgraphNet(); InfEngineNgraphNet(detail::NetImplBase& netImpl);
InfEngineNgraphNet(InferenceEngine::CNNNetwork& net); InfEngineNgraphNet(detail::NetImplBase& netImpl, InferenceEngine::CNNNetwork& net);
void addOutput(const std::string& name); void addOutput(const std::string& name);
@ -55,6 +55,8 @@ public:
void reset(); void reset();
private: private:
detail::NetImplBase& netImpl_;
void release(); void release();
int getNumComponents(); int getNumComponents();
void dfs(std::shared_ptr<ngraph::Node>& node, std::vector<std::shared_ptr<ngraph::Node>>& comp, void dfs(std::shared_ptr<ngraph::Node>& node, std::vector<std::shared_ptr<ngraph::Node>>& comp,

View File

@ -61,11 +61,4 @@
#include <opencv2/dnn.hpp> #include <opencv2/dnn.hpp>
#include <opencv2/dnn/all_layers.hpp> #include <opencv2/dnn/all_layers.hpp>
#include "dnn_common.hpp"
namespace cv { namespace dnn {
CV__DNN_EXPERIMENTAL_NS_BEGIN
#define IS_DNN_OPENCL_TARGET(id) (id == DNN_TARGET_OPENCL || id == DNN_TARGET_OPENCL_FP16)
Mutex& getInitializationMutex();
void initializeLayerFactory();
CV__DNN_EXPERIMENTAL_NS_END
}} // namespace