From 7d3e3fd76a002cd1dd78cb7f11bab760fb5abecb Mon Sep 17 00:00:00 2001 From: Malcolm Reynolds Date: Thu, 26 Apr 2018 16:24:51 -0700 Subject: [PATCH] More informative error message when loading a graph_def which uses unknown ops. Fixes #17014 PiperOrigin-RevId: 194472083 --- tensorflow/core/framework/op.cc | 27 ++++++++++++++++--------- tensorflow/core/graph/graph_constructor_test.cc | 15 ++++++++++++++ 2 files changed, 33 insertions(+), 9 deletions(-) diff --git a/tensorflow/core/framework/op.cc b/tensorflow/core/framework/op.cc index 5f68c59..0873d4e 100644 --- a/tensorflow/core/framework/op.cc +++ b/tensorflow/core/framework/op.cc @@ -91,11 +91,15 @@ Status OpRegistry::LookUp(const string& op_type_name, } } } - Status status = - errors::NotFound("Op type not registered '", op_type_name, - "' in binary running on ", port::Hostname(), ". ", - "Make sure the Op and Kernel are registered in the " - "binary running in this process."); + Status status = errors::NotFound( + "Op type not registered '", op_type_name, "' in binary running on ", + port::Hostname(), ". ", + "Make sure the Op and Kernel are registered in the " + "binary running in this process. Note that if you " + "are loading a saved graph which used ops from " + "tf.contrib, accessing (e.g.) `tf.contrib.resampler` should be done" + "before importing the graph, as contrib ops are lazily registered " + "when the module is first accessed."); VLOG(1) << status.ToString(); return status; } @@ -246,10 +250,15 @@ Status OpListOpRegistry::LookUp(const string& op_type_name, auto iter = index_.find(op_type_name); if (iter == index_.end()) { *op_reg_data = nullptr; - return errors::NotFound("Op type not registered '", op_type_name, - "' in binary running on ", port::Hostname(), ". ", - "Make sure the Op and Kernel are registered in the " - "binary running in this process."); + return errors::NotFound( + "Op type not registered '", op_type_name, "' in binary running on ", + port::Hostname(), ". ", + "Make sure the Op and Kernel are registered in the " + "binary running in this process. Note that if you " + "are loading a saved graph which used ops from " + "tf.contrib, accessing (e.g.) `tf.contrib.resampler` should be done" + "before importing the graph, as contrib ops are lazily registered " + "when the module is first accessed."); } *op_reg_data = iter->second; return Status::OK(); diff --git a/tensorflow/core/graph/graph_constructor_test.cc b/tensorflow/core/graph/graph_constructor_test.cc index c18ccf6..b513778 100644 --- a/tensorflow/core/graph/graph_constructor_test.cc +++ b/tensorflow/core/graph/graph_constructor_test.cc @@ -3160,5 +3160,20 @@ TEST_F(GraphConstructorTest, ImportGraphDef_ValidateColationConstraints) { TF_EXPECT_OK(ImportGraphDef(options, def, &graph_, nullptr)); } +TEST_F(GraphConstructorTest, ImportGraphDef_UnknownOps) { + const string pb_ascii = "node { name: 'op_from_contrib' op: 'OpFromContrib'}"; + // Try load twice to check for two parts of the error message. We cannot check + // for the whole thing in one go because the message includes the hostname. + ExpectError(pb_ascii, {"Op type not registered 'OpFromContrib'"}); + ExpectError( + pb_ascii, + {"Make sure the Op and Kernel are registered in the " + "binary running in this process. Note that if you " + "are loading a saved graph which used ops from " + "tf.contrib, accessing (e.g.) `tf.contrib.resampler` should be done" + "before importing the graph, as contrib ops are lazily registered " + "when the module is first accessed."}); +} + } // namespace } // namespace tensorflow -- 2.7.4