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:
parent
804eb6e03f
commit
fd4ece49c9
tensorflow
python
debug/lib
framework
profiler
util
tools/api/golden
@ -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):
|
||||||
|
@ -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,
|
||||||
|
@ -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."""
|
||||||
|
@ -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")
|
||||||
|
@ -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):
|
||||||
|
@ -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:
|
||||||
|
@ -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) {
|
||||||
|
@ -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())
|
|
||||||
|
@ -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__":
|
||||||
|
@ -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\'>"
|
||||||
|
@ -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\'>"
|
||||||
|
Loading…
Reference in New Issue
Block a user