Removed StackFrame.func_start_lineno and Operation.traceback_with_start_lines

They were only referenced inside tfprof and, as far as I can tell, never used
in the tfprof UI.

PiperOrigin-RevId: 265987217
This commit is contained in:
Sergei Lebedev 2019-08-28 13:59:33 -07:00 committed by TensorFlower Gardener
parent 804eb6e03f
commit fd4ece49c9
11 changed files with 35 additions and 110 deletions

View File

@ -670,7 +670,7 @@ class DebugDumpDir(object):
self._node_traceback = {} self._node_traceback = {}
if self._python_graph: if self._python_graph:
for op in self._python_graph.get_operations(): for op in self._python_graph.get_operations():
self._node_traceback[op.name] = op.traceback self._node_traceback[op.name] = tuple(map(tuple, op.traceback))
@property @property
def python_graph(self): def python_graph(self):

View File

@ -18,6 +18,7 @@ from __future__ import absolute_import
from __future__ import division from __future__ import division
from __future__ import print_function from __future__ import print_function
import collections
import os import os
import re import re
@ -28,18 +29,20 @@ from tensorflow.python.framework import test_util
from tensorflow.python.framework import traceable_stack from tensorflow.python.framework import traceable_stack
from tensorflow.python.ops import math_ops from tensorflow.python.ops import math_ops
from tensorflow.python.platform import test from tensorflow.python.platform import test
from tensorflow.python.util import tf_stack
# A mock for ``tf_stack.StackFrame``.
StackFrame = collections.namedtuple(
"StackFrame", ["filename", "lineno", "name", "line"])
def _make_frame_with_filename(op, idx, filename): def _make_frame_with_filename(op, idx, filename):
"""Return a copy of an existing stack frame with a new filename.""" """Return a copy of an existing stack frame with a new filename."""
frame = op._traceback[idx] frame = op._traceback[idx]
return tf_stack.StackFrame( return StackFrame(
filename, filename,
frame.lineno, frame.lineno,
frame.name, frame.name,
frame.globals, frame.line)
frame.func_start_lineno)
def _modify_op_stack_with_filenames(op, num_user_frames, user_filename, def _modify_op_stack_with_filenames(op, num_user_frames, user_filename,

View File

@ -2304,17 +2304,7 @@ class Operation(object):
@property @property
def traceback(self): def traceback(self):
"""Returns the call stack from when this operation was constructed.""" """Returns the call stack from when this operation was constructed."""
return tf_stack.convert_stack(self._traceback) return self._traceback
@property
def traceback_with_start_lines(self):
"""Same as traceback but includes start line of function definition.
Returns:
A list of 5-tuples (filename, lineno, name, code, func_start_lineno).
"""
return tf_stack.convert_stack(
self._traceback, include_func_start_lineno=True)
def _set_attr(self, attr_name, attr_value): def _set_attr(self, attr_name, attr_value):
"""Private method used to set an attribute in the node_def.""" """Private method used to set an attribute in the node_def."""

View File

@ -3350,28 +3350,6 @@ class NameScopeTest(test_util.TensorFlowTestCase):
self.assertRaisesRegexp(ValueError, "'_' is not a valid scope name", f) self.assertRaisesRegexp(ValueError, "'_' is not a valid scope name", f)
class TracebackTest(test_util.TensorFlowTestCase):
@test_util.run_deprecated_v1
def testTracebackWithStartLines(self):
with self.cached_session() as sess:
a = constant_op.constant(2.0)
sess.run(
a,
options=config_pb2.RunOptions(
trace_level=config_pb2.RunOptions.FULL_TRACE))
self.assertTrue(sess.graph.get_operations())
# Tests that traceback_with_start_lines is the same as traceback
# but includes one more element at the end.
for op in sess.graph.get_operations():
self.assertEquals(len(op.traceback), len(op.traceback_with_start_lines))
for frame, frame_with_start_line in zip(
op.traceback, op.traceback_with_start_lines):
self.assertEquals(5, len(frame_with_start_line))
self.assertEquals(frame, frame_with_start_line[:-1])
class EnableEagerExecutionTest(test_util.TensorFlowTestCase): class EnableEagerExecutionTest(test_util.TensorFlowTestCase):
@test_util.run_v1_only("b/120545219") @test_util.run_v1_only("b/120545219")

View File

@ -328,7 +328,7 @@ class PprofProfiler(object):
# Call at current frame calls function at previous frame. # Call at current frame calls function at previous frame.
prev_file_path = prev_stack_frame[0] prev_file_path = prev_stack_frame[0]
prev_function = prev_stack_frame[2] prev_function = prev_stack_frame[2]
prev_function_start_line = prev_stack_frame[4] prev_function_start_line = -1
curr_file_path = stack_frame[0] curr_file_path = stack_frame[0]
curr_line_number = stack_frame[1] curr_line_number = stack_frame[1]
@ -371,7 +371,7 @@ class PprofProfiler(object):
node_to_traceback = defaultdict(list) node_to_traceback = defaultdict(list)
node_to_op_type = defaultdict(str) node_to_op_type = defaultdict(str)
for op in self._graph.get_operations(): for op in self._graph.get_operations():
node_to_traceback[op.name] = op.traceback_with_start_lines node_to_traceback[op.name] = op.traceback
node_to_op_type[op.name] = op.type node_to_op_type[op.name] = op.type
def profile_data_generator(device_step_stats): def profile_data_generator(device_step_stats):

View File

@ -113,13 +113,14 @@ def _get_logged_ops(graph, run_meta=None, add_trace=True,
add_entry = True add_entry = True
if add_trace: if add_trace:
for tb in op.traceback_with_start_lines: for tb in op.traceback:
trace = entry.code_def.traces.add() trace = entry.code_def.traces.add()
trace.file_id = _str_id(tb[0], string_to_id) if tb[0] else 0 trace.file_id = _str_id(tb[0], string_to_id) if tb[0] else 0
trace.lineno = tb[1] if tb[1] else -1 trace.lineno = tb[1] if tb[1] else -1
trace.function_id = _str_id(tb[2], string_to_id) if tb[2] else 0 trace.function_id = _str_id(tb[2], string_to_id) if tb[2] else 0
trace.line_id = _str_id(tb[3], string_to_id) if tb[3] else 0 trace.line_id = _str_id(tb[3], string_to_id) if tb[3] else 0
trace.func_start_line = tb[4] if tb[4] else -1 # TODO(slebedev): remove this unused field from the proto.
trace.func_start_line = -1
add_entry = True add_entry = True
if add_entry: if add_entry:

View File

@ -37,7 +37,6 @@ struct StackFrame {
int lineno; int lineno;
py::str name; py::str name;
py::object globals; py::object globals;
int func_start_lineno;
py::object line() const { py::object line() const {
static const auto* linecache = static const auto* linecache =
@ -101,9 +100,7 @@ std::vector<StackFrame> ExtractStack(ssize_t limit, const py::list& mappers,
} }
const auto& globals = py::reinterpret_borrow<py::object>(f->f_globals); const auto& globals = py::reinterpret_borrow<py::object>(f->f_globals);
const int func_start_lineno = co->co_firstlineno; ret.push_back({std::move(filename), lineno, std::move(name), globals});
ret.push_back({std::move(filename), lineno, std::move(name), globals,
func_start_lineno});
} }
std::reverse(ret.begin(), ret.end()); std::reverse(ret.begin(), ret.end());
@ -115,14 +112,9 @@ std::vector<StackFrame> ExtractStack(ssize_t limit, const py::list& mappers,
PYBIND11_MODULE(_tf_stack, m) { PYBIND11_MODULE(_tf_stack, m) {
// TODO(slebedev): rename to FrameSummary to match Python 3.5+. // TODO(slebedev): rename to FrameSummary to match Python 3.5+.
py::class_<StackFrame>(m, "StackFrame") py::class_<StackFrame>(m, "StackFrame")
.def(py::init<const py::str&, int, const py::str&, const py::object&,
int>())
.def_readonly("filename", &StackFrame::filename) .def_readonly("filename", &StackFrame::filename)
.def_readonly("lineno", &StackFrame::lineno) .def_readonly("lineno", &StackFrame::lineno)
.def_readonly("name", &StackFrame::name) .def_readonly("name", &StackFrame::name)
// TODO(slebedev): remove globals and make the constructor private.
.def_readonly("globals", &StackFrame::globals)
.def_readonly("func_start_lineno", &StackFrame::func_start_lineno)
.def_property_readonly("line", &StackFrame::line) .def_property_readonly("line", &StackFrame::line)
.def("__repr__", .def("__repr__",
[](const StackFrame& self) { [](const StackFrame& self) {
@ -132,26 +124,28 @@ PYBIND11_MODULE(_tf_stack, m) {
// For compatibility with the traceback module. // For compatibility with the traceback module.
.def("__getitem__", .def("__getitem__",
[](const StackFrame& self, ssize_t index) -> py::object { [](const StackFrame& self, const py::object& index) -> py::object {
switch (index >= 0 ? index : 4 + index) { return py::make_tuple(self.filename, self.lineno, self.name,
case 0: self.line())[index];
return self.filename;
case 1:
return py::cast(self.lineno);
case 2:
return self.name;
case 3:
return self.line();
default:
throw py::index_error();
}
}) })
.def("__len__", [](const StackFrame&) { .def("__len__", [](const StackFrame&) {
return 4; // For compatibility with the traceback module. return 4; // For compatibility with the traceback module.
}); });
// TODO(slebedev): rename to StackSummary to match Python 3.5+. // TODO(slebedev): rename to StackSummary to match Python 3.5+.
py::bind_vector<std::vector<StackFrame>>(m, "Stack", py::module_local(true)); py::bind_vector<std::vector<StackFrame>>(m, "Stack", py::module_local(true))
// TODO(slebedev): upstream negative indexing support into pybind11.
.def(
"__getitem__",
[](const std::vector<StackFrame>& self, ssize_t index) {
const size_t eff_index =
index < 0 ? self.size() + index : static_cast<size_t>(index);
if (eff_index > self.size()) {
throw py::index_error();
}
return self[eff_index];
},
py::return_value_policy::reference_internal);
m.def("extract_stack", [](const py::object& limit, const py::list& mappers, m.def("extract_stack", [](const py::object& limit, const py::list& mappers,
const py::list& filters) { const py::list& filters) {

View File

@ -148,11 +148,8 @@ def extract_stack(limit=-1):
limit: A limit on the number of frames to return. limit: A limit on the number of frames to return.
Returns: Returns:
A sequence of StackFrame objects A sequence of StackFrame objects (filename, lineno, name, line)
(filename, lineno, name, globals, func_start_lineno) corresponding to the call stack of the current thread.
corresponding to the call stack of the current thread. The returned
tuples have the innermost stack frame at the end, unlike the Python
inspect module's stack() function.
""" """
# N.B ExtractStack in tf_stack.cc will drop this frame prior to # N.B ExtractStack in tf_stack.cc will drop this frame prior to
# traversing the stack. # traversing the stack.
@ -163,32 +160,3 @@ def extract_stack(limit=-1):
_source_filter_stacks[thread_key]) _source_filter_stacks[thread_key])
StackFrame = _tf_stack.StackFrame StackFrame = _tf_stack.StackFrame
def convert_stack(stack, include_func_start_lineno=False):
"""Converts a stack extracted using extract_stack() to a traceback stack.
Args:
stack: A sequence of StackFrame objects,
(filename, lineno, name, globals, func_start_lineno).
include_func_start_lineno: True if function start line number should be
included as the 5th entry in return tuples.
Returns:
A tuple of n 4-tuples or 5-tuples
(filename, lineno, name, code, [optional: func_start_lineno]), where the
code tuple element is calculated from the corresponding elements of the
input tuple.
"""
def _tuple_generator(): # pylint: disable=missing-docstring
for frame in stack:
filename = frame.filename
lineno = frame.lineno
name = frame.name
line = frame.line
if include_func_start_lineno:
yield (filename, lineno, name, line, frame.func_start_lineno)
else:
yield (filename, lineno, name, line)
return tuple(_tuple_generator())

View File

@ -36,7 +36,7 @@ class TFStackTest(test.TestCase):
def testConsistencyWithTraceback(self): def testConsistencyWithTraceback(self):
stack, expected_stack = extract_stack() stack, expected_stack = extract_stack()
for frame, expected in zip(stack, expected_stack): for frame, expected in zip(stack, expected_stack):
self.assertEqual(frame, expected) self.assertEqual(tuple(frame), expected)
def testFormatStack(self): def testFormatStack(self):
stack, expected_stack = extract_stack() stack, expected_stack = extract_stack()
@ -46,9 +46,8 @@ class TFStackTest(test.TestCase):
def extract_stack(limit=None): def extract_stack(limit=None):
convert = tf_stack.convert_stack
# Both defined on the same line to produce identical stacks. # Both defined on the same line to produce identical stacks.
return convert(tf_stack.extract_stack(limit)), traceback.extract_stack(limit) return tf_stack.extract_stack(limit), traceback.extract_stack(limit)
if __name__ == "__main__": if __name__ == "__main__":

View File

@ -38,10 +38,6 @@ tf_class {
name: "traceback" name: "traceback"
mtype: "<type \'property\'>" mtype: "<type \'property\'>"
} }
member {
name: "traceback_with_start_lines"
mtype: "<type \'property\'>"
}
member { member {
name: "type" name: "type"
mtype: "<type \'property\'>" mtype: "<type \'property\'>"

View File

@ -38,10 +38,6 @@ tf_class {
name: "traceback" name: "traceback"
mtype: "<type \'property\'>" mtype: "<type \'property\'>"
} }
member {
name: "traceback_with_start_lines"
mtype: "<type \'property\'>"
}
member { member {
name: "type" name: "type"
mtype: "<type \'property\'>" mtype: "<type \'property\'>"