diff --git a/modules/dnn/src/net_impl.cpp b/modules/dnn/src/net_impl.cpp index b66c7c759c..4e9b865963 100644 --- a/modules/dnn/src/net_impl.cpp +++ b/modules/dnn/src/net_impl.cpp @@ -64,7 +64,7 @@ Net::Impl::Impl() modelFormat = DNN_MODEL_GENERIC; originalLayout = DATA_LAYOUT_NCHW; - onnx_opset = 0; + // onnx_opset = 0; accuracy = CV_32F; enableFP16 = haveFP16 = false; diff --git a/modules/dnn/src/net_impl.hpp b/modules/dnn/src/net_impl.hpp index 209786d7b9..8eec5dbf3f 100644 --- a/modules/dnn/src/net_impl.hpp +++ b/modules/dnn/src/net_impl.hpp @@ -73,7 +73,7 @@ struct Net::Impl : public detail::NetImplBase std::string modelFileName; ModelFormat modelFormat; DataLayout originalLayout; - int onnx_opset; + // int onnx_opset; NamesHash argnames; NamesHash dimnames; diff --git a/modules/dnn/src/net_impl2.cpp b/modules/dnn/src/net_impl2.cpp index a00ccea48a..1dfe373de0 100644 --- a/modules/dnn/src/net_impl2.cpp +++ b/modules/dnn/src/net_impl2.cpp @@ -1119,10 +1119,6 @@ std::ostream& Net::Impl::dump(std::ostream& strm) strm << "{\n"; prindent(strm, indent); strm << "model_format: \"" << modelFormatToString(modelFormat) << "\",\n"; - if (modelFormat == DNN_MODEL_ONNX) { - prindent(strm, indent); - strm << "onnx_opset: " << onnx_opset << ",\n"; - } prindent(strm, indent); strm << "layout: \"" << layoutToString(originalLayout) << "\",\n"; if (mainGraph) { diff --git a/modules/dnn/src/onnx/onnx_importer.cpp b/modules/dnn/src/onnx/onnx_importer.cpp index 3338a86a88..3a9a7f8a91 100644 --- a/modules/dnn/src/onnx/onnx_importer.cpp +++ b/modules/dnn/src/onnx/onnx_importer.cpp @@ -141,8 +141,8 @@ private: DomainDispatchMap domain_dispatch_map; std::string getLayerTypeDomain(const opencv_onnx::NodeProto& node_proto); const DispatchMap& getDispatchMap(const opencv_onnx::NodeProto& node_proto); - void buildDispatchMap_ONNX_AI(int opset_version); - void buildDispatchMap_COM_MICROSOFT(int opset_version); + void buildDispatchMap_ONNX_AI(); + void buildDispatchMap_COM_MICROSOFT(); // Domain: 'ai.onnx' (default) // URL: https://github.com/onnx/onnx/blob/master/docs/Operators.md @@ -220,12 +220,11 @@ private: // '???' domain or '???' layer type void parseCustomLayer (LayerParams& layerParams, const opencv_onnx::NodeProto& node_proto); - int onnx_opset; // OperatorSetIdProto for 'onnx' domain std::map onnx_opset_map; // map from OperatorSetIdProto void parseOperatorSet(); const std::string str_domain_ai_onnx = "ai.onnx"; - + const std::string str_domain_com_microsoft = "com.microsoft"; bool useLegacyNames; bool getParamUseLegacyNames() @@ -272,7 +271,6 @@ void ONNXLayerHandler::fillRegistry(const opencv_onnx::GraphProto &net) ONNXImporter::ONNXImporter(Net& net, const char *onnxFile) : layerHandler(DNN_DIAGNOSTICS_RUN ? new ONNXLayerHandler(this) : nullptr) , dstNet(net) - , onnx_opset(0) , useLegacyNames(getParamUseLegacyNames()) { hasDynamicShapes = false; @@ -296,7 +294,6 @@ ONNXImporter::ONNXImporter(Net& net, const char *onnxFile) ONNXImporter::ONNXImporter(Net& net, const char* buffer, size_t sizeBuffer) : layerHandler(DNN_DIAGNOSTICS_RUN ? new ONNXLayerHandler(this) : nullptr) , dstNet(net) - , onnx_opset(0) , useLegacyNames(getParamUseLegacyNames()) { hasDynamicShapes = false; @@ -705,22 +702,24 @@ void ONNXImporter::parseOperatorSet() const ::opencv_onnx::OperatorSetIdProto& opset_entry = model_proto.opset_import(i); const std::string& domain = opset_entry.has_domain() ? opset_entry.domain() : std::string(); int version = opset_entry.has_version() ? opset_entry.version() : -1; - if (domain.empty() || domain == str_domain_ai_onnx) - { - // ONNX opset covered by specification: https://github.com/onnx/onnx/blob/master/docs/Operators.md - onnx_opset = std::max(onnx_opset, version); - onnx_opset_map[str_domain_ai_onnx] = onnx_opset; - } + const std::string domain_key = domain.empty() ? str_domain_ai_onnx : domain; + if (onnx_opset_map.find(domain_key) == onnx_opset_map.end()) + onnx_opset_map[domain_key] = version; else + onnx_opset_map[domain_key] = std::max( + onnx_opset_map[domain_key], version); + if ( + domain_key != str_domain_ai_onnx && + domain_key != str_domain_com_microsoft) { - CV_LOG_DEBUG(NULL, "DNN/ONNX: using non-standard ONNX opset[" << i << "]: domain='" << domain << "' version=" << version); - onnx_opset_map[domain] = onnx_opset; + CV_LOG_INFO(NULL, "DNN/ONNX: found opset[" << i << "]: domain='" << domain_key << "' version=" << version); } } - CV_LOG_INFO(NULL, "DNN/ONNX: ONNX opset version = " << onnx_opset); + // CV_LOG_INFO(NULL, "DNN/ONNX: ONNX opset version = " << onnx_opset); - buildDispatchMap_ONNX_AI(onnx_opset); + buildDispatchMap_ONNX_AI(); // onnx_opset_map[str_domain_ai_onnx]); + buildDispatchMap_COM_MICROSOFT(); // onnx_opset_map[str_domain_com_microsoft]); for (const auto& pair : onnx_opset_map) { if (pair.first == str_domain_ai_onnx) @@ -729,7 +728,7 @@ void ONNXImporter::parseOperatorSet() } else if (pair.first == "com.microsoft") { - buildDispatchMap_COM_MICROSOFT(pair.second); + buildDispatchMap_COM_MICROSOFT(); } else { @@ -2811,7 +2810,11 @@ void ONNXImporter::parseSoftMax(LayerParams& layerParams, const opencv_onnx::Nod { const std::string& layer_type = node_proto.op_type(); int axis; - if (onnx_opset != 0 && onnx_opset <= 11) { + if (onnx_opset_map.find(str_domain_ai_onnx) == onnx_opset_map.end()) { + CV_Error(Error::StsParseError , "ONNX/Softmax: opset for ai.onnx domain is not found"); + } + const int opset_onnx_ai = onnx_opset_map[str_domain_ai_onnx]; + if (opset_onnx_ai != 0 && opset_onnx_ai <= 11) { axis = layerParams.get("axis", 1); } else { axis = layerParams.get("axis", -1); @@ -3954,9 +3957,8 @@ void ONNXImporter::parseAttention(LayerParams& params, const opencv_onnx::NodePr // Domain: ai.onnx (default) // URL: https://github.com/onnx/onnx/blob/master/docs/Operators.md -void ONNXImporter::buildDispatchMap_ONNX_AI(int opset_version) +void ONNXImporter::buildDispatchMap_ONNX_AI() { - CV_UNUSED(opset_version); DispatchMap dispatch; dispatch["ArgMax"] = dispatch["ArgMin"] = &ONNXImporter::parseArg; @@ -4049,9 +4051,8 @@ void ONNXImporter::buildDispatchMap_ONNX_AI(int opset_version) // Domain: com.microsoft // URL: https://github.com/microsoft/onnxruntime/blob/master/docs/ContribOperators.md -void ONNXImporter::buildDispatchMap_COM_MICROSOFT(int opset_version) +void ONNXImporter::buildDispatchMap_COM_MICROSOFT() { - CV_UNUSED(opset_version); DispatchMap dispatch; dispatch["QLinearAdd"] = dispatch["QLinearMul"] = &ONNXImporter::parseQEltwise; diff --git a/modules/dnn/src/onnx/onnx_importer2.cpp b/modules/dnn/src/onnx/onnx_importer2.cpp index e4c730f6b7..c9ca79b0a5 100644 --- a/modules/dnn/src/onnx/onnx_importer2.cpp +++ b/modules/dnn/src/onnx/onnx_importer2.cpp @@ -166,8 +166,8 @@ protected: DomainDispatchMap domain_dispatch_map; std::string getLayerTypeDomain(const opencv_onnx::NodeProto& node_proto); const DispatchMap& getDispatchMap(const opencv_onnx::NodeProto& node_proto); - void buildDispatchMap_ONNX_AI(int opset_version); - void buildDispatchMap_COM_MICROSOFT(int opset_version); + void buildDispatchMap_ONNX_AI(); + void buildDispatchMap_COM_MICROSOFT(); // Domain: 'ai.onnx' (default) // URL: https://github.com/onnx/onnx/blob/master/docs/Operators.md @@ -264,7 +264,6 @@ protected: //void parseQSigmoid (LayerParams& layerParams, const opencv_onnx::NodeProto& node_proto); //void parseQSoftmax (LayerParams& layerParams, const opencv_onnx::NodeProto& node_proto); - int onnx_opset; // OperatorSetIdProto for 'onnx' domain std::map onnx_opset_map; // map from OperatorSetIdProto void parseOperatorSet(); @@ -282,7 +281,6 @@ protected: }; ONNXImporter2::ONNXImporter2() : - onnx_opset(0), useLegacyNames(getParamUseLegacyNames()) { netimpl = net.getImpl(); @@ -577,33 +575,24 @@ void ONNXImporter2::parseOperatorSet() const ::opencv_onnx::OperatorSetIdProto& opset_entry = model_proto.opset_import(i); const std::string& domain = opset_entry.has_domain() ? opset_entry.domain() : std::string(); int version = opset_entry.has_version() ? opset_entry.version() : -1; - if (domain.empty() || domain == str_domain_ai_onnx) - { - // ONNX opset covered by specification: https://github.com/onnx/onnx/blob/master/docs/Operators.md - onnx_opset = std::max(onnx_opset, version); - onnx_opset_map[str_domain_ai_onnx] = onnx_opset; - } + const std::string domain_key = domain.empty() ? str_domain_ai_onnx : domain; + + if (onnx_opset_map.find(domain_key) == onnx_opset_map.end()) + onnx_opset_map[domain_key] = version; else + onnx_opset_map[domain_key] = std::max( + onnx_opset_map[domain_key], version); + + if ( + domain_key != str_domain_ai_onnx && + domain_key != str_domain_com_microsoft) { - CV_LOG_DEBUG(NULL, "DNN/ONNX: using non-standard ONNX opset[" << i << "]: domain='" << domain << "' version=" << version); - onnx_opset_map[domain] = onnx_opset; + CV_LOG_INFO(NULL, "DNN/ONNX: found opset[" << i << "]: domain='" << domain_key << "' version=" << version); } } + buildDispatchMap_ONNX_AI(); + buildDispatchMap_COM_MICROSOFT(); - CV_LOG_INFO(NULL, "DNN/ONNX: ONNX opset version = " << onnx_opset); - - buildDispatchMap_ONNX_AI(onnx_opset); - buildDispatchMap_COM_MICROSOFT(onnx_opset); - - for (const auto& pair : onnx_opset_map) - { - if ((pair.first != str_domain_ai_onnx) && (pair.first != str_domain_com_microsoft)) - CV_LOG_INFO( - NULL, - "DNN/ONNX: unknown domain='" << pair.first << "' version=" << pair.second << ". No dispatch map, you may need to register 'custom' layers." - ); - - } } /*static bool ifInt8Output(const String& layerType) @@ -679,7 +668,7 @@ Net ONNXImporter2::parseModel() netimpl->mainGraph = mainGraph; netimpl->modelFormat = DNN_MODEL_ONNX; netimpl->originalLayout = DATA_LAYOUT_NCHW; - netimpl->onnx_opset = onnx_opset; + // netimpl->onnx_opset = onnx_opset; if (have_errors) { std::stringstream sstrm; @@ -1877,7 +1866,12 @@ void ONNXImporter2::parseSoftMax(LayerParams& layerParams, const opencv_onnx::No { const std::string& layer_type = node_proto.op_type(); int axis; - if (onnx_opset != 0 && onnx_opset <= 11) { + if (onnx_opset_map.find(str_domain_ai_onnx) == onnx_opset_map.end()) { + CV_Error(Error::StsParseError , "ONNX/Softmax: opset for ai.onnx domain is not found"); + } + const int opset_onnx_ai = onnx_opset_map[str_domain_ai_onnx]; + + if (opset_onnx_ai != 0 && opset_onnx_ai <= 11) { axis = layerParams.get("axis", 1); } else { axis = layerParams.get("axis", -1); @@ -2619,9 +2613,8 @@ void ONNXImporter2::parseAttention(LayerParams& params, const opencv_onnx::NodeP // Domain: ai.onnx (default) // URL: https://github.com/onnx/onnx/blob/master/docs/Operators.md -void ONNXImporter2::buildDispatchMap_ONNX_AI(int opset_version) +void ONNXImporter2::buildDispatchMap_ONNX_AI() { - CV_UNUSED(opset_version); DispatchMap dispatch; dispatch["ArgMax"] = dispatch["ArgMin"] = &ONNXImporter2::parseArgMinMax; @@ -2738,9 +2731,8 @@ void ONNXImporter2::buildDispatchMap_ONNX_AI(int opset_version) // Domain: com.microsoft // URL: https://github.com/microsoft/onnxruntime/blob/master/docs/ContribOperators.md -void ONNXImporter2::buildDispatchMap_COM_MICROSOFT(int opset_version) +void ONNXImporter2::buildDispatchMap_COM_MICROSOFT() { - CV_UNUSED(opset_version); DispatchMap dispatch; // BUG: https://github.com/opencv/opencv/issues/26310