def testLocateTensorElement2DNoEllipsis(self): a = np.linspace(0.0, 1.0 - 1.0 / 16.0, 16).reshape([4, 4]) out = tensor_format.format_tensor(a, "a") self.assertEqual([ "Tensor \"a\":", "", "array([[ 0. , 0.0625, 0.125 , 0.1875],", " [ 0.25 , 0.3125, 0.375 , 0.4375],", " [ 0.5 , 0.5625, 0.625 , 0.6875],", " [ 0.75 , 0.8125, 0.875 , 0.9375]])", ], out.lines) is_omitted, row, start_col, end_col = tensor_format.locate_tensor_element( out, [0, 0]) self.assertFalse(is_omitted) self.assertEqual(2, row) self.assertEqual(9, start_col) self.assertEqual(11, end_col) is_omitted, row, start_col, end_col = tensor_format.locate_tensor_element( out, [0, 3]) self.assertFalse(is_omitted) self.assertEqual(2, row) self.assertEqual(36, start_col) self.assertEqual(42, end_col) is_omitted, row, start_col, end_col = tensor_format.locate_tensor_element( out, [1, 0]) self.assertFalse(is_omitted) self.assertEqual(3, row) self.assertEqual(9, start_col) self.assertEqual(13, end_col) is_omitted, row, start_col, end_col = tensor_format.locate_tensor_element( out, [1, 3]) self.assertFalse(is_omitted) self.assertEqual(3, row) self.assertEqual(36, start_col) self.assertEqual(42, end_col) is_omitted, row, start_col, end_col = tensor_format.locate_tensor_element( out, [3, 3]) self.assertFalse(is_omitted) self.assertEqual(5, row) self.assertEqual(36, start_col) self.assertEqual(42, end_col) with self.assertRaisesRegexp( ValueError, "Indices exceed tensor dimensions"): tensor_format.locate_tensor_element(out, [1, 4]) with self.assertRaisesRegexp( ValueError, "Indices contain negative"): tensor_format.locate_tensor_element(out, [-1, 2]) with self.assertRaisesRegexp( ValueError, "Dimensions mismatch"): tensor_format.locate_tensor_element(out, [0])
def testBatchModeWithErrors(self): a = np.zeros(20) out = tensor_format.format_tensor( a, "a", np_printoptions={"linewidth": 40}) self.assertEqual([ "Tensor \"a\":", "", "array([ 0., 0., 0., 0., 0., 0.,", " 0., 0., 0., 0., 0., 0.,", " 0., 0., 0., 0., 0., 0.,", " 0., 0.])", ], out.lines) with self.assertRaisesRegexp(ValueError, "Dimensions mismatch"): tensor_format.locate_tensor_element(out, [[0, 0], [0]]) with self.assertRaisesRegexp(ValueError, "Indices exceed tensor dimensions"): tensor_format.locate_tensor_element(out, [[0], [20]]) with self.assertRaisesRegexp(ValueError, r"Indices contain negative value\(s\)"): tensor_format.locate_tensor_element(out, [[0], [-1]]) with self.assertRaisesRegexp( ValueError, "Input indices sets are not in ascending order"): tensor_format.locate_tensor_element(out, [[5], [0]])
def testFormatTensor3DNoEllipsisWithArgwhereHighlightWithMatches(self): a = np.linspace(0.0, 1.0 - 1.0 / 24.0, 24).reshape([2, 3, 4]) lower_bound = 0.26 upper_bound = 0.5 def highlight_filter(x): return np.logical_and(x > lower_bound, x < upper_bound) highlight_options = tensor_format.HighlightOptions( highlight_filter, description="between 0.26 and 0.5") out = tensor_format.format_tensor( a, "a", highlight_options=highlight_options) cli_test_utils.assert_lines_equal_ignoring_whitespace( self, ["Tensor \"a\": " "Highlighted(between 0.26 and 0.5): 5 of 24 element(s) (20.83%)", ""], out.lines[:2]) self.assertEqual(repr(a).split("\n"), out.lines[2:]) self._checkTensorMetadata(a, out.annotations) # Check annotations for beginning indices of the lines. self._checkBeginIndicesAnnotations(out, a) self.assertAllClose( [0.29166667, 0.33333333, 0.375, 0.41666667, 0.45833333], self._extractBoldNumbers(out, 2))
def testBatchModeWithErrors(self): a = np.zeros(20) out = tensor_format.format_tensor(a, "a", np_printoptions={"linewidth": 40}) cli_test_utils.assert_lines_equal_ignoring_whitespace( self, ["Tensor \"a\":", ""], out.lines[:2]) self.assertEqual(repr(a).split("\n"), out.lines[2:]) with self.assertRaisesRegex(ValueError, "Dimensions mismatch"): tensor_format.locate_tensor_element(out, [[0, 0], [0]]) with self.assertRaisesRegex(ValueError, "Indices exceed tensor dimensions"): tensor_format.locate_tensor_element(out, [[0], [20]]) with self.assertRaisesRegex(ValueError, r"Indices contain negative value\(s\)"): tensor_format.locate_tensor_element(out, [[0], [-1]]) with self.assertRaisesRegex( ValueError, "Input indices sets are not in ascending order"): tensor_format.locate_tensor_element(out, [[5], [0]])
def testLocateTensorElement2DNoEllipsisWithNumericSummary(self): a = np.linspace(0.0, 1.0 - 1.0 / 16.0, 16).reshape([4, 4]) out = tensor_format.format_tensor(a, "a", include_numeric_summary=True) cli_test_utils.assert_lines_equal_ignoring_whitespace( self, ["Tensor \"a\":", "", "Numeric summary:", "| 0 + | total |", "| 1 15 | 16 |", "| min max mean std |"], out.lines[:6]) cli_test_utils.assert_array_lines_close( self, [0.0, 0.9375, 0.46875, 0.28811076429], out.lines[6:7]) cli_test_utils.assert_array_lines_close(self, a, out.lines[8:]) self._checkTensorElementLocations(out, a) with self.assertRaisesRegexp( ValueError, "Indices exceed tensor dimensions"): tensor_format.locate_tensor_element(out, [1, 4]) with self.assertRaisesRegexp( ValueError, "Indices contain negative"): tensor_format.locate_tensor_element(out, [-1, 2]) with self.assertRaisesRegexp( ValueError, "Dimensions mismatch"): tensor_format.locate_tensor_element(out, [0])
def testFormatTensor3DNoEllipsisWithArgwhereHighlightWithMatches(self): a = np.linspace(0.0, 1.0 - 1.0 / 24.0, 24).reshape([2, 3, 4]) lower_bound = 0.26 upper_bound = 0.5 def highlight_filter(x): return np.logical_and(x > lower_bound, x < upper_bound) highlight_options = tensor_format.HighlightOptions( highlight_filter, description="between 0.26 and 0.5") out = tensor_format.format_tensor(a, "a", highlight_options=highlight_options) cli_test_utils.assert_lines_equal_ignoring_whitespace( self, [ "Tensor \"a\": " "Highlighted(between 0.26 and 0.5): 5 of 24 element(s) (20.83%)", "" ], out.lines[:2]) self.assertEqual(repr(a).split("\n"), out.lines[2:]) self._checkTensorMetadata(a, out.annotations) # Check annotations for beginning indices of the lines. self._checkBeginIndicesAnnotations(out, a) self.assertAllClose( [0.29166667, 0.33333333, 0.375, 0.41666667, 0.45833333], self._extractBoldNumbers(out, 2))
def testLocateTensorElement2DNoEllipsisWithNumericSummary(self): a = np.linspace(0.0, 1.0 - 1.0 / 16.0, 16).reshape([4, 4]) out = tensor_format.format_tensor(a, "a", include_numeric_summary=True) cli_test_utils.assert_lines_equal_ignoring_whitespace( self, [ "Tensor \"a\":", "", "Numeric summary:", "| 0 + | total |", "| 1 15 | 16 |", "| min max mean std |" ], out.lines[:6]) cli_test_utils.assert_array_lines_close( self, [0.0, 0.9375, 0.46875, 0.28811076429], out.lines[6:7]) cli_test_utils.assert_array_lines_close(self, a, out.lines[8:]) self._checkTensorElementLocations(out, a) with self.assertRaisesRegex(ValueError, "Indices exceed tensor dimensions"): tensor_format.locate_tensor_element(out, [1, 4]) with self.assertRaisesRegex(ValueError, "Indices contain negative"): tensor_format.locate_tensor_element(out, [-1, 2]) with self.assertRaisesRegex(ValueError, "Dimensions mismatch"): tensor_format.locate_tensor_element(out, [0])
def testFormatTensor2DNoEllipsisWithRowBreak(self): a = np.linspace(0.0, 1.0 - 1.0 / 40.0, 40).reshape([2, 20]) out = tensor_format.format_tensor( a, "a", np_printoptions={"linewidth": 50}) self.assertEqual( {"dtype": a.dtype, "shape": a.shape}, out.annotations["tensor_metadata"]) self.assertEqual([ "Tensor \"a\":", "", "array([[ 0. , 0.025, 0.05 , 0.075, 0.1 ,", " 0.125, 0.15 , 0.175, 0.2 , 0.225,", " 0.25 , 0.275, 0.3 , 0.325, 0.35 ,", " 0.375, 0.4 , 0.425, 0.45 , 0.475],", " [ 0.5 , 0.525, 0.55 , 0.575, 0.6 ,", " 0.625, 0.65 , 0.675, 0.7 , 0.725,", " 0.75 , 0.775, 0.8 , 0.825, 0.85 ,", " 0.875, 0.9 , 0.925, 0.95 , 0.975]])", ], out.lines) self._checkTensorMetadata(a, out.annotations) # Check annotations for the beginning indices of the lines. self._checkBeginIndices([0, 0], out.annotations[2]) self._checkBeginIndices([0, 5], out.annotations[3]) self._checkBeginIndices([0, 10], out.annotations[4]) self._checkBeginIndices([0, 15], out.annotations[5]) self._checkBeginIndices([1, 0], out.annotations[6]) self._checkBeginIndices([1, 5], out.annotations[7]) self._checkBeginIndices([1, 10], out.annotations[8]) self._checkBeginIndices([1, 15], out.annotations[9])
def testFormatTensor3DNoEllipsis(self): # TODO(cais): Test name. a = np.linspace(0.0, 1.0 - 1.0 / 24.0, 24).reshape([2, 3, 4]) out = tensor_format.format_tensor(a, "a") self.assertEqual([ "Tensor \"a\":", "", "array([[[ 0. , 0.04166667, 0.08333333, 0.125 ],", " [ 0.16666667, 0.20833333, 0.25 , 0.29166667],", " [ 0.33333333, 0.375 , 0.41666667, 0.45833333]],", "", " [[ 0.5 , 0.54166667, 0.58333333, 0.625 ],", " [ 0.66666667, 0.70833333, 0.75 , 0.79166667],", " [ 0.83333333, 0.875 , 0.91666667, 0.95833333]]])", ], out.lines) self._checkTensorMetadata(a, out.annotations) # Check annotations for beginning indices of the lines. self._checkBeginIndices([0, 0, 0], out.annotations[2]) self._checkBeginIndices([0, 1, 0], out.annotations[3]) self._checkBeginIndices([0, 2, 0], out.annotations[4]) self.assertNotIn(5, out.annotations) self._checkBeginIndices([1, 0, 0], out.annotations[6]) self._checkBeginIndices([1, 1, 0], out.annotations[7]) self._checkBeginIndices([1, 2, 0], out.annotations[8])
def testFormatTensorWithEllipses(self): a = (np.arange(11 * 11 * 11) + 1000).reshape([11, 11, 11]).astype(np.int32) out = tensor_format.format_tensor( a, "a", False, np_printoptions={"threshold": 100, "edgeitems": 2}) cli_test_utils.assert_lines_equal_ignoring_whitespace( self, ["Tensor \"a\":", ""], out.lines[:2]) self.assertEqual(repr(a).split("\n"), out.lines[2:]) self._checkTensorMetadata(a, out.annotations) # Check annotations for beginning indices of the lines. actual_row_0_0_0, _ = self._findFirst(out.lines, "1000") self.assertEqual({tensor_format.BEGIN_INDICES_KEY: [0, 0, 0]}, out.annotations[actual_row_0_0_0]) actual_row_0_1_0, _ = self._findFirst(out.lines, "1011") self.assertEqual({tensor_format.BEGIN_INDICES_KEY: [0, 1, 0]}, out.annotations[actual_row_0_1_0]) # Find the first line that is completely omitted. omitted_line = 2 while not out.lines[omitted_line].strip().startswith("..."): omitted_line += 1 self.assertEqual({tensor_format.OMITTED_INDICES_KEY: [0, 2, 0]}, out.annotations[omitted_line]) actual_row_10_10_0, _ = self._findFirst(out.lines, "2320") self.assertEqual({tensor_format.BEGIN_INDICES_KEY: [10, 10, 0]}, out.annotations[actual_row_10_10_0]) # Find the last line that is completely omitted. omitted_line = len(out.lines) - 1 while not out.lines[omitted_line].strip().startswith("..."): omitted_line -= 1 self.assertEqual({tensor_format.OMITTED_INDICES_KEY: [10, 2, 0]}, out.annotations[omitted_line])
def print_tensor(self, args, screen_info=None): """Command handler for print_tensor. Print value of a given dumped tensor. Args: args: Command-line arguments, excluding the command prefix, as a list of str. screen_info: Optional dict input containing screen information such as cols. Returns: Output text lines as a RichTextLines object. """ if screen_info and "cols" in screen_info: np_printoptions = {"linewidth": screen_info["cols"]} else: np_printoptions = {} parsed = self._arg_parsers["print_tensor"].parse_args(args) node_name, output_slot = debug_data.parse_node_or_tensor_name( parsed.tensor_name) if output_slot is None: return self._error("\"%s\" is not a valid tensor name" % parsed.tensor_name) if not self._debug_dump.node_exists(node_name): return self._error( "Node \"%s\" does not exist in partition graphs" % node_name) watch_keys = self._debug_dump.debug_watch_keys(node_name) # Find debug dump data that match the tensor name (node name + output # slot). matching_data = [] for watch_key in watch_keys: debug_tensor_data = self._debug_dump.watch_key_to_data(watch_key) for datum in debug_tensor_data: if datum.output_slot == output_slot: matching_data.append(datum) if not matching_data: return self._error( "Tensor \"%s\" did not generate any dumps." % parsed.tensor_name) # TODO(cais): In the case of multiple dumps from the same tensor, require # explicit specification of the DebugOp and the temporal order. if len(matching_data) > 1: return self._error( "print_tensor logic for multiple dumped records has not been " "implemented.") return tensor_format.format_tensor( matching_data[0].get_tensor(), matching_data[0].watch_key, include_metadata=True, np_printoptions=np_printoptions)
def print_tensor(self, args, screen_info=None): """Command handler for print_tensor. Print value of a given dumped tensor. Args: args: Command-line arguments, excluding the command prefix, as a list of str. screen_info: Optional dict input containing screen information such as cols. Returns: Output text lines as a RichTextLines object. """ if screen_info and "cols" in screen_info: np_printoptions = {"linewidth": screen_info["cols"]} else: np_printoptions = {} parsed = self._arg_parsers["print_tensor"].parse_args(args) node_name, output_slot = self._parse_node_or_tensor_name( parsed.tensor_name) if output_slot is None: return self._error("\"%s\" is not a valid tensor name" % parsed.tensor_name) if not self._debug_dump.node_exists(node_name): return self._error( "Node \"%s\" does not exist in partition graphs" % node_name) watch_keys = self._debug_dump.debug_watch_keys(node_name) # Find debug dump data that match the tensor name (node name + output # slot). matching_data = [] for watch_key in watch_keys: debug_tensor_data = self._debug_dump.watch_key_to_data(watch_key) for datum in debug_tensor_data: if datum.output_slot == output_slot: matching_data.append(datum) if not matching_data: return self._error( "Tensor \"%s\" did not generate any dumps." % parsed.tensor_name) # TODO(cais): In the case of multiple dumps from the same tensor, require # explicit specification of the DebugOp and the temporal order. if len(matching_data) > 1: return self._error( "print_tensor logic for multiple dumped records has not been " "implemented.") return tensor_format.format_tensor( matching_data[0].get_tensor(), matching_data[0].watch_key, include_metadata=True, np_printoptions=np_printoptions)
def testLocateTensorElementAnnotationsUnavailable(self): out = tensor_format.format_tensor(None, "a") self.assertEqual(["Tensor \"a\":", "", "Uninitialized tensor"], out.lines) with self.assertRaisesRegexp( AttributeError, "tensor_metadata is not available in annotations"): tensor_format.locate_tensor_element(out, [0])
def testFormatTensorSuppressingTensorName(self): a = np.linspace(0.0, 1.0 - 1.0 / 16.0, 16).reshape([4, 4]) out = tensor_format.format_tensor(a, None) self.assertEqual(repr(a).split("\n"), out.lines) self._checkTensorMetadata(a, out.annotations) self._checkBeginIndicesAnnotations(out, a)
def testFormatTensorHighlightsTensorNameWithoutDebugOp(self): tensor_name = "a_tensor:0" a = np.zeros(2) out = tensor_format.format_tensor(a, tensor_name, np_printoptions={"linewidth": 40}) self.assertEqual([(8, 8 + len(tensor_name), "bold")], out.font_attr_segs[0])
def testFormatZeroDimensionTensor(self): a = np.array(42.0, dtype=np.float32) out = tensor_format.format_tensor(a, "a") self.assertEqual(["Tensor \"a\":", "", "array(42.0, dtype=float32)"], out.lines) self._checkTensorMetadata(a, out.annotations)
def testLocateTensorElement1DTinyAndNanValues(self): a = np.ones([3, 3]) * 1e-8 a[1, 0] = np.nan a[1, 2] = np.inf out = tensor_format.format_tensor(a, "a", np_printoptions={"linewidth": 100}) self.assertEqual([ "Tensor \"a\":", "", "array([[ 1.00000000e-08, 1.00000000e-08, 1.00000000e-08],", " [ nan, 1.00000000e-08, inf],", " [ 1.00000000e-08, 1.00000000e-08, 1.00000000e-08]])", ], out.lines) is_omitted, row, start_col, end_col = tensor_format.locate_tensor_element( out, [0, 0]) self.assertFalse(is_omitted) self.assertEqual(2, row) self.assertEqual(10, start_col) self.assertEqual(24, end_col) is_omitted, row, start_col, end_col = tensor_format.locate_tensor_element( out, [0, 2]) self.assertFalse(is_omitted) self.assertEqual(2, row) self.assertEqual(46, start_col) self.assertEqual(60, end_col) is_omitted, row, start_col, end_col = tensor_format.locate_tensor_element( out, [1, 0]) self.assertFalse(is_omitted) self.assertEqual(3, row) self.assertEqual(21, start_col) self.assertEqual(24, end_col) is_omitted, row, start_col, end_col = tensor_format.locate_tensor_element( out, [1, 1]) self.assertFalse(is_omitted) self.assertEqual(3, row) self.assertEqual(28, start_col) self.assertEqual(42, end_col) is_omitted, row, start_col, end_col = tensor_format.locate_tensor_element( out, [1, 2]) self.assertFalse(is_omitted) self.assertEqual(3, row) self.assertEqual(57, start_col) self.assertEqual(60, end_col) is_omitted, row, start_col, end_col = tensor_format.locate_tensor_element( out, [2, 2]) self.assertFalse(is_omitted) self.assertEqual(4, row) self.assertEqual(46, start_col) self.assertEqual(60, end_col)
def testLocateTensorElement1DTinyAndNanValues(self): a = np.ones([3, 3]) * 1e-8 a[1, 0] = np.nan a[1, 2] = np.inf out = tensor_format.format_tensor( a, "a", np_printoptions={"linewidth": 100}) self.assertEqual([ "Tensor \"a\":", "", "array([[ 1.00000000e-08, 1.00000000e-08, 1.00000000e-08],", " [ nan, 1.00000000e-08, inf],", " [ 1.00000000e-08, 1.00000000e-08, 1.00000000e-08]])", ], out.lines) is_omitted, row, start_col, end_col = tensor_format.locate_tensor_element( out, [0, 0]) self.assertFalse(is_omitted) self.assertEqual(2, row) self.assertEqual(10, start_col) self.assertEqual(24, end_col) is_omitted, row, start_col, end_col = tensor_format.locate_tensor_element( out, [0, 2]) self.assertFalse(is_omitted) self.assertEqual(2, row) self.assertEqual(46, start_col) self.assertEqual(60, end_col) is_omitted, row, start_col, end_col = tensor_format.locate_tensor_element( out, [1, 0]) self.assertFalse(is_omitted) self.assertEqual(3, row) self.assertEqual(21, start_col) self.assertEqual(24, end_col) is_omitted, row, start_col, end_col = tensor_format.locate_tensor_element( out, [1, 1]) self.assertFalse(is_omitted) self.assertEqual(3, row) self.assertEqual(28, start_col) self.assertEqual(42, end_col) is_omitted, row, start_col, end_col = tensor_format.locate_tensor_element( out, [1, 2]) self.assertFalse(is_omitted) self.assertEqual(3, row) self.assertEqual(57, start_col) self.assertEqual(60, end_col) is_omitted, row, start_col, end_col = tensor_format.locate_tensor_element( out, [2, 2]) self.assertFalse(is_omitted) self.assertEqual(4, row) self.assertEqual(46, start_col) self.assertEqual(60, end_col)
def testFormatTensorWithEllipses(self): a = np.zeros([11, 11, 11]) out = tensor_format.format_tensor( a, "a", False, np_printoptions={"threshold": 100, "edgeitems": 2}) self.assertEqual([ "Tensor \"a\":", "", "array([[[ 0., 0., ..., 0., 0.],", " [ 0., 0., ..., 0., 0.],", " ..., ", " [ 0., 0., ..., 0., 0.],", " [ 0., 0., ..., 0., 0.]],", "", " [[ 0., 0., ..., 0., 0.],", " [ 0., 0., ..., 0., 0.],", " ..., ", " [ 0., 0., ..., 0., 0.],", " [ 0., 0., ..., 0., 0.]],", "", " ..., ", " [[ 0., 0., ..., 0., 0.],", " [ 0., 0., ..., 0., 0.],", " ..., ", " [ 0., 0., ..., 0., 0.],", " [ 0., 0., ..., 0., 0.]],", "", " [[ 0., 0., ..., 0., 0.],", " [ 0., 0., ..., 0., 0.],", " ..., ", " [ 0., 0., ..., 0., 0.],", " [ 0., 0., ..., 0., 0.]]])", ], out.lines) self._checkTensorMetadata(a, out.annotations) # Check annotations for beginning indices of the lines. for i in xrange(2): self._checkBeginIndices([i, 0, 0], out.annotations[i * 6 + 2]) self._checkBeginIndices([i, 1, 0], out.annotations[i * 6 + 3]) self._checkOmittedIndices([i, 2, 0], out.annotations[i * 6 + 4]) self._checkBeginIndices([i, 9, 0], out.annotations[i * 6 + 5]) self._checkBeginIndices([i, 10, 0], out.annotations[i * 6 + 6]) self.assertNotIn(i * 6 + 7, out.annotations) p = 15 for i in xrange(2): self._checkBeginIndices([9 + i, 0, 0], out.annotations[p + i * 6]) self._checkBeginIndices([9 + i, 1, 0], out.annotations[p + i * 6 + 1]) self._checkOmittedIndices( [9 + i, 2, 0], out.annotations[p + i * 6 + 2]) self._checkBeginIndices([9 + i, 9, 0], out.annotations[p + i * 6 + 3]) self._checkBeginIndices([9 + i, 10, 0], out.annotations[p + i * 6 + 4]) if i < 1: self.assertNotIn(p + i * 6 + 5, out.annotations)
def testFormatZeroDimensionTensor(self): a = np.array(42, dtype=np.int32) out = tensor_format.format_tensor(a, "a") cli_test_utils.assert_lines_equal_ignoring_whitespace( self, ["Tensor \"a\":", ""], out.lines[:2]) self.assertTrue(out.lines[2].startswith("array(42")) self._checkTensorMetadata(a, out.annotations)
def testFormatResourceTypeTensor(self): tensor_proto = tensor_pb2.TensorProto( dtype=types_pb2.DataType.Value("DT_RESOURCE"), tensor_shape=tensor_shape_pb2.TensorShapeProto( dim=[tensor_shape_pb2.TensorShapeProto.Dim(size=1)])) out = tensor_format.format_tensor( debug_data.InconvertibleTensorProto(tensor_proto), "a") self.assertEqual(["Tensor \"a\":", ""], out.lines[:2]) self.assertEqual(str(tensor_proto).split("\n"), out.lines[2:])
def testFormatTensorHighlightsTensorNameWithDebugOp(self): tensor_name = "a_tensor:0" debug_op = "DebugIdentity" a = np.zeros(2) out = tensor_format.format_tensor( a, "%s:%s" % (tensor_name, debug_op), np_printoptions={"linewidth": 40}) self.assertEqual([(8, 8 + len(tensor_name), "bold"), (8 + len(tensor_name) + 1, 8 + len(tensor_name) + 1 + len(debug_op), "yellow")], out.font_attr_segs[0])
def testFormatTensorHighlightsTensorNameWithDebugOp(self): tensor_name = "a_tensor:0" debug_op = "DebugIdentity" a = np.zeros(2) out = tensor_format.format_tensor(a, "%s:%s" % (tensor_name, debug_op), np_printoptions={"linewidth": 40}) self.assertEqual([(8, 8 + len(tensor_name), "bold"), (8 + len(tensor_name) + 1, 8 + len(tensor_name) + 1 + len(debug_op), "yellow")], out.font_attr_segs[0])
def _format_tensor(self, tensor, watch_key, np_printoptions, print_all=False, tensor_slicing=None, highlight_options=None): """Generate formatted str to represent a tensor or its slices. Args: tensor: (numpy ndarray) The tensor value. watch_key: (str) Tensor debug watch key. np_printoptions: (dict) Numpy tensor formatting options. print_all: (bool) Whether the tensor is to be displayed in its entirety, instead of printing ellipses, even if its number of elements exceeds the default numpy display threshold. (Note: Even if this is set to true, the screen output can still be cut off by the UI frontend if it consist of more lines than the frontend can handle.) tensor_slicing: (str or None) Slicing of the tensor, e.g., "[:, 1]". If None, no slicing will be performed on the tensor. highlight_options: (tensor_format.HighlightOptions) options to highlight elements of the tensor. See the doc of tensor_format.format_tensor() for more details. Returns: (str) Formatted str representing the (potentially sliced) tensor. Raises: ValueError: If tehsor_slicing is not a valid numpy ndarray slicing str. """ if tensor_slicing: # Validate the indexing. if not command_parser.validate_slicing_string(tensor_slicing): raise ValueError("Invalid tensor-slicing string.") value = eval("tensor" + tensor_slicing) # pylint: disable=eval-used sliced_name = watch_key + tensor_slicing else: value = tensor sliced_name = watch_key if print_all: np_printoptions["threshold"] = value.size else: np_printoptions[ "threshold"] = self.default_ndarray_display_threshold return tensor_format.format_tensor( value, sliced_name, include_metadata=True, np_printoptions=np_printoptions, highlight_options=highlight_options)
def inject_value(self, args, screen_info=None): """Inject value to a given tensor. Args: args: (list of str) command-line arguments for the "step" command. screen_info: Information about screen. Returns: (RichTextLines) Screen output for the result of the stepping action. """ _ = screen_info # Currently unused. if screen_info and "cols" in screen_info: np_printoptions = {"linewidth": screen_info["cols"]} else: np_printoptions = {} parsed = self.arg_parsers["inject_value"].parse_args(args) tensor_names = self._resolve_tensor_names(parsed.tensor_name) if not tensor_names: return cli_shared.error(self._MESSAGE_TEMPLATES["NOT_IN_CLOSURE"] % parsed.tensor_name) elif len(tensor_names) > 1: return cli_shared.error( self._MESSAGE_TEMPLATES["MULTIPLE_TENSORS"] % parsed.tensor_name) else: tensor_name = tensor_names[0] tensor_value = eval(parsed.tensor_value_str) # pylint: disable=eval-used try: self._node_stepper.override_tensor(tensor_name, tensor_value) lines = [ "Injected value \"%s\"" % parsed.tensor_value_str, " to tensor \"%s\":" % tensor_name, "" ] tensor_lines = tensor_format.format_tensor( tensor_value, tensor_name, include_metadata=True, np_printoptions=np_printoptions).lines lines.extend(tensor_lines) except ValueError: lines = [ "ERROR: Failed to inject value to tensor %s" % parsed.tensor_name ] return debugger_cli_common.RichTextLines(lines)
def testLocateTensorElement1DNoEllipsisBatchMode(self): a = np.zeros(20) out = tensor_format.format_tensor( a, "a", np_printoptions={"linewidth": 40}) cli_test_utils.assert_lines_equal_ignoring_whitespace( self, ["Tensor \"a\":", ""], out.lines[:2]) self.assertEqual(repr(a).split("\n"), out.lines[2:]) self._checkTensorElementLocations(out, a)
def testFormatTensor3DNoEllipsis(self): a = np.linspace(0.0, 1.0 - 1.0 / 24.0, 24).reshape([2, 3, 4]) out = tensor_format.format_tensor(a, "a") cli_test_utils.assert_lines_equal_ignoring_whitespace( self, ["Tensor \"a\":", ""], out.lines[:2]) self.assertEqual(repr(a).split("\n"), out.lines[2:]) self._checkTensorMetadata(a, out.annotations) self._checkBeginIndicesAnnotations(out, a)
def testLocateTensorElement1DNoEllipsis(self): a = np.zeros(20) out = tensor_format.format_tensor( a, "a", np_printoptions={"linewidth": 40}) self.assertEqual([ "Tensor \"a\":", "", "array([ 0., 0., 0., 0., 0., 0.,", " 0., 0., 0., 0., 0., 0.,", " 0., 0., 0., 0., 0., 0.,", " 0., 0.])", ], out.lines) is_omitted, row = tensor_format.locate_tensor_element(out, [0]) self.assertFalse(is_omitted) self.assertEqual(2, row) is_omitted, row = tensor_format.locate_tensor_element(out, [5]) self.assertFalse(is_omitted) self.assertEqual(2, row) is_omitted, row = tensor_format.locate_tensor_element(out, [6]) self.assertFalse(is_omitted) self.assertEqual(3, row) is_omitted, row = tensor_format.locate_tensor_element(out, [11]) self.assertFalse(is_omitted) self.assertEqual(3, row) is_omitted, row = tensor_format.locate_tensor_element(out, [12]) self.assertFalse(is_omitted) self.assertEqual(4, row) is_omitted, row = tensor_format.locate_tensor_element(out, [18]) self.assertFalse(is_omitted) self.assertEqual(5, row) is_omitted, row = tensor_format.locate_tensor_element(out, [19]) self.assertFalse(is_omitted) self.assertEqual(5, row) with self.assertRaisesRegexp( ValueError, "Indices exceed tensor dimensions"): tensor_format.locate_tensor_element(out, [20]) with self.assertRaisesRegexp( ValueError, "Indices contain negative"): tensor_format.locate_tensor_element(out, [-1]) with self.assertRaisesRegexp( ValueError, "Dimensions mismatch"): tensor_format.locate_tensor_element(out, [0, 0])
def testFormatUninitializedTensor(self): tensor_proto = tensor_pb2.TensorProto( dtype=types_pb2.DataType.Value("DT_FLOAT"), tensor_shape=tensor_shape_pb2.TensorShapeProto( dim=[tensor_shape_pb2.TensorShapeProto.Dim(size=1)])) out = tensor_format.format_tensor( debug_data.InconvertibleTensorProto(tensor_proto, False), "a") self.assertEqual(["Tensor \"a\":", "", "Uninitialized tensor:"], out.lines[:3]) self.assertEqual(str(tensor_proto).split("\n"), out.lines[3:])
def _format_tensor(self, tensor, watch_key, np_printoptions, print_all=False, tensor_slicing=None, highlight_options=None): """Generate formatted str to represent a tensor or its slices. Args: tensor: (numpy ndarray) The tensor value. watch_key: (str) Tensor debug watch key. np_printoptions: (dict) Numpy tensor formatting options. print_all: (bool) Whether the tensor is to be displayed in its entirety, instead of printing ellipses, even if its number of elements exceeds the default numpy display threshold. (Note: Even if this is set to true, the screen output can still be cut off by the UI frontend if it consist of more lines than the frontend can handle.) tensor_slicing: (str or None) Slicing of the tensor, e.g., "[:, 1]". If None, no slicing will be performed on the tensor. highlight_options: (tensor_format.HighlightOptions) options to highlight elements of the tensor. See the doc of tensor_format.format_tensor() for more details. Returns: (str) Formatted str representing the (potentially sliced) tensor. Raises: ValueError: If tehsor_slicing is not a valid numpy ndarray slicing str. """ if tensor_slicing: # Validate the indexing. if not command_parser.validate_slicing_string(tensor_slicing): raise ValueError("Invalid tensor-slicing string.") value = eval("tensor" + tensor_slicing) # pylint: disable=eval-used sliced_name = watch_key + tensor_slicing else: value = tensor sliced_name = watch_key if print_all: np_printoptions["threshold"] = value.size else: np_printoptions[ "threshold"] = self.default_ndarray_display_threshold return tensor_format.format_tensor(value, sliced_name, include_metadata=True, np_printoptions=np_printoptions, highlight_options=highlight_options)
def testFormatTensorWithMetadata(self): a = np.linspace(0.0, 1.0 - 1.0 / 16.0, 16).reshape([4, 4]) out = tensor_format.format_tensor(a, "a", include_metadata=True) cli_test_utils.assert_lines_equal_ignoring_whitespace( self, ["Tensor \"a\":", " dtype: float64", " shape: (4, 4)", ""], out.lines[:4]) self.assertEqual(repr(a).split("\n"), out.lines[4:]) self._checkTensorMetadata(a, out.annotations) self._checkBeginIndicesAnnotations(out, a)
def testLocateTensorElement1DNoEllipsisBatchMode(self): a = np.zeros(20) out = tensor_format.format_tensor(a, "a", np_printoptions={"linewidth": 40}) cli_test_utils.assert_lines_equal_ignoring_whitespace( self, ["Tensor \"a\":", ""], out.lines[:2]) self.assertEqual(repr(a).split("\n"), out.lines[2:]) self._checkTensorElementLocations(out, a)
def format_tensor(tensor, tensor_name, np_printoptions, print_all=False, tensor_slicing=None, highlight_options=None, include_numeric_summary=False): """Generate formatted str to represent a tensor or its slices. Args: tensor: (numpy ndarray) The tensor value. tensor_name: (str) Name of the tensor, e.g., the tensor's debug watch key. np_printoptions: (dict) Numpy tensor formatting options. print_all: (bool) Whether the tensor is to be displayed in its entirety, instead of printing ellipses, even if its number of elements exceeds the default numpy display threshold. (Note: Even if this is set to true, the screen output can still be cut off by the UI frontend if it consist of more lines than the frontend can handle.) tensor_slicing: (str or None) Slicing of the tensor, e.g., "[:, 1]". If None, no slicing will be performed on the tensor. highlight_options: (tensor_format.HighlightOptions) options to highlight elements of the tensor. See the doc of tensor_format.format_tensor() for more details. include_numeric_summary: Whether a text summary of the numeric values (if applicable) will be included. Returns: An instance of `debugger_cli_common.RichTextLines` representing the (potentially sliced) tensor. """ if tensor_slicing: # Validate the indexing. value = command_parser.evaluate_tensor_slice(tensor, tensor_slicing) sliced_name = tensor_name + tensor_slicing else: value = tensor sliced_name = tensor_name if print_all: np_printoptions["threshold"] = value.size else: np_printoptions["threshold"] = DEFAULT_NDARRAY_DISPLAY_THRESHOLD return tensor_format.format_tensor( value, sliced_name, include_metadata=True, include_numeric_summary=include_numeric_summary, np_printoptions=np_printoptions, highlight_options=highlight_options)
def inject_value(self, args, screen_info=None): """Inject value to a given tensor. Args: args: (list of str) command-line arguments for the "step" command. screen_info: Information about screen. Returns: (RichTextLines) Screen output for the result of the stepping action. """ _ = screen_info # Currently unused. if screen_info and "cols" in screen_info: np_printoptions = {"linewidth": screen_info["cols"]} else: np_printoptions = {} parsed = self.arg_parsers["inject_value"].parse_args(args) tensor_names = self._resolve_tensor_names(parsed.tensor_name) if not tensor_names: return cli_shared.error( self._MESSAGE_TEMPLATES["NOT_IN_CLOSURE"] % parsed.tensor_name) elif len(tensor_names) > 1: return cli_shared.error( self._MESSAGE_TEMPLATES["MULTIPLE_TENSORS"] % parsed.tensor_name) else: tensor_name = tensor_names[0] tensor_value = eval(parsed.tensor_value_str) # pylint: disable=eval-used try: self._node_stepper.override_tensor(tensor_name, tensor_value) lines = [ "Injected value \"%s\"" % parsed.tensor_value_str, " to tensor \"%s\":" % tensor_name, "" ] tensor_lines = tensor_format.format_tensor( tensor_value, tensor_name, include_metadata=True, np_printoptions=np_printoptions).lines lines.extend(tensor_lines) except ValueError: lines = [ "ERROR: Failed to inject value to tensor %s" % parsed.tensor_name ] return debugger_cli_common.RichTextLines(lines)
def testLocateTensorElement1DTinyAndNanValues(self): a = np.ones([3, 3]) * 1e-8 a[1, 0] = np.nan a[1, 2] = np.inf out = tensor_format.format_tensor( a, "a", np_printoptions={"linewidth": 100}) cli_test_utils.assert_lines_equal_ignoring_whitespace( self, ["Tensor \"a\":", ""], out.lines[:2]) self.assertEqual(repr(a).split("\n"), out.lines[2:]) self._checkTensorElementLocations(out, a)
def testLocateTensorElement1DNoEllipsisBatchMode(self): a = np.zeros(20) out = tensor_format.format_tensor(a, "a", np_printoptions={"linewidth": 40}) self.assertEqual([ "Tensor \"a\":", "", "array([ 0., 0., 0., 0., 0., 0.,", " 0., 0., 0., 0., 0., 0.,", " 0., 0., 0., 0., 0., 0.,", " 0., 0.])", ], out.lines) (are_omitted, rows, start_cols, end_cols) = tensor_format.locate_tensor_element(out, [[0]]) self.assertEqual([False], are_omitted) self.assertEqual([2], rows) self.assertEqual([8], start_cols) self.assertEqual([10], end_cols) (are_omitted, rows, start_cols, end_cols) = tensor_format.locate_tensor_element(out, [[0], [5]]) self.assertEqual([False, False], are_omitted) self.assertEqual([2, 2], rows) self.assertEqual([8, 33], start_cols) self.assertEqual([10, 35], end_cols) (are_omitted, rows, start_cols, end_cols) = tensor_format.locate_tensor_element(out, [[0], [6]]) self.assertEqual([False, False], are_omitted) self.assertEqual([2, 3], rows) self.assertEqual([8, 8], start_cols) self.assertEqual([10, 10], end_cols) (are_omitted, rows, start_cols, end_cols) = tensor_format.locate_tensor_element(out, [[0], [5], [6]]) self.assertEqual([False, False, False], are_omitted) self.assertEqual([2, 2, 3], rows) self.assertEqual([8, 33, 8], start_cols) self.assertEqual([10, 35, 10], end_cols) (are_omitted, rows, start_cols, end_cols) = tensor_format.locate_tensor_element( out, [[0], [5], [6], [19]]) self.assertEqual([False, False, False, False], are_omitted) self.assertEqual([2, 2, 3, 5], rows) self.assertEqual([8, 33, 8, 13], start_cols) self.assertEqual([10, 35, 10, 15], end_cols)
def testLocateTensorElement1DTinyAndNanValues(self): a = np.ones([3, 3]) * 1e-8 a[1, 0] = np.nan a[1, 2] = np.inf out = tensor_format.format_tensor(a, "a", np_printoptions={"linewidth": 100}) cli_test_utils.assert_lines_equal_ignoring_whitespace( self, ["Tensor \"a\":", ""], out.lines[:2]) self.assertEqual(repr(a).split("\n"), out.lines[2:]) self._checkTensorElementLocations(out, a)
def testLocateTensorElementAnnotationsUnavailable(self): tensor_proto = tensor_pb2.TensorProto( dtype=types_pb2.DataType.Value("DT_FLOAT"), tensor_shape=tensor_shape_pb2.TensorShapeProto( dim=[tensor_shape_pb2.TensorShapeProto.Dim(size=1)])) out = tensor_format.format_tensor( debug_data.InconvertibleTensorProto(tensor_proto, False), "a") self.assertEqual(["Tensor \"a\":", "", "Uninitialized tensor:"], out.lines[:3]) with self.assertRaisesRegexp( AttributeError, "tensor_metadata is not available in annotations"): tensor_format.locate_tensor_element(out, [0])
def testFormatTensor1DNoEllipsis(self): a = np.zeros(20) out = tensor_format.format_tensor( a, "a", np_printoptions={"linewidth": 40}) cli_test_utils.assert_lines_equal_ignoring_whitespace( self, ["Tensor \"a\":", ""], out.lines[:2]) self.assertEqual(repr(a).split("\n"), out.lines[2:]) self._checkTensorMetadata(a, out.annotations) # Check annotations for beginning indices of the lines. self._checkBeginIndicesAnnotations(out, a)
def testLocateTensorElement3DWithEllipsesBatchMode(self): a = (np.arange(11 * 11 * 11) + 1000).reshape([11, 11, 11]).astype(np.int32) out = tensor_format.format_tensor(a, "a", False, np_printoptions={ "threshold": 100, "edgeitems": 2 }) cli_test_utils.assert_lines_equal_ignoring_whitespace( self, ["Tensor \"a\":", ""], out.lines[:2]) self.assertEqual(repr(a).split("\n"), out.lines[2:]) actual_row_0_0_0, actual_col_0_0_0 = self._findFirst(out.lines, "1000") actual_row_0_0_10, _ = self._findFirst(out.lines, "1010") actual_row_10_10_10, _ = self._findFirst(out.lines, "2330") (are_omitted, rows, start_cols, end_cols) = tensor_format.locate_tensor_element(out, [[0, 0, 0]]) self.assertEqual([False], are_omitted) self.assertEqual([actual_row_0_0_0], rows) self.assertEqual([actual_col_0_0_0], start_cols) self.assertEqual([actual_col_0_0_0 + 4], end_cols) (are_omitted, rows, start_cols, end_cols) = tensor_format.locate_tensor_element( out, [[0, 0, 0], [0, 0, 10]]) self.assertEqual([False, False], are_omitted) self.assertEqual([actual_row_0_0_0, actual_row_0_0_10], rows) self.assertEqual([actual_col_0_0_0, None], start_cols) self.assertEqual([actual_col_0_0_0 + 4, None], end_cols) (are_omitted, rows, start_cols, end_cols) = tensor_format.locate_tensor_element( out, [[0, 0, 0], [0, 2, 0]]) self.assertEqual([False, True], are_omitted) self.assertEqual([2, 4], rows) self.assertEqual(2, len(start_cols)) self.assertEqual(2, len(end_cols)) (are_omitted, rows, start_cols, end_cols) = tensor_format.locate_tensor_element( out, [[0, 0, 0], [10, 10, 10]]) self.assertEqual([False, False], are_omitted) self.assertEqual([actual_row_0_0_0, actual_row_10_10_10], rows) self.assertEqual([actual_col_0_0_0, None], start_cols) self.assertEqual([actual_col_0_0_0 + 4, None], end_cols)
def testLocateTensorElement1DNoEllipsisBatchMode(self): a = np.zeros(20) out = tensor_format.format_tensor( a, "a", np_printoptions={"linewidth": 40}) self.assertEqual([ "Tensor \"a\":", "", "array([ 0., 0., 0., 0., 0., 0.,", " 0., 0., 0., 0., 0., 0.,", " 0., 0., 0., 0., 0., 0.,", " 0., 0.])", ], out.lines) (are_omitted, rows, start_cols, end_cols) = tensor_format.locate_tensor_element(out, [[0]]) self.assertEqual([False], are_omitted) self.assertEqual([2], rows) self.assertEqual([8], start_cols) self.assertEqual([10], end_cols) (are_omitted, rows, start_cols, end_cols) = tensor_format.locate_tensor_element(out, [[0], [5]]) self.assertEqual([False, False], are_omitted) self.assertEqual([2, 2], rows) self.assertEqual([8, 33], start_cols) self.assertEqual([10, 35], end_cols) (are_omitted, rows, start_cols, end_cols) = tensor_format.locate_tensor_element(out, [[0], [6]]) self.assertEqual([False, False], are_omitted) self.assertEqual([2, 3], rows) self.assertEqual([8, 8], start_cols) self.assertEqual([10, 10], end_cols) (are_omitted, rows, start_cols, end_cols) = tensor_format.locate_tensor_element(out, [[0], [5], [6]]) self.assertEqual([False, False, False], are_omitted) self.assertEqual([2, 2, 3], rows) self.assertEqual([8, 33, 8], start_cols) self.assertEqual([10, 35, 10], end_cols) (are_omitted, rows, start_cols, end_cols) = tensor_format.locate_tensor_element(out, [[0], [5], [6], [19]]) self.assertEqual([False, False, False, False], are_omitted) self.assertEqual([2, 2, 3, 5], rows) self.assertEqual([8, 33, 8, 13], start_cols) self.assertEqual([10, 35, 10, 15], end_cols)
def testFormatTensor1DNoEllipsis(self): a = np.zeros(20) out = tensor_format.format_tensor(a, "a", np_printoptions={"linewidth": 40}) cli_test_utils.assert_lines_equal_ignoring_whitespace( self, ["Tensor \"a\":", ""], out.lines[:2]) self.assertEqual(repr(a).split("\n"), out.lines[2:]) self._checkTensorMetadata(a, out.annotations) # Check annotations for beginning indices of the lines. self._checkBeginIndicesAnnotations(out, a)
def testFormatTensor3DNoEllipsisWithArgwhereHighlightWithMatches(self): a = np.linspace(0.0, 1.0 - 1.0 / 24.0, 24).reshape([2, 3, 4]) lower_bound = 0.26 upper_bound = 0.5 def highlight_filter(x): return np.logical_and(x > lower_bound, x < upper_bound) highlight_options = tensor_format.HighlightOptions( highlight_filter, description="between 0.26 and 0.5") out = tensor_format.format_tensor( a, "a", highlight_options=highlight_options) self.assertEqual([ "Tensor \"a\": " "Highlighted(between 0.26 and 0.5): 5 of 24 element(s) (20.83%)", "", "array([[[ 0. , 0.04166667, 0.08333333, 0.125 ],", " [ 0.16666667, 0.20833333, 0.25 , 0.29166667],", " [ 0.33333333, 0.375 , 0.41666667, 0.45833333]],", "", " [[ 0.5 , 0.54166667, 0.58333333, 0.625 ],", " [ 0.66666667, 0.70833333, 0.75 , 0.79166667],", " [ 0.83333333, 0.875 , 0.91666667, 0.95833333]]])", ], out.lines) self._checkTensorMetadata(a, out.annotations) # Check annotations for beginning indices of the lines. self._checkBeginIndices([0, 0, 0], out.annotations[2]) self._checkBeginIndices([0, 1, 0], out.annotations[3]) self._checkBeginIndices([0, 2, 0], out.annotations[4]) self.assertNotIn(5, out.annotations) self._checkBeginIndices([1, 0, 0], out.annotations[6]) self._checkBeginIndices([1, 1, 0], out.annotations[7]) self._checkBeginIndices([1, 2, 0], out.annotations[8]) # Check font attribute segments for highlighted elements. self.assertNotIn(2, out.font_attr_segs) self.assertEqual([(49, 59, "bold")], out.font_attr_segs[3]) self.assertEqual([(10, 20, "bold"), (23, 28, "bold"), (36, 46, "bold"), (49, 59, "bold")], out.font_attr_segs[4]) self.assertNotIn(5, out.font_attr_segs) self.assertNotIn(6, out.font_attr_segs) self.assertNotIn(7, out.font_attr_segs) self.assertNotIn(8, out.font_attr_segs)
def testFormatTensorSuppressingTensorName(self): a = np.linspace(0.0, 1.0 - 1.0 / 16.0, 16).reshape([4, 4]) out = tensor_format.format_tensor(a, None) self.assertEqual([ "array([[ 0. , 0.0625, 0.125 , 0.1875],", " [ 0.25 , 0.3125, 0.375 , 0.4375],", " [ 0.5 , 0.5625, 0.625 , 0.6875],", " [ 0.75 , 0.8125, 0.875 , 0.9375]])", ], out.lines) self._checkTensorMetadata(a, out.annotations) # Check annotations for the beginning indices of the lines. for i in xrange(4): self._checkBeginIndices([i, 0], out.annotations[i])