Add Node::SinceVersion() (#4874)

* Add Node::SinceVersion() so that the value is known when loading a graph from the ORT format (OpSchema is not available).

* Fix build warning from returning 'const int'
This commit is contained in:
Scott McKay 2020-08-21 16:48:52 +10:00 committed by GitHub
parent d4d52056be
commit ef19916d07
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 31 additions and 20 deletions

View file

@ -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<const NodeArg*>& 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);

View file

@ -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

View file

@ -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();

View file

@ -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());

View file

@ -294,11 +294,11 @@ bool IsSupportedOptypeVersionAndDomain(const Node& node,
}
bool MatchesOpSinceVersion(const Node& node, const std::initializer_list<ONNX_NAMESPACE::OperatorSetVersion>& 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<ONNX_NAMESPACE::OperatorSetVersion>& 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::vector<EdgeEndToM
for (auto it = edges_begin; it != edges_end; ++it) {
#ifndef NDEBUG
LOGS(logger, VERBOSE) << "E:" << it->GetSrcArgIndex() << "," << 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() &&

View file

@ -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];

View file

@ -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;

View file

@ -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;

View file

@ -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?