Files
tensorflow--tensorflow/tensorflow/python/summary/summary_v2_test.py
T
wehub-resource-sync 8a852e4b4e
cffconvert / validate (push) Has been skipped
License Check / license-check (push) Failing after 2s
chore: import upstream snapshot with attribution
2026-07-13 12:14:16 +08:00

312 lines
11 KiB
Python

# Copyright 2021 The TensorFlow Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ==============================================================================
"""Tests for the API surface of the V1 tf.summary ops when TF2 is enabled.
V1 summary ops will invoke V2 TensorBoard summary ops in eager mode.
"""
import unittest
from tensorflow.python.framework import constant_op
from tensorflow.python.framework import dtypes
from tensorflow.python.framework import ops
from tensorflow.python.framework import test_util
from tensorflow.python.ops import array_ops
from tensorflow.python.ops import summary_ops_v2
from tensorflow.python.platform import test
from tensorflow.python.summary import summary as summary_lib
from tensorflow.python.summary import tb_summary
from tensorflow.python.training import training_util
TENSORBOARD_AVAILABLE = (
hasattr(tb_summary, 'TENSORBOARD_AVAILABLE')
and tb_summary.TENSORBOARD_AVAILABLE
)
@unittest.skipIf(not TENSORBOARD_AVAILABLE, 'Tensorboard not installed.')
class SummaryV2Test(test.TestCase):
@test_util.run_v2_only
def test_scalar_summary_v2__w_writer(self):
"""Tests scalar v2 invocation with a v2 writer."""
with test.mock.patch.object(
tb_summary, 'scalar', autospec=True) as mock_scalar_v2:
with summary_ops_v2.create_summary_file_writer(
self.get_temp_dir()).as_default(step=1):
i = constant_op.constant(2.5)
tensor = summary_lib.scalar('float', i)
# Returns empty string.
self.assertEqual(tensor.numpy(), b'')
self.assertEqual(tensor.dtype, dtypes.string)
mock_scalar_v2.assert_called_once_with(name='float', data=i, step=1)
@test_util.run_v2_only
def test_scalar_summary_v2__wo_writer(self):
"""Tests scalar v2 invocation with no writer."""
with self.assertWarnsRegex(
UserWarning, 'default summary writer not found'):
with test.mock.patch.object(
tb_summary, 'scalar', autospec=True) as mock_scalar_v2:
summary_lib.scalar('float', constant_op.constant(2.5))
mock_scalar_v2.assert_not_called()
@test_util.run_v2_only
def test_scalar_summary_v2__global_step_not_set(self):
"""Tests scalar v2 invocation when global step is not set."""
with self.assertWarnsRegex(UserWarning, 'global step not set'):
with test.mock.patch.object(
tb_summary, 'scalar', autospec=True) as mock_scalar_v2:
with summary_ops_v2.create_summary_file_writer(
self.get_temp_dir()).as_default():
summary_lib.scalar('float', constant_op.constant(2.5))
mock_scalar_v2.assert_not_called()
@test_util.run_v2_only
def test_tf_summary_scalar_invalid_step_shapes_raise(self):
writer = summary_ops_v2.create_summary_file_writer(self.get_temp_dir())
invalid_steps = [
(), # empty tuple
[], # empty list
[1, 2], # non-scalar list
(1, 2), # non-scalar tuple
array_ops.ones((2,)), # rank-1 tensor
array_ops.ones((1, 1)), # rank-2 tensor
]
with writer.as_default(step=1):
for step in invalid_steps:
with self.assertRaises(ValueError):
summary_ops_v2.scalar('loss', 0.5, step=step)
@test_util.run_v2_only
def test_tf_summary_histogram_invalid_step_raises(self):
writer = summary_ops_v2.create_summary_file_writer(self.get_temp_dir())
with writer.as_default(step=1):
with self.assertRaises(ValueError):
summary_ops_v2.histogram(
'h',
array_ops.ones((10,)),
step=(),
)
@test_util.run_v2_only
def test_tf_summary_image_invalid_step_raises(self):
writer = summary_ops_v2.create_summary_file_writer(self.get_temp_dir())
image = array_ops.ones((1, 4, 4, 3))
with writer.as_default(step=1):
with self.assertRaises(ValueError):
summary_ops_v2.image(
'img',
image,
step=(),
)
@test_util.run_v2_only
def test_tf_summary_audio_invalid_step_raises(self):
writer = summary_ops_v2.create_summary_file_writer(self.get_temp_dir())
audio = array_ops.ones((1, 16000, 1))
with writer.as_default(step=1):
with self.assertRaises(ValueError):
summary_ops_v2.audio(
'audio',
audio,
sample_rate=16000,
max_outputs=1,
step=(),
)
@test_util.run_v2_only
def test_tf_summary_write_invalid_step_raises(self):
writer = summary_ops_v2.create_summary_file_writer(self.get_temp_dir())
with writer.as_default(step=1):
with self.assertRaises(ValueError):
summary_ops_v2.write(
tag='tag',
tensor=constant_op.constant(1.0),
step=(),
)
@test_util.run_v2_only
def test_tf_summary_trace_export_invalid_step_raises(self):
writer = summary_ops_v2.create_summary_file_writer(self.get_temp_dir())
with writer.as_default():
summary_ops_v2.trace_on(graph=True)
with self.assertRaises(ValueError):
summary_ops_v2.trace_export('trace', step=())
@test_util.run_v2_only
def test_scalar_summary_v2__family(self):
"""Tests `family` arg handling when scalar v2 is invoked."""
with test.mock.patch.object(
tb_summary, 'scalar', autospec=True) as mock_scalar_v2:
with summary_ops_v2.create_summary_file_writer(
self.get_temp_dir()).as_default(step=1):
tensor = summary_lib.scalar(
'float', constant_op.constant(2.5), family='otter')
# Returns empty string.
self.assertEqual(tensor.numpy(), b'')
self.assertEqual(tensor.dtype, dtypes.string)
mock_scalar_v2.assert_called_once_with(
name='otter/otter/float',
data=constant_op.constant(2.5),
step=1,
)
@test_util.run_v2_only
def test_scalar_summary_v2__family_w_outer_scope(self):
"""Tests `family` arg handling when there is an outer scope."""
with test.mock.patch.object(
tb_summary, 'scalar', autospec=True) as mock_scalar_v2:
with summary_ops_v2.create_summary_file_writer(
self.get_temp_dir()).as_default(step=1):
with ops.name_scope_v2('sea'):
tensor = summary_lib.scalar(
'float', constant_op.constant(3.5), family='crabnet')
# Returns empty string.
self.assertEqual(tensor.numpy(), b'')
self.assertEqual(tensor.dtype, dtypes.string)
mock_scalar_v2.assert_called_once_with(
name='crabnet/sea/crabnet/float',
data=constant_op.constant(3.5),
step=1,
)
@test_util.run_v2_only
def test_scalar_summary_v2__v1_set_step(self):
"""Tests scalar v2 invocation when v1 step is set."""
global_step = training_util.create_global_step()
global_step.assign(1024)
with test.mock.patch.object(
tb_summary, 'scalar', autospec=True) as mock_scalar_v2:
with summary_ops_v2.create_summary_file_writer(
self.get_temp_dir()).as_default():
i = constant_op.constant(2.5)
tensor = summary_lib.scalar('float', i)
# Returns empty string.
self.assertEqual(tensor.numpy(), b'')
self.assertEqual(tensor.dtype, dtypes.string)
mock_scalar_v2.assert_called_once_with(name='float', data=i, step=1024)
@test_util.run_v2_only
def test_image_summary_v2(self):
"""Tests image v2 invocation."""
with test.mock.patch.object(
tb_summary, 'image', autospec=True) as mock_image_v2:
with summary_ops_v2.create_summary_file_writer(
self.get_temp_dir()).as_default(step=2):
i = array_ops.ones((5, 4, 4, 3))
with ops.name_scope_v2('outer'):
tensor = summary_lib.image('image', i, max_outputs=3, family='family')
# Returns empty string.
self.assertEqual(tensor.numpy(), b'')
self.assertEqual(tensor.dtype, dtypes.string)
mock_image_v2.assert_called_once_with(
name='family/outer/family/image',
data=i,
step=2,
max_outputs=3,
)
@test_util.run_v2_only
def test_histogram_summary_v2(self):
"""Tests histogram v2 invocation."""
with test.mock.patch.object(
tb_summary, 'histogram', autospec=True) as mock_histogram_v2:
with summary_ops_v2.create_summary_file_writer(
self.get_temp_dir()).as_default(step=3):
i = array_ops.ones((1024,))
tensor = summary_lib.histogram('histogram', i, family='family')
# Returns empty string.
self.assertEqual(tensor.numpy(), b'')
self.assertEqual(tensor.dtype, dtypes.string)
mock_histogram_v2.assert_called_once_with(
name='family/family/histogram',
data=i,
step=3,
)
@test_util.run_v2_only
def test_audio_summary_v2(self):
"""Tests audio v2 invocation."""
with test.mock.patch.object(
tb_summary, 'audio', autospec=True) as mock_audio_v2:
with summary_ops_v2.create_summary_file_writer(
self.get_temp_dir()).as_default(step=10):
i = array_ops.ones((5, 3, 4))
with ops.name_scope_v2('dolphin'):
tensor = summary_lib.audio('wave', i, 0.2, max_outputs=3)
# Returns empty string.
self.assertEqual(tensor.numpy(), b'')
self.assertEqual(tensor.dtype, dtypes.string)
mock_audio_v2.assert_called_once_with(
name='dolphin/wave',
data=i,
sample_rate=0.2,
step=10,
max_outputs=3,
)
@test_util.run_v2_only
def test_audio_summary_v2__2d_tensor(self):
"""Tests audio v2 invocation with 2-D tensor input."""
with test.mock.patch.object(
tb_summary, 'audio', autospec=True) as mock_audio_v2:
with summary_ops_v2.create_summary_file_writer(
self.get_temp_dir()).as_default(step=11):
input_2d = array_ops.ones((5, 3))
tensor = summary_lib.audio('wave', input_2d, 0.2, max_outputs=3)
# Returns empty string.
self.assertEqual(tensor.numpy(), b'')
self.assertEqual(tensor.dtype, dtypes.string)
mock_audio_v2.assert_called_once_with(
name='wave',
data=test.mock.ANY,
sample_rate=0.2,
step=11,
max_outputs=3,
)
input_3d = array_ops.ones((5, 3, 1)) # 3-D input tensor
self.assertAllEqual(mock_audio_v2.call_args[1]['data'], input_3d)
@test_util.run_v2_only
def test_text_summary_v2(self):
"""Tests text v2 invocation."""
with test.mock.patch.object(
tb_summary, 'text', autospec=True) as mock_text_v2:
with summary_ops_v2.create_summary_file_writer(
self.get_temp_dir()).as_default(step=22):
i = constant_op.constant('lorem ipsum', dtype=dtypes.string)
tensor = summary_lib.text('text', i)
# Returns empty string.
self.assertEqual(tensor.numpy(), b'')
self.assertEqual(tensor.dtype, dtypes.string)
mock_text_v2.assert_called_once_with(name='text', data=i, step=22)
if __name__ == '__main__':
test.main()