aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Malcolm Reynolds <mareynolds@google.com>2018-04-26 16:24:51 -0700
committerGravatar TensorFlower Gardener <gardener@tensorflow.org>2018-04-26 16:27:33 -0700
commit7d3e3fd76a002cd1dd78cb7f11bab760fb5abecb (patch)
tree8e19d80440a1f57d25aefd3fafd57fb5356d68d9
parentbcefec3d6782365510c45e08763892d478dabb07 (diff)
More informative error message when loading a graph_def which uses unknown ops.
Fixes #17014 PiperOrigin-RevId: 194472083
-rw-r--r--tensorflow/core/framework/op.cc27
-rw-r--r--tensorflow/core/graph/graph_constructor_test.cc15
2 files changed, 33 insertions, 9 deletions
diff --git a/tensorflow/core/framework/op.cc b/tensorflow/core/framework/op.cc
index 5f68c59fe9..0873d4e47b 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 c18ccf6ce4..b513778de9 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