More informative error message when loading a graph_def which uses unknown ops.
authorMalcolm Reynolds <mareynolds@google.com>
Thu, 26 Apr 2018 23:24:51 +0000 (16:24 -0700)
committerTensorFlower Gardener <gardener@tensorflow.org>
Thu, 26 Apr 2018 23:27:33 +0000 (16:27 -0700)
Fixes #17014

PiperOrigin-RevId: 194472083

tensorflow/core/framework/op.cc
tensorflow/core/graph/graph_constructor_test.cc

index 5f68c59..0873d4e 100644 (file)
@@ -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();
index c18ccf6..b513778 100644 (file)
@@ -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