def testPluginTagToContent_PluginsCannotJumpOnTheBandwagon(self): # If there are multiple `SummaryMetadata` for a given tag, and the # set of plugins in the `plugin_data` of second is different from # that of the first, then the second set should be ignored. logdir = self.get_temp_dir() summary_metadata_1 = summary_pb2.SummaryMetadata( display_name='current tagee', summary_description='no', plugin_data=[ summary_pb2.SummaryMetadata.PluginData(plugin_name='outlet', content='120v') ]) self._writeMetadata(logdir, summary_metadata_1, nonce='1') acc = ea.EventAccumulator(logdir) acc.Reload() summary_metadata_2 = summary_pb2.SummaryMetadata( display_name='tagee of the future', summary_description='definitely not', plugin_data=[ summary_pb2.SummaryMetadata.PluginData(plugin_name='plug', content='110v') ]) self._writeMetadata(logdir, summary_metadata_2, nonce='2') acc.Reload() self.assertEqual(acc.PluginTagToContent('outlet'), {'you_are_it': '120v'}) with six.assertRaisesRegex(self, KeyError, 'plug'): acc.PluginTagToContent('plug')
def ipu_compile_summary(name, op_list, collections=None): """Create an IPU compiler summary operation. Args: name: A name for the summary. op_list: An operation or list of operations to make this summary dependent upon. collections: Optional collections to add the summary into. Returns: The new summary operation """ if not isinstance(op_list, list): op_list = [op_list] with ops.device("cpu"): with ops.control_dependencies(op_list): reports = gen_ipu_ops.ipu_event_trace() summary_metadata = summary_pb2.SummaryMetadata( plugin_data=summary_pb2.SummaryMetadata.PluginData( plugin_name="ipu")) t_summary = tensor_summary(name='ipu_trace', tensor=reports, summary_metadata=summary_metadata, collections=collections, display_name=name) return t_summary
def run_metadata_graphs(name, data, step): """Writes graphs from a RunMetadata summary. Args: name: A name for this summary. The summary tag used for TensorBoard will be this name prefixed by any active name scopes. data: A RunMetadata proto to write. step: Required `int64`-castable monotonic step value. Returns: True on success, or false if no summary was written because no default summary writer was available. """ summary_metadata = summary_pb2.SummaryMetadata() # Hard coding a plugin name. Please refer to go/tb-plugin-name-hardcode for # the rationale. summary_metadata.plugin_data.plugin_name = "graph_run_metadata_graph" # version number = 1 summary_metadata.plugin_data.content = b"1" data = config_pb2.RunMetadata( function_graphs=data.function_graphs, partition_graphs=data.partition_graphs) with summary_scope(name, "graph_run_metadata_graph_summary", [data, step]) as (tag, _): return write( tag=tag, tensor=constant_op.constant( data.SerializeToString(), dtype=dtypes.string), step=step, metadata=summary_metadata)
def keras_model(name, data, step): """Writes a Keras model as JSON to as a Summary. Writing the Keras model configuration allows the TensorBoard graph plugin to render a conceptual graph, as opposed to graph of ops. Args: name: A name for this summary. The summary tag used for TensorBoard will be this name prefixed by any active name scopes. data: A Keras Model to write. step: Required `int64`-castable monotonic step value. Returns: True on success, or false if no summary was written because no default summary writer was available. """ summary_metadata = summary_pb2.SummaryMetadata() # Hard coding a plugin name. Please refer to go/tb-plugin-name-hardcode for # the rationale. summary_metadata.plugin_data.plugin_name = "graph_keras_model" # version number = 1 summary_metadata.plugin_data.content = b"1" json_string = data.to_json() with summary_scope(name, "graph_keras_model", [data, step]) as (tag, _): return write( tag=tag, tensor=constant_op.constant(json_string, dtype=dtypes.string), step=step, metadata=summary_metadata)
def after_create_session(self, session=None, coord=None): """Writes out Gin's operative config, and maybe adds a summary of it.""" config_str = config.operative_config_str() if not tf.gfile.IsDirectory(self._output_dir): tf.gfile.MakeDirs(self._output_dir) global_step_val = 0 if session is not None: global_step = tf.train.get_global_step() if global_step is not None: global_step_val = session.run(global_step) filename = '%s-%s.gin' % (self._base_name, global_step_val) config_path = os.path.join(self._output_dir, filename) with tf.gfile.GFile(config_path, 'w') as f: f.write(config_str) if self._summarize_config: md_config_str = self._markdownify_operative_config_str(config_str) summary_metadata = summary_pb2.SummaryMetadata() summary_metadata.plugin_data.plugin_name = 'text' summary_metadata.plugin_data.content = b'{}' text_tensor = tf.make_tensor_proto(md_config_str) summary = summary_pb2.Summary() summary.value.add(tag='gin/' + self._base_name, tensor=text_tensor, metadata=summary_metadata) if not self._summary_writer: # Creating the FileWriter also creates the events file, so it should be # done here (where it is most likely to only occur on chief workers), as # opposed to in the constructor. self._summary_writer = tf.summary.FileWriterCache.get( self._output_dir) self._summary_writer.add_summary(summary, global_step_val) self._summary_writer.flush()
def tensor_summary(name, tensor, summary_description=None, collections=None, summary_metadata=None, family=None, display_name=None): """Outputs a `Summary` protocol buffer with a serialized tensor.proto. Args: name: A name for the generated node. If display_name is not set, it will also serve as the tag name in TensorBoard. (In that case, the tag name will inherit tf name scopes.) tensor: A tensor of any type and shape to serialize. summary_description: A long description of the summary sequence. Markdown is supported. collections: Optional list of graph collections keys. The new summary op is added to these collections. Defaults to `[GraphKeys.SUMMARIES]`. summary_metadata: Optional SummaryMetadata proto (which describes which plugins may use the summary value). family: Optional; if provided, used as the prefix of the summary tag, which controls the name used for display on TensorBoard when display_name is not set. display_name: A string used to name this data in TensorBoard. If this is not set, then the node name will be used instead. Returns: A scalar `Tensor` of type `string`. The serialized `Summary` protocol buffer. """ if summary_metadata is None: summary_metadata = summary_pb2.SummaryMetadata() if summary_description is not None: summary_metadata.summary_description = summary_description if display_name is not None: summary_metadata.display_name = display_name serialized_summary_metadata = summary_metadata.SerializeToString() if summary_op_util.skip_summary(): return constant_op.constant("") with summary_op_util.summary_scope(name, family, values=[tensor]) as (tag, scope): val = gen_logging_ops.tensor_summary_v2( tensor=tensor, tag=tag, name=scope, serialized_summary_metadata=serialized_summary_metadata) summary_op_util.collect(val, collections, [ops.GraphKeys.SUMMARIES]) return val
def test_fully_populated_tensor(self): metadata = summary_pb2.SummaryMetadata() metadata.plugin_data.add(plugin_name='font_of_wisdom', content='adobe_garamond') op = summary_lib.tensor_summary( name='tensorpocalypse', tensor=constant_op.constant([[0.0, 2.0], [float('inf'), float('nan')]]), display_name='TENSORPOCALYPSE', summary_description='look on my works ye mighty and despair', summary_metadata=metadata) value = self._value_from_op(op) assert value.HasField('tensor'), value self._assert_noop(value)
def testSummaryMetadata(self): logdir = self.get_temp_dir() summary_metadata = summary_pb2.SummaryMetadata( display_name='current tagee', summary_description='no', plugin_data=[ summary_pb2.SummaryMetadata.PluginData(plugin_name='outlet') ]) self._writeMetadata(logdir, summary_metadata) acc = ea.EventAccumulator(logdir) acc.Reload() self.assertProtoEquals(summary_metadata, acc.SummaryMetadata('you_are_it'))
def testWrite_gpuDeviceContext(self): logdir = self.get_temp_dir() with context.eager_mode(): with summary_ops.create_file_writer(logdir).as_default(): with ops.device('/GPU:0'): value = constant_op.constant(42.0) step = constant_op.constant(12, dtype=dtypes.int64) summary_ops.write('tag', value, step=step).numpy() empty_metadata = summary_pb2.SummaryMetadata() events = events_from_logdir(logdir) self.assertEqual(2, len(events)) self.assertEqual(12, events[1].step) self.assertEqual(42, to_numpy(events[1].summary.value[0])) self.assertEqual(empty_metadata, events[1].summary.value[0].metadata)
def testSummaryDescriptionAndDisplayName(self): with self.cached_session() as sess: def get_description(summary_op): summ_str = self.evaluate(summary_op) summ = summary_pb2.Summary() summ.ParseFromString(summ_str) return summ.value[0].metadata const = constant_op.constant(1) # Default case; no description or display name simple_summary = summary_lib.tensor_summary("simple", const) descr = get_description(simple_summary) self.assertEqual(descr.display_name, "") self.assertEqual(descr.summary_description, "") # Values are provided via function args with_values = summary_lib.tensor_summary( "simple", const, display_name="my name", summary_description="my description") descr = get_description(with_values) self.assertEqual(descr.display_name, "my name") self.assertEqual(descr.summary_description, "my description") # Values are provided via the SummaryMetadata arg metadata = summary_pb2.SummaryMetadata() metadata.display_name = "my name" metadata.summary_description = "my description" with_metadata = summary_lib.tensor_summary( "simple", const, summary_metadata=metadata) descr = get_description(with_metadata) self.assertEqual(descr.display_name, "my name") self.assertEqual(descr.summary_description, "my description") # If both SummaryMetadata and explicit args are provided, the args win overwrite = summary_lib.tensor_summary( "simple", const, summary_metadata=metadata, display_name="overwritten", summary_description="overwritten") descr = get_description(overwrite) self.assertEqual(descr.display_name, "overwritten") self.assertEqual(descr.summary_description, "overwritten")
def testWrite_metadata(self): logdir = self.get_temp_dir() metadata = summary_pb2.SummaryMetadata() metadata.plugin_data.plugin_name = 'foo' with context.eager_mode(): with summary_ops.create_file_writer_v2(logdir).as_default(): summary_ops.write('obj', 0, 0, metadata=metadata) summary_ops.write('bytes', 0, 0, metadata=metadata.SerializeToString()) m = constant_op.constant(metadata.SerializeToString()) summary_ops.write('string_tensor', 0, 0, metadata=m) events = events_from_logdir(logdir) self.assertEqual(4, len(events)) self.assertEqual(metadata, events[1].summary.value[0].metadata) self.assertEqual(metadata, events[2].summary.value[0].metadata) self.assertEqual(metadata, events[3].summary.value[0].metadata)
def testSummaryMetadata_FirstMetadataWins(self): logdir = self.get_temp_dir() summary_metadata_1 = summary_pb2.SummaryMetadata( display_name='current tagee', summary_description='no', plugin_data=[ summary_pb2.SummaryMetadata.PluginData(plugin_name='outlet', content='120v') ]) self._writeMetadata(logdir, summary_metadata_1, nonce='1') acc = ea.EventAccumulator(logdir) acc.Reload() summary_metadata_2 = summary_pb2.SummaryMetadata( display_name='tagee of the future', summary_description='definitely not', plugin_data=[ summary_pb2.SummaryMetadata.PluginData(plugin_name='plug', content='110v') ]) self._writeMetadata(logdir, summary_metadata_2, nonce='2') acc.Reload() self.assertProtoEquals(summary_metadata_1, acc.SummaryMetadata('you_are_it'))
def ipu_compile_summary(name, op_list, collections=None): with ops.device("cpu"): with ops.control_dependencies(op_list): reports = gen_ipu_ops.ipu_event_trace() summary_metadata = summary_pb2.SummaryMetadata( plugin_data=summary_pb2.SummaryMetadata.PluginData( plugin_name="ipu")) t_summary = tensor_summary( name=name, tensor=reports, summary_metadata=summary_metadata, collections=collections) return t_summary
def keras_model(name, data, step=None): """Writes a Keras model as JSON to as a Summary. Writing the Keras model configuration allows the TensorBoard graph plugin to render a conceptual graph, as opposed to graph of ops. In case the model fails to serialze as JSON, it ignores and returns False. Args: name: A name for this summary. The summary tag used for TensorBoard will be this name prefixed by any active name scopes. data: A Keras Model to write. step: Explicit `int64`-castable monotonic step value for this summary. If omitted, this defaults to `tf.summary.experimental.get_step()`, which must not be None. Returns: True on success, or False if no summary was written because no default summary writer was available. Raises: ValueError: if a default writer exists, but no step was provided and `tf.summary.experimental.get_step()` is None. """ summary_metadata = summary_pb2.SummaryMetadata() # Hard coding a plugin name. Please refer to go/tb-plugin-name-hardcode for # the rationale. summary_metadata.plugin_data.plugin_name = "graph_keras_model" # version number = 1 summary_metadata.plugin_data.content = b"1" try: json_string = data.to_json() except Exception as exc: # pylint: disable=broad-except # An exception should not break a model code. logging.warn("Model failed to serialize as JSON. Ignoring... %s" % exc) return False with summary_scope(name, "graph_keras_model", [data, step]) as (tag, _): with ops.device("cpu:0"): tensor = constant_op.constant(json_string, dtype=dtypes.string) return write( tag=tag, tensor=tensor, step=step, metadata=summary_metadata)
def text_summary(name, tensor, collections=None): """Summarizes textual data. Text data summarized via this plugin will be visible in the Text Dashboard in TensorBoard. The standard TensorBoard Text Dashboard will render markdown in the strings, and will automatically organize 1d and 2d tensors into tables. If a tensor with more than 2 dimensions is provided, a 2d subarray will be displayed along with a warning message. (Note that this behavior is not intrinsic to the text summary api, but rather to the default TensorBoard text plugin.) Args: name: A name for the generated node. Will also serve as a series name in TensorBoard. tensor: a string-type Tensor to summarize. collections: Optional list of ops.GraphKeys. The collections to add the summary to. Defaults to [_ops.GraphKeys.SUMMARIES] Returns: A TensorSummary op that is configured so that TensorBoard will recognize that it contains textual data. The TensorSummary is a scalar `Tensor` of type `string` which contains `Summary` protobufs. Raises: ValueError: If tensor has the wrong type. """ if tensor.dtype != dtypes.string: raise ValueError("Expected tensor %s to have dtype string, got %s" % (tensor.name, tensor.dtype)) summary_metadata = summary_pb2.SummaryMetadata() text_plugin_data = _TextPluginData() data_dict = text_plugin_data._asdict() # pylint: disable=protected-access summary_metadata.plugin_data.add( plugin_name=PLUGIN_NAME, content=json.dumps(data_dict)) t_summary = tensor_summary( name=name, tensor=tensor, summary_metadata=summary_metadata, collections=collections) return t_summary
def run_metadata_graphs(name, data, step=None): """Writes graphs from a RunMetadata summary. Args: name: A name for this summary. The summary tag used for TensorBoard will be this name prefixed by any active name scopes. data: A RunMetadata proto to write. step: Explicit `int64`-castable monotonic step value for this summary. If omitted, this defaults to `tf.summary.experimental.get_step()`, which must not be None. Returns: True on success, or false if no summary was written because no default summary writer was available. Raises: ValueError: if a default writer exists, but no step was provided and `tf.summary.experimental.get_step()` is None. """ summary_metadata = summary_pb2.SummaryMetadata() # Hard coding a plugin name. Please refer to go/tb-plugin-name-hardcode for # the rationale. summary_metadata.plugin_data.plugin_name = "graph_run_metadata_graph" # version number = 1 summary_metadata.plugin_data.content = b"1" data = config_pb2.RunMetadata( function_graphs=data.function_graphs, partition_graphs=data.partition_graphs) with summary_scope(name, "graph_run_metadata_graph_summary", [data, step]) as (tag, _): with ops.device("cpu:0"): tensor = constant_op.constant(data.SerializeToString(), dtype=dtypes.string) return write( tag=tag, tensor=tensor, step=step, metadata=summary_metadata)
def keras_model(name, data, step=None): """Writes a Keras model as JSON to as a Summary. Writing the Keras model configuration allows the TensorBoard graph plugin to render a conceptual graph, as opposed to graph of ops. Args: name: A name for this summary. The summary tag used for TensorBoard will be this name prefixed by any active name scopes. data: A Keras Model to write. step: Explicit `int64`-castable monotonic step value for this summary. If omitted, this defaults to `tf.summary.experimental.get_step()`, which must not be None. Returns: True on success, or false if no summary was written because no default summary writer was available. Raises: ValueError: if a default writer exists, but no step was provided and `tf.summary.experimental.get_step()` is None. """ summary_metadata = summary_pb2.SummaryMetadata() # Hard coding a plugin name. Please refer to go/tb-plugin-name-hardcode for # the rationale. summary_metadata.plugin_data.plugin_name = "graph_keras_model" # version number = 1 summary_metadata.plugin_data.content = b"1" json_string = data.to_json() with summary_scope(name, "graph_keras_model", [data, step]) as (tag, _): return write(tag=tag, tensor=constant_op.constant(json_string, dtype=dtypes.string), step=step, metadata=summary_metadata)