aboutsummaryrefslogtreecommitdiffhomepage
path: root/tensorflow/python/framework
diff options
context:
space:
mode:
authorGravatar A. Unique TensorFlower <gardener@tensorflow.org>2018-08-31 14:35:47 -0700
committerGravatar TensorFlower Gardener <gardener@tensorflow.org>2018-08-31 14:56:33 -0700
commite082d5208e56d3d8f69544781bebf830eae82de7 (patch)
tree8bdf5a08ebb7fa41a16c00c7f6b5921d9bc54555 /tensorflow/python/framework
parent8341a69d25a6f09b57e866e802efd2eb7d588c78 (diff)
Currently there are two formats for error reporting inside TensorFlow. This is first of a series of CL to merge these into one. In this change, we remove the format tag from the errors.
PiperOrigin-RevId: 211146036
Diffstat (limited to 'tensorflow/python/framework')
-rw-r--r--tensorflow/python/framework/error_interpolation.py81
-rw-r--r--tensorflow/python/framework/error_interpolation_test.py111
2 files changed, 85 insertions, 107 deletions
diff --git a/tensorflow/python/framework/error_interpolation.py b/tensorflow/python/framework/error_interpolation.py
index 6e844e14b9..a69018d00d 100644
--- a/tensorflow/python/framework/error_interpolation.py
+++ b/tensorflow/python/framework/error_interpolation.py
@@ -26,21 +26,17 @@ import collections
import itertools
import os
import re
-import string
import six
from tensorflow.python.util import tf_stack
-
_NAME_REGEX = r"[A-Za-z0-9.][A-Za-z0-9_.\-/]*?"
-_FORMAT_REGEX = r"[A-Za-z0-9_.\-/${}:]+"
-_TAG_REGEX = r"\^\^({name}):({name}):({fmt})\^\^".format(
- name=_NAME_REGEX, fmt=_FORMAT_REGEX)
+_TAG_REGEX = r"\^\^({name}):({name})\^\^".format(name=_NAME_REGEX)
_INTERPOLATION_REGEX = r"^(.*?)({tag})".format(tag=_TAG_REGEX)
_INTERPOLATION_PATTERN = re.compile(_INTERPOLATION_REGEX)
-_ParseTag = collections.namedtuple("_ParseTag", ["type", "name", "format"])
+_ParseTag = collections.namedtuple("_ParseTag", ["type", "name"])
_BAD_FILE_SUBSTRINGS = [
os.path.join("tensorflow", "python"),
@@ -52,16 +48,9 @@ def _parse_message(message):
"""Parses the message.
Splits the message into separators and tags. Tags are named tuples
- representing the string ^^type:name:format^^ and they are separated by
- separators. For example, in
- "123^^node:Foo:${file}^^456^^node:Bar:${line}^^789", there are two tags and
- three separators. The separators are the numeric characters.
-
- Supported tags after node:<node_name>
- file: Replaced with the filename in which the node was defined.
- line: Replaced by the line number at which the node was defined.
- colocations: Replaced by a multi-line message describing the file and
- line numbers at which this node was colocated with other nodes.
+ representing the string ^^type:name^^ and they are separated by
+ separators. For example, in "123^^node:Foo^^456^^node:Bar^^789", there are
+ two tags and three separators. The separators are the numeric characters.
Args:
message: String to parse
@@ -69,8 +58,8 @@ def _parse_message(message):
Returns:
(list of separator strings, list of _ParseTags).
- For example, if message is "123^^node:Foo:${file}^^456" then this function
- returns (["123", "456"], [_ParseTag("node", "Foo", "${file}")])
+ For example, if message is "123^^node:Foo^^456" then this function
+ returns (["123", "456"], [_ParseTag("node", "Foo")])
"""
seps = []
tags = []
@@ -79,7 +68,7 @@ def _parse_message(message):
match = re.match(_INTERPOLATION_PATTERN, message[pos:])
if match:
seps.append(match.group(1))
- tags.append(_ParseTag(match.group(3), match.group(4), match.group(5)))
+ tags.append(_ParseTag(match.group(3), match.group(4)))
pos += match.end()
else:
break
@@ -111,12 +100,12 @@ def _compute_device_summary_from_list(name, device_assignment_list, prefix=""):
return prefix + message
str_list = []
- str_list.append("%sDevice assignments active during op '%s' creation:"
- % (prefix, name))
+ str_list.append(
+ "%sDevice assignments active during op '%s' creation:" % (prefix, name))
for traceable_obj in device_assignment_list:
- location_summary = "<{file}:{line}>".format(file=traceable_obj.filename,
- line=traceable_obj.lineno)
+ location_summary = "<{file}:{line}>".format(
+ file=traceable_obj.filename, line=traceable_obj.lineno)
subs = {
"prefix": prefix,
"indent": " ",
@@ -160,12 +149,12 @@ def _compute_colocation_summary_from_dict(name, colocation_dict, prefix=""):
return prefix + message
str_list = []
- str_list.append("%sNode-device colocations active during op '%s' creation:"
- % (prefix, name))
+ str_list.append("%sNode-device colocations active during op '%s' creation:" %
+ (prefix, name))
for coloc_name, location in colocation_dict.items():
- location_summary = "<{file}:{line}>".format(file=location.filename,
- line=location.lineno)
+ location_summary = "<{file}:{line}>".format(
+ file=location.filename, line=location.lineno)
subs = {
"prefix": prefix,
"indent": " ",
@@ -180,8 +169,10 @@ def _compute_colocation_summary_from_dict(name, colocation_dict, prefix=""):
def _compute_colocation_summary_from_op(op, prefix=""):
"""Fetch colocation file, line, and nesting and return a summary string."""
- return _compute_colocation_summary_from_dict(
- op.name, op._colocation_dict, prefix) # pylint: disable=protected-access
+ # pylint: disable=protected-access
+ return _compute_colocation_summary_from_dict(op.name, op._colocation_dict,
+ prefix)
+ # pylint: enable=protected-access
def _find_index_of_defining_frame_for_op(op):
@@ -276,7 +267,7 @@ def compute_field_dict(op):
def interpolate(error_message, graph):
"""Interpolates an error message.
- The error message can contain tags of the form ^^type:name:format^^ which will
+ The error message can contain tags of the form ^^type:name^^ which will
be replaced.
Args:
@@ -285,29 +276,29 @@ def interpolate(error_message, graph):
message.
Returns:
- The string with tags of the form ^^type:name:format^^ interpolated.
+ The string with tags of the form ^^type:name^^ interpolated.
"""
seps, tags = _parse_message(error_message)
+ subs = []
+ end_msg = ""
- node_name_to_substitution_dict = {}
- for name in [t.name for t in tags]:
- if name in node_name_to_substitution_dict:
- continue
+ for t in tags:
try:
- op = graph.get_operation_by_name(name)
+ op = graph.get_operation_by_name(t.name)
except KeyError:
op = None
+ msg = "^^%s:%s^^" % (t.type, t.name)
if op is not None:
field_dict = compute_field_dict(op)
- else:
- msg = "<NA>"
- field_dict = collections.defaultdict(lambda s=msg: s)
- node_name_to_substitution_dict[name] = field_dict
-
- subs = [
- string.Template(tag.format).safe_substitute(
- node_name_to_substitution_dict[tag.name]) for tag in tags
- ]
+ if t.type == "node":
+ msg = "node %s%s " % (t.name, field_dict["defined_at"])
+ elif t.type == "colocation_node":
+ msg = "node %s%s having device %s " % (t.name, field_dict["defined_at"],
+ field_dict["devices"])
+ end_msg += "\n\n" + field_dict["devs_and_colocs"]
+ subs.append(msg)
+ subs.append(end_msg)
+
return "".join(
itertools.chain(*six.moves.zip_longest(seps, subs, fillvalue="")))
diff --git a/tensorflow/python/framework/error_interpolation_test.py b/tensorflow/python/framework/error_interpolation_test.py
index 0427156b2b..a7c7bbf28b 100644
--- a/tensorflow/python/framework/error_interpolation_test.py
+++ b/tensorflow/python/framework/error_interpolation_test.py
@@ -50,9 +50,9 @@ def _modify_op_stack_with_filenames(op, num_user_frames, user_filename,
stack = []
for idx in range(0, num_outer_frames):
stack.append(op._traceback[idx])
- for idx in range(len(stack), len(stack)+num_user_frames):
+ for idx in range(len(stack), len(stack) + num_user_frames):
stack.append(_make_frame_with_filename(op, idx, user_filename % idx))
- for idx in range(len(stack), len(stack)+num_inner_tf_frames):
+ for idx in range(len(stack), len(stack) + num_inner_tf_frames):
stack.append(_make_frame_with_filename(op, idx, tf_filename % idx))
op._traceback = stack
@@ -62,13 +62,11 @@ class ComputeDeviceSummaryFromOpTest(test.TestCase):
def testCorrectFormatWithActiveDeviceAssignments(self):
assignments = []
assignments.append(
- traceable_stack.TraceableObject("/cpu:0",
- filename="hope.py",
- lineno=24))
+ traceable_stack.TraceableObject(
+ "/cpu:0", filename="hope.py", lineno=24))
assignments.append(
- traceable_stack.TraceableObject("/gpu:2",
- filename="please.py",
- lineno=42))
+ traceable_stack.TraceableObject(
+ "/gpu:2", filename="please.py", lineno=42))
summary = error_interpolation._compute_device_summary_from_list(
"nodename", assignments, prefix=" ")
@@ -90,12 +88,10 @@ class ComputeDeviceSummaryFromOpTest(test.TestCase):
class ComputeColocationSummaryFromOpTest(test.TestCase):
def testCorrectFormatWithActiveColocations(self):
- t_obj_1 = traceable_stack.TraceableObject(None,
- filename="test_1.py",
- lineno=27)
- t_obj_2 = traceable_stack.TraceableObject(None,
- filename="test_2.py",
- lineno=38)
+ t_obj_1 = traceable_stack.TraceableObject(
+ None, filename="test_1.py", lineno=27)
+ t_obj_2 = traceable_stack.TraceableObject(
+ None, filename="test_2.py", lineno=38)
colocation_dict = {
"test_node_1": t_obj_1,
"test_node_2": t_obj_2,
@@ -140,10 +136,11 @@ class InterpolateFilenamesAndLineNumbersTest(test.TestCase):
def testFindIndexOfDefiningFrameForOp(self):
local_op = constant_op.constant(42).op
user_filename = "hope.py"
- _modify_op_stack_with_filenames(local_op,
- num_user_frames=3,
- user_filename=user_filename,
- num_inner_tf_frames=5)
+ _modify_op_stack_with_filenames(
+ local_op,
+ num_user_frames=3,
+ user_filename=user_filename,
+ num_inner_tf_frames=5)
idx = error_interpolation._find_index_of_defining_frame_for_op(local_op)
# Expected frame is 6th from the end because there are 5 inner frames witih
# TF filenames.
@@ -155,44 +152,39 @@ class InterpolateFilenamesAndLineNumbersTest(test.TestCase):
# Truncate stack to known length.
local_op._traceback = local_op._traceback[:7]
# Ensure all frames look like TF frames.
- _modify_op_stack_with_filenames(local_op,
- num_user_frames=0,
- user_filename="user_file.py",
- num_inner_tf_frames=7)
+ _modify_op_stack_with_filenames(
+ local_op,
+ num_user_frames=0,
+ user_filename="user_file.py",
+ num_inner_tf_frames=7)
idx = error_interpolation._find_index_of_defining_frame_for_op(local_op)
self.assertEqual(0, idx)
def testNothingToDo(self):
normal_string = "This is just a normal string"
- interpolated_string = error_interpolation.interpolate(normal_string,
- self.graph)
+ interpolated_string = error_interpolation.interpolate(
+ normal_string, self.graph)
self.assertEqual(interpolated_string, normal_string)
- def testOneTag(self):
- one_tag_string = "^^node:Two:${file}^^"
- interpolated_string = error_interpolation.interpolate(one_tag_string,
- self.graph)
- self.assertTrue(interpolated_string.endswith("constant_op.py"),
- "interpolated_string '%s' did not end with constant_op.py"
- % interpolated_string)
-
def testOneTagWithAFakeNameResultsInPlaceholders(self):
- one_tag_string = "^^node:MinusOne:${file}^^"
- interpolated_string = error_interpolation.interpolate(one_tag_string,
- self.graph)
- self.assertEqual("<NA>", interpolated_string)
+ one_tag_string = "^^node:MinusOne^^"
+ interpolated_string = error_interpolation.interpolate(
+ one_tag_string, self.graph)
+ self.assertEqual(one_tag_string, interpolated_string)
def testTwoTagsNoSeps(self):
- two_tags_no_seps = "^^node:One:${file}^^^^node:Three:${line}^^"
- interpolated_string = error_interpolation.interpolate(two_tags_no_seps,
- self.graph)
- self.assertRegexpMatches(interpolated_string, "constant_op.py[0-9]+")
+ two_tags_no_seps = "^^node:One^^^^node:Three^^"
+ interpolated_string = error_interpolation.interpolate(
+ two_tags_no_seps, self.graph)
+ self.assertRegexpMatches(interpolated_string,
+ "constant_op.py:[0-9]+.*constant_op.py:[0-9]+")
def testTwoTagsWithSeps(self):
- two_tags_with_seps = ";;;^^node:Two:${file}^^,,,^^node:Three:${line}^^;;;"
- interpolated_string = error_interpolation.interpolate(two_tags_with_seps,
- self.graph)
- expected_regex = "^;;;.*constant_op.py,,,[0-9]*;;;$"
+ two_tags_with_seps = ";;;^^node:Two^^,,,^^node:Three^^;;;"
+ interpolated_string = error_interpolation.interpolate(
+ two_tags_with_seps, self.graph)
+ expected_regex = (
+ r"^;;;.*constant_op.py:[0-9]+\) ,,,.*constant_op.py:[0-9]*\) ;;;$")
self.assertRegexpMatches(interpolated_string, expected_regex)
@@ -214,30 +206,26 @@ class InterpolateDeviceSummaryTest(test.TestCase):
self.graph = self.three.graph
def testNodeZeroHasNoDeviceSummaryInfo(self):
- message = "^^node:zero:${devices}^^"
+ message = "^^colocation_node:zero^^"
result = error_interpolation.interpolate(message, self.graph)
self.assertIn("No device assignments were active", result)
def testNodeOneHasExactlyOneInterpolatedDevice(self):
- message = "^^node:one:${devices}^^"
+ message = "^^colocation_node:one^^"
result = error_interpolation.interpolate(message, self.graph)
- num_devices = result.count("tf.device")
- self.assertEqual(1, num_devices)
- self.assertIn("tf.device(/cpu)", result)
+ self.assertEqual(2, result.count("tf.device(/cpu)"))
def testNodeTwoHasTwoInterpolatedDevice(self):
- message = "^^node:two:${devices}^^"
+ message = "^^colocation_node:two^^"
result = error_interpolation.interpolate(message, self.graph)
- num_devices = result.count("tf.device")
- self.assertEqual(2, num_devices)
- self.assertIn("tf.device(/cpu)", result)
- self.assertIn("tf.device(/cpu:0)", result)
+ self.assertEqual(2, result.count("tf.device(/cpu)"))
+ self.assertEqual(2, result.count("tf.device(/cpu:0)"))
def testNodeThreeHasFancyFunctionDisplayNameForInterpolatedDevice(self):
- message = "^^node:three:${devices}^^"
+ message = "^^colocation_node:three^^"
result = error_interpolation.interpolate(message, self.graph)
num_devices = result.count("tf.device")
- self.assertEqual(1, num_devices)
+ self.assertEqual(2, num_devices)
name_re = r"_fancy_device_function<.*error_interpolation_test.py, [0-9]+>"
expected_re = r"with tf.device\(.*%s\)" % name_re
self.assertRegexpMatches(result, expected_re)
@@ -268,27 +256,26 @@ class InterpolateColocationSummaryTest(test.TestCase):
self.graph = node_three.graph
def testNodeThreeHasColocationInterpolation(self):
- message = "^^node:Three_with_one:${colocations}^^"
+ message = "^^colocation_node:Three_with_one^^"
result = error_interpolation.interpolate(message, self.graph)
self.assertIn("colocate_with(One)", result)
def testNodeFourHasColocationInterpolationForNodeThreeOnly(self):
- message = "^^node:Four_with_three:${colocations}^^"
+ message = "^^colocation_node:Four_with_three^^"
result = error_interpolation.interpolate(message, self.graph)
self.assertIn("colocate_with(Three_with_one)", result)
self.assertNotIn(
"One", result,
- "Node One should not appear in Four_with_three's summary:\n%s"
- % result)
+ "Node One should not appear in Four_with_three's summary:\n%s" % result)
def testNodeFiveHasColocationInterpolationForNodeOneAndTwo(self):
- message = "^^node:Five_with_one_with_two:${colocations}^^"
+ message = "^^colocation_node:Five_with_one_with_two^^"
result = error_interpolation.interpolate(message, self.graph)
self.assertIn("colocate_with(One)", result)
self.assertIn("colocate_with(Two)", result)
def testColocationInterpolationForNodeLackingColocation(self):
- message = "^^node:One:${colocations}^^"
+ message = "^^colocation_node:One^^"
result = error_interpolation.interpolate(message, self.graph)
self.assertIn("No node-device colocations", result)
self.assertNotIn("Two", result)