diff --git a/tensorflow/core/framework/op_kernel.cc b/tensorflow/core/framework/op_kernel.cc index 4df0ffeda7ef12fb9dee8cca093195d8b065313d..66a281e29ffc38ad440688be8748e568a3889af7 100644 --- a/tensorflow/core/framework/op_kernel.cc +++ b/tensorflow/core/framework/op_kernel.cc @@ -708,8 +708,10 @@ Status AttrsMatch(const NodeDef& node_def, const KernelDef& kernel_def, } Status FindKernelRegistration(DeviceType device_type, const NodeDef& node_def, - const KernelRegistration** reg) { + const KernelRegistration** reg, + bool* was_attr_mismatch) { *reg = nullptr; + *was_attr_mismatch = false; string label; // Label defaults to empty if not found in NodeDef. GetNodeAttr(node_def, "_kernel", &label); const string key = Key(node_def.op(), device_type, label); @@ -728,6 +730,8 @@ Status FindKernelRegistration(DeviceType device_type, const NodeDef& node_def, ProtoShortDebugString(iter->second.def), "'"); } *reg = &iter->second; + } else { + *was_attr_mismatch = true; } } return Status::OK(); @@ -738,12 +742,19 @@ Status FindKernelRegistration(DeviceType device_type, const NodeDef& node_def, Status FindKernelDef(DeviceType device_type, const NodeDef& node_def, const KernelDef** def, string* kernel_class_name) { const KernelRegistration* reg = nullptr; - TF_RETURN_IF_ERROR(FindKernelRegistration(device_type, node_def, ®)); + bool was_attr_mismatch; + TF_RETURN_IF_ERROR( + FindKernelRegistration(device_type, node_def, ®, &was_attr_mismatch)); if (reg == nullptr) { - return errors::NotFound("No registered '", node_def.op(), "' OpKernel for ", - DeviceTypeString(device_type), - " devices compatible with node ", - SummarizeNodeDef(node_def)); + Status s = errors::NotFound( + "No registered '", node_def.op(), "' OpKernel for ", + DeviceTypeString(device_type), " devices compatible with node ", + SummarizeNodeDef(node_def)); + if (was_attr_mismatch) { + errors::AppendToMessage( + &s, " (OpKernel was found, but attributes didn't match)"); + } + return s; } if (def != nullptr) *def = ®->def; if (kernel_class_name != nullptr) *kernel_class_name = reg->kernel_class_name; @@ -762,7 +773,9 @@ Status SupportedDeviceTypesForNode( if (s.ok()) { for (const DeviceType& device_type : prioritized_types) { const KernelRegistration* reg = nullptr; - TF_RETURN_IF_ERROR(FindKernelRegistration(device_type, def, ®)); + bool was_attr_mismatch; + TF_RETURN_IF_ERROR( + FindKernelRegistration(device_type, def, ®, &was_attr_mismatch)); if (reg != nullptr) device_types->push_back(device_type); } } else { @@ -800,7 +813,9 @@ Status CreateOpKernel(DeviceType device_type, DeviceBase* device, // Look up kernel registration. const KernelRegistration* registration; - s = FindKernelRegistration(device_type, node_def, ®istration); + bool was_attr_mismatch; + s = FindKernelRegistration(device_type, node_def, ®istration, + &was_attr_mismatch); if (!s.ok()) { errors::AppendToMessage(&s, " when instantiating ", node_def.op()); return s; @@ -810,6 +825,10 @@ Status CreateOpKernel(DeviceType device_type, DeviceBase* device, "' OpKernel for ", DeviceTypeString(device_type), " devices compatible with node ", SummarizeNodeDef(node_def))); + if (was_attr_mismatch) { + errors::AppendToMessage( + &s, " (OpKernel was found, but attributes didn't match)"); + } return s; }