Improve error message when no kernel found

This error occurs when an Op node does not have a registered kernel that supports the requested attributes. This improves the error message to:

* Add rich formatting that allows the Python layer to fill in where the node was created
* Specify the (implicitly) requested attributes, so the user can more easily see why none of the the listed kernels are suitable

PiperOrigin-RevId: 219694648
This commit is contained in:
James Keeling 2018-11-01 14:04:46 -07:00 committed by TensorFlower Gardener
parent 10d3dc6d8b
commit f0dbcffb0e
3 changed files with 27 additions and 11 deletions
tensorflow
core/common_runtime
python/saved_model

View File

@ -21,6 +21,7 @@ limitations under the License.
#include <vector>
#include "tensorflow/core/common_runtime/device.h"
#include "tensorflow/core/framework/attr_value_util.h"
#include "tensorflow/core/framework/device_attributes.pb.h"
#include "tensorflow/core/framework/graph.pb.h"
#include "tensorflow/core/framework/node_def_util.h"
@ -30,6 +31,7 @@ limitations under the License.
#include "tensorflow/core/lib/core/errors.h"
#include "tensorflow/core/lib/core/stringpiece.h"
#include "tensorflow/core/lib/strings/str_util.h"
#include "tensorflow/core/lib/strings/strcat.h"
namespace tensorflow {
@ -575,11 +577,21 @@ class ColocationGraph {
for (Device* d : device_set_->devices()) {
registered_device_types.insert(d->device_type());
}
std::vector<string> attr_key_vals;
for (const auto& it : node.attrs()) {
const string& name = it.first;
const AttrValue& attr_value = it.second;
attr_key_vals.push_back(
strings::StrCat(name, "=", SummarizeAttrValue(attr_value)));
}
return errors::InvalidArgument(
"No OpKernel was registered to support Op '", node.type_string(),
"' with these attrs. Registered devices: [",
str_util::Join(registered_device_types, ","),
"], Registered kernels:\n",
"' used by ", errors::FormatNodeNameForError(node.name()),
"with these attrs: [", str_util::Join(attr_key_vals, ", "),
"]\n"
"Registered devices: [",
str_util::Join(registered_device_types, ", "), "]\n",
"Registered kernels:\n",
KernelsRegisteredForOp(node.type_string()));
}

View File

@ -1028,9 +1028,10 @@ TEST_F(PlacerTest, TestNoKernelsRegistered) {
Status s = Place(&g);
EXPECT_EQ(error::INVALID_ARGUMENT, s.code());
EXPECT_TRUE(str_util::StrContains(
s.error_message(),
"No OpKernel was registered to support Op 'VariableNoKernels'"));
EXPECT_TRUE(
str_util::StrContains(s.error_message(),
"No OpKernel was registered to support Op "
"'VariableNoKernels' used by {{node var}}"));
EXPECT_TRUE(
str_util::StrContains(s.error_message(), "<no registered kernels>"));
}
@ -1052,9 +1053,9 @@ TEST_F(PlacerTest, TestNoDevicesRegistered) {
Status s = Place(&g, &cpu_only);
EXPECT_EQ(error::INVALID_ARGUMENT, s.code());
EXPECT_TRUE(str_util::StrContains(
s.error_message(),
"No OpKernel was registered to support Op 'VariableGPU'"));
EXPECT_TRUE(str_util::StrContains(s.error_message(),
"No OpKernel was registered to support Op "
"'VariableGPU' used by {{node var}}"));
EXPECT_TRUE(str_util::StrContains(s.error_message(), "device='FakeGPU'"));
}

View File

@ -1420,8 +1420,11 @@ class SavedModelTest(test.TestCase):
sess = session.Session(graph=ops.Graph())
with self.assertRaisesRegexp(
errors.InvalidArgumentError,
".*No OpKernel was registered to support Op \'TestAttr\' with these "
"attrs..*"):
"No OpKernel was registered to support Op 'TestAttr' used by node "
"test_attr \\(defined at .*\\) with these attrs: \\[.*\\]\n"
"Registered devices:.*\n"
"Registered kernels:.*"
):
loader.load(sess, ["foo"], export_dir)