diff --git a/include/onnxruntime/core/graph/graph.h b/include/onnxruntime/core/graph/graph.h index b7f2747d5e..fa2d66761a 100644 --- a/include/onnxruntime/core/graph/graph.h +++ b/include/onnxruntime/core/graph/graph.h @@ -98,6 +98,12 @@ class Node { @remarks The graph containing this node must be resolved, otherwise nullptr will be returned. */ const ONNX_NAMESPACE::OpSchema* Op() const noexcept; + /** Gets the opset version that the Node's operator was first defined in. + @returns Opset version. If -1 the Node's operator has not been set. + @remarks Prefer over Op()->SinceVersion() as Op() is disabled in a minimal build + */ + int SinceVersion() const noexcept { return since_version_; } + /** Gets the Node's Node::Type. */ Node::Type NodeType() const noexcept; @@ -112,7 +118,7 @@ class Node { Nodes of type "Fused" are created during partitioning and the function body initialization for such nodes also happens during node creation. Therefore, initialization of function body will happen via this method only in case 2 mentioned above. - */ + */ const Function* GetFunctionBody(bool try_init_func_body = true); /** Gets the function body if applicable otherwise nullptr. */ @@ -469,6 +475,10 @@ class Node { // OperatorSchema that <*this> node refers to. const ONNX_NAMESPACE::OpSchema* op_ = nullptr; + + // set from op_->SinceVersion() or via deserialization when OpSchema is not available + int since_version_ = -1; + Node::Type node_type_ = Node::Type::Primitive; // The function body is owned by graph_ @@ -565,7 +575,7 @@ class Graph { } /** Return true if "node_arg" is a input or an initializer. Otherwise, returns false. */ - bool IsInputsIncludingInitializers(const NodeArg* node_arg) const noexcept{ + bool IsInputsIncludingInitializers(const NodeArg* node_arg) const noexcept { return std::find(graph_inputs_including_initializers_.begin(), graph_inputs_including_initializers_.end(), node_arg) != graph_inputs_including_initializers_.end(); } @@ -581,7 +591,7 @@ class Graph { @remarks Contains no nullptr values.*/ const std::vector& GetOutputs() const noexcept { return graph_outputs_; } - bool IsOutput(const NodeArg* node_arg) const noexcept{ + bool IsOutput(const NodeArg* node_arg) const noexcept { return std::find(graph_outputs_.begin(), graph_outputs_.end(), node_arg) != graph_outputs_.end(); } @@ -814,7 +824,7 @@ class Graph { @param node Node with Node::Type of Node::Type::Fused @returns Status indicating success or providing an error message. */ - Status InlineFunction(Node& node); + Status InlineFunction(Node& node); /** Initialize function body for the given node */ void InitFunctionBodyForNode(Node& node); diff --git a/onnxruntime/core/framework/kernel_registry.cc b/onnxruntime/core/framework/kernel_registry.cc index 844c2a0d9d..3774cbf4d8 100644 --- a/onnxruntime/core/framework/kernel_registry.cc +++ b/onnxruntime/core/framework/kernel_registry.cc @@ -121,7 +121,7 @@ bool KernelRegistry::VerifyKernelDef(const onnxruntime::Node& node, int kernel_end_version; kernel_def.SinceVersion(&kernel_start_version, &kernel_end_version); - int node_since_version = node.Op()->since_version(); + int node_since_version = node.SinceVersion(); // Ideal case is, if schema is Since(5), current opset version is opset 7, // kernel_def Since(8) Invalid // kernel_def Since(6) Valid diff --git a/onnxruntime/core/framework/kernel_registry_manager.cc b/onnxruntime/core/framework/kernel_registry_manager.cc index f7136f5b6e..e7823f3722 100644 --- a/onnxruntime/core/framework/kernel_registry_manager.cc +++ b/onnxruntime/core/framework/kernel_registry_manager.cc @@ -62,8 +62,7 @@ Status KernelRegistryManager::SearchKernelRegistry(const onnxruntime::Node& node auto create_error_message = [&node, &status](const std::string& prefix) { std::ostringstream errormsg; - errormsg << prefix << node.OpType(); - if (node.Op() != nullptr) errormsg << "(" << node.Op()->since_version() << ")"; + errormsg << prefix << node.OpType() << "(" << node.SinceVersion() << ")"; if (!node.Name().empty()) errormsg << " (node " << node.Name() << "). "; if (!status.IsOK()) errormsg << status.ErrorMessage(); diff --git a/onnxruntime/core/graph/graph.cc b/onnxruntime/core/graph/graph.cc index 3a7cbc68c9..296cdaeba7 100644 --- a/onnxruntime/core/graph/graph.cc +++ b/onnxruntime/core/graph/graph.cc @@ -453,6 +453,7 @@ const Function* Node::GetFunctionBody() const noexcept { void Node::SetFunctionBody(const Function& func) { func_body_ = &func; op_ = &func.OpSchema(); + since_version_ = op_->since_version(); } const std::string& Node::GetExecutionProviderType() const noexcept { @@ -2053,11 +2054,13 @@ Status Graph::VerifyNodeAndOpMatch(const ResolveOptions& options) { node.op_ = nullptr; } - InitFunctionBodyForNode(node); + InitFunctionBodyForNode(node); if (!node.op_) { return Status(ONNXRUNTIME, FAIL, "Fatal error: " + node.OpType() + " is not a registered function/op"); } + + node.since_version_ = node.op_->since_version(); } ORT_RETURN_IF_ERROR(node.UpdateInputArgCount()); diff --git a/onnxruntime/core/graph/graph_utils.cc b/onnxruntime/core/graph/graph_utils.cc index 4065fa67a5..9100d3685f 100644 --- a/onnxruntime/core/graph/graph_utils.cc +++ b/onnxruntime/core/graph/graph_utils.cc @@ -294,11 +294,11 @@ bool IsSupportedOptypeVersionAndDomain(const Node& node, } bool MatchesOpSinceVersion(const Node& node, const std::initializer_list& versions) { - return std::find(versions.begin(), versions.end(), node.Op()->SinceVersion()) != versions.end(); + return std::find(versions.begin(), versions.end(), node.SinceVersion()) != versions.end(); } bool MatchesOpSinceVersion(const Node& node, const std::vector& versions) { - return std::find(versions.begin(), versions.end(), node.Op()->SinceVersion()) != versions.end(); + return std::find(versions.begin(), versions.end(), node.SinceVersion()) != versions.end(); } bool MatchesOpSetDomain(const Node& node, const std::string& domain) { @@ -722,7 +722,8 @@ bool FindPath(const Node& node, bool is_input_edge, const std::vectorGetSrcArgIndex() << "," << it->GetDstArgIndex() - << "," << it->GetNode().OpType() << "," << it->GetNode().Domain() << "," << it->GetNode().Op()->SinceVersion(); + << "," << it->GetNode().OpType() << "," << it->GetNode().Domain() << "," + << it->GetNode().SinceVersion(); #endif if (edge.dst_arg_index == it->GetDstArgIndex() && edge.src_arg_index == it->GetSrcArgIndex() && diff --git a/onnxruntime/core/optimizer/nchwc_transformer.cc b/onnxruntime/core/optimizer/nchwc_transformer.cc index 7414c99e13..a4a6716344 100644 --- a/onnxruntime/core/optimizer/nchwc_transformer.cc +++ b/onnxruntime/core/optimizer/nchwc_transformer.cc @@ -847,7 +847,7 @@ void NchwcTransformerImpl::TransformResize(Node& node) { } NodeArg* scales_arg; - if (node.Op()->SinceVersion() >= 11) { + if (node.SinceVersion() >= 11) { // Bail out if Resize has the optional "sizes" tensor. if (input_defs.size() == 3) { scales_arg = input_defs[2]; diff --git a/onnxruntime/core/providers/cpu/nn/pool_base.h b/onnxruntime/core/providers/cpu/nn/pool_base.h index 4aa86c7c15..3d1edfbdaf 100644 --- a/onnxruntime/core/providers/cpu/nn/pool_base.h +++ b/onnxruntime/core/providers/cpu/nn/pool_base.h @@ -101,13 +101,13 @@ class LpPool { class PoolBase { private: static int GetStartVersion(const OpKernelInfo& info) { - return info.node().Op()->since_version(); + return info.node().SinceVersion(); } protected: PoolBase(const OpKernelInfo& info) - : op_name_(info.GetKernelDef().OpName()), - pool_attrs_(info, op_name_, GetStartVersion(info)) { + : op_name_(info.GetKernelDef().OpName()), + pool_attrs_(info, op_name_, GetStartVersion(info)) { } ~PoolBase() = default; diff --git a/onnxruntime/core/providers/cpu/tensor/upsample.h b/onnxruntime/core/providers/cpu/tensor/upsample.h index 82c33ca052..18c50d7208 100644 --- a/onnxruntime/core/providers/cpu/tensor/upsample.h +++ b/onnxruntime/core/providers/cpu/tensor/upsample.h @@ -48,7 +48,7 @@ class UpsampleBase { protected: UpsampleBase(OpKernelInfo info) : scales_cached_(false), roi_cached_(false), use_extrapolation_(false) { const auto& node = info.node(); - auto opset = node.Op()->SinceVersion(); + auto opset = node.SinceVersion(); is_resize_ = (opset >= 10); std::string mode; diff --git a/onnxruntime/core/session/inference_session.cc b/onnxruntime/core/session/inference_session.cc index 5e8c7c74c9..f6fc2b9ba8 100644 --- a/onnxruntime/core/session/inference_session.cc +++ b/onnxruntime/core/session/inference_session.cc @@ -657,10 +657,8 @@ common::Status InferenceSession::TransformGraph(onnxruntime::Graph& graph, oss << "Could not find an implementation for the node "; if (!node.Name().empty()) oss << node.Name() << ":"; - oss << node.OpType(); - if (node.Op()) { - oss << "(" << node.Op()->since_version() << ")"; - } + oss << node.OpType() << "(" << node.SinceVersion() << ")"; + return Status(common::ONNXRUNTIME, common::NOT_IMPLEMENTED, oss.str()); } else { if (is_verbose_mode) { // TODO: should we disable this if the number of nodes are above a certain threshold?