[tfdbg] Load metadata in DebugDataReader

- This resolves a TODO item realted to DebugDataReader not reading the
  .metadata file in the file set.
- This is needed by the debugger_v2/runs route of in the DebuggerV2 work
  in TensorBoard.
- A unit test is added.

Also in this CL:
- Clean up some inadvertently left-over cruft in debug_events_reader.py.

PiperOrigin-RevId: 288046710
Change-Id: I663255f2822ffec9247823ac0099592af48ebac9
This commit is contained in:
Shanqing Cai 2020-01-03 14:07:57 -08:00 committed by TensorFlower Gardener
parent d6d4c5df84
commit e51a2086d5
2 changed files with 37 additions and 9 deletions

View File

@ -632,6 +632,8 @@ class DebugDataReader(object):
def __init__(self, dump_root): def __init__(self, dump_root):
self._reader = DebugEventsReader(dump_root) self._reader = DebugEventsReader(dump_root)
self._load_metadata()
# TODO(cais): Implement pagination for memory constraints. # TODO(cais): Implement pagination for memory constraints.
self._execution_digests = [] self._execution_digests = []
@ -651,15 +653,12 @@ class DebugDataReader(object):
# TODO(cais): Implement pagination for memory constraints. # TODO(cais): Implement pagination for memory constraints.
self._graph_execution_trace_digests = [] self._graph_execution_trace_digests = []
# The following timestamps keep track where we've reached in each def _load_metadata(self):
# file of the DebugEvent source file, so that we don't run into race metadata_iter = self._reader.metadata_iterator()
# conditions with the writer. debug_event = next(metadata_iter).debug_event
self._source_files_timestamp = 0 self._starting_wall_time = debug_event.wall_time
# Temporary object used to hold DebugEvent protos with stack_frames self._tensorflow_version = debug_event.debug_metadata.tensorflow_version
# field that has been read beyond max_wall_time.
# self._last_successful_stack_frames_offset = -1 # TODO(cais): Fix.
# TODO(cais): Read metadata.
def _load_source_files(self): def _load_source_files(self):
"""Incrementally read the .source_files DebugEvent file.""" """Incrementally read the .source_files DebugEvent file."""
source_files_iter = self._reader.source_files_iterator() source_files_iter = self._reader.source_files_iterator()
@ -667,7 +666,6 @@ class DebugDataReader(object):
source_file = debug_event.source_file source_file = debug_event.source_file
self._host_name_file_path_to_offset[ self._host_name_file_path_to_offset[
(source_file.host_name, source_file.file_path)] = offset (source_file.host_name, source_file.file_path)] = offset
self._source_file_timestamp = debug_event.wall_time
def _load_stack_frames(self): def _load_stack_frames(self):
"""Incrementally read the .stack_frames file. """Incrementally read the .stack_frames file.
@ -789,6 +787,25 @@ class DebugDataReader(object):
offset = self._host_name_file_path_to_offset[(host_name, file_path)] offset = self._host_name_file_path_to_offset[(host_name, file_path)]
return list(self._reader.read_source_files_event(offset).source_file.lines) return list(self._reader.read_source_files_event(offset).source_file.lines)
def starting_wall_time(self):
"""Wall timestamp for when the debugged TensorFlow program started.
Returns:
Stating wall time as seconds since the epoch, as a `float`.
"""
return self._starting_wall_time
def tensorflow_version(self):
"""TensorFlow version used in the debugged TensorFlow program.
Note: this is not necessarily the same as the version of TensorFlow used to
load the DebugEvent file set.
Returns:
TensorFlow version used by the debugged program, as a `str`.
"""
return self._tensorflow_version
def outermost_graphs(self): def outermost_graphs(self):
"""Get the number of outer most graphs read so far.""" """Get the number of outer most graphs read so far."""
return [graph for graph in self._graph_by_id.values() return [graph for graph in self._graph_by_id.values()

View File

@ -21,12 +21,14 @@ from __future__ import print_function
import glob import glob
import os import os
import threading import threading
import time
from tensorflow.core.protobuf import debug_event_pb2 from tensorflow.core.protobuf import debug_event_pb2
from tensorflow.python.debug.lib import debug_events_reader from tensorflow.python.debug.lib import debug_events_reader
from tensorflow.python.debug.lib import debug_events_writer from tensorflow.python.debug.lib import debug_events_writer
from tensorflow.python.debug.lib import dumping_callback_test_lib from tensorflow.python.debug.lib import dumping_callback_test_lib
from tensorflow.python.framework import ops from tensorflow.python.framework import ops
from tensorflow.python.framework import versions
from tensorflow.python.platform import googletest from tensorflow.python.platform import googletest
@ -192,6 +194,15 @@ class DebugEventsWriterTest(dumping_callback_test_lib.DumpingCallbackTestBase):
graph_op_names = sorted([actual.op_name for actual in actuals]) graph_op_names = sorted([actual.op_name for actual in actuals])
self.assertEqual(graph_op_names, ["Op0", "Op1", "Op2"]) self.assertEqual(graph_op_names, ["Op0", "Op1", "Op2"])
def testWriteAndReadMetadata(self):
t0 = time.time()
writer = debug_events_writer.DebugEventsWriter(self.dump_root)
writer.Close()
with debug_events_reader.DebugDataReader(self.dump_root) as reader:
self.assertIsInstance(reader.starting_wall_time(), float)
self.assertGreaterEqual(reader.starting_wall_time(), t0)
self.assertEqual(reader.tensorflow_version(), versions.__version__)
def testWriteExecutionEventsWithCircularBuffer(self): def testWriteExecutionEventsWithCircularBuffer(self):
writer = debug_events_writer.DebugEventsWriter(self.dump_root) writer = debug_events_writer.DebugEventsWriter(self.dump_root)
num_execution_events = debug_events_writer.DEFAULT_CIRCULAR_BUFFER_SIZE * 2 num_execution_events = debug_events_writer.DEFAULT_CIRCULAR_BUFFER_SIZE * 2