/*************************************************
USAGE:
-./model_diagnostics -m <onnx file location>
+./model_diagnostics -m <model file location>
**************************************************/
#include <opencv2/dnn.hpp>
#include <opencv2/core/utils/filesystem.hpp>
}
std::string diagnosticKeys =
- "{ model m | | Path to the model .onnx file. }"
+ "{ model m | | Path to the model file. }"
"{ config c | | Path to the model configuration file. }"
"{ framework f | | [Optional] Name of the model framework. }";
int main( int argc, const char** argv )
{
CommandLineParser argParser(argc, argv, diagnosticKeys);
- argParser.about("Use this tool to run the diagnostics of provided ONNX model"
+ argParser.about("Use this tool to run the diagnostics of provided ONNX/TF model"
"to obtain the information about its support (supported layers).");
if (argc == 1)
namespace dnn {
CV__DNN_INLINE_NS_BEGIN
+extern bool DNN_DIAGNOSTICS_RUN;
+
#if HAVE_PROTOBUF
using ::google::protobuf::RepeatedField;
TFImporter(Net& net, const char *dataModel, size_t lenModel,
const char *dataConfig = NULL, size_t lenConfig = 0);
protected:
+ std::unique_ptr<Net> utilNet;
Net& dstNet;
void populateNet();
}
TFImporter::TFImporter(Net& net, const char *model, const char *config)
- : dstNet(net), dispatch(buildDispatchMap())
+ : utilNet(DNN_DIAGNOSTICS_RUN ? new Net : nullptr),
+ dstNet(DNN_DIAGNOSTICS_RUN ? *utilNet : net), dispatch(buildDispatchMap())
{
if (model && model[0])
{
const char *dataModel, size_t lenModel,
const char *dataConfig, size_t lenConfig
)
- : dstNet(net), dispatch(buildDispatchMap())
+ : utilNet(DNN_DIAGNOSTICS_RUN ? new Net : nullptr),
+ dstNet(DNN_DIAGNOSTICS_RUN ? *utilNet : net), dispatch(buildDispatchMap())
{
if (dataModel != NULL && lenModel > 0)
{
return it->second;
}
+Ptr<Layer> dummy_constructor(LayerParams & params)
+{
+ return new Layer(params);
+}
+
void TFImporter::populateNet()
{
CV_Assert(netBin.ByteSize() || netTxt.ByteSize());
const std::string& name = layer.name();
const std::string& type = layer.op();
+ LayerParams layerParams;
try
{
- LayerParams layerParams;
if (layers_to_ignore.find(name) != layers_to_ignore.end())
{
}
else
{
+ if (DNN_DIAGNOSTICS_RUN && !LayerFactory::createLayerInstance(type, layerParams))
+ {
+ CV_LOG_ERROR(NULL, "DNN/TF: Node='" << name << "' of type='"<< type
+ << "' is not supported. This error won't be displayed again.");
+ LayerFactory::registerLayer(type, dummy_constructor);
+ }
+
parseCustomLayer(net, layer, layerParams);
}
}
catch (const std::exception& e)
{
- CV_LOG_ERROR(NULL, "DNN/TF: Can't parse layer for node='" << name << "'. Exception: " << e.what());
- throw;
+ if (!DNN_DIAGNOSTICS_RUN)
+ {
+ CV_LOG_ERROR(NULL, "DNN/TF: Can't parse layer for node='" << name << "' of type='" << type
+ << "'. Exception: " << e.what());
+ throw;
+ }
+ else
+ {
+ CV_LOG_ERROR(NULL, "DNN/TF: Can't parse layer for node='" << name << "' of type='" << type
+ << "'. Exception: " << e.what());
+
+ // internal layer failure (didnt call addLayer)
+ if (dstNet.getLayerId(name) == -1)
+ {
+ int id = dstNet.addLayer(name, type, layerParams);
+ layer_id[name] = id;
+ }
+ }
}
}