Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/tensorflow/python/ops/summary_op_util.py: 34%
29 statements
« prev ^ index » next coverage.py v7.4.0, created at 2024-01-03 07:57 +0000
« prev ^ index » next coverage.py v7.4.0, created at 2024-01-03 07:57 +0000
1# Copyright 2017 The TensorFlow Authors. All Rights Reserved.
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14#==============================================================================
15"""Contains utility functions used by summary ops."""
17import contextlib
18import re
20from tensorflow.python.framework import ops
21from tensorflow.python.platform import tf_logging
24def collect(val, collections, default_collections):
25 """Adds keys to a collection.
27 Args:
28 val: The value to add per each key.
29 collections: A collection of keys to add.
30 default_collections: Used if collections is None.
31 """
32 if collections is None:
33 collections = default_collections
34 for key in collections:
35 ops.add_to_collection(key, val)
38_INVALID_TAG_CHARACTERS = re.compile(r'[^-/\w\.]')
41def clean_tag(name):
42 """Cleans a tag. Removes illegal characters for instance.
44 Args:
45 name: The original tag name to be processed.
47 Returns:
48 The cleaned tag name.
49 """
50 # In the past, the first argument to summary ops was a tag, which allowed
51 # arbitrary characters. Now we are changing the first argument to be the node
52 # name. This has a number of advantages (users of summary ops now can
53 # take advantage of the tf name scope system) but risks breaking existing
54 # usage, because a much smaller set of characters are allowed in node names.
55 # This function replaces all illegal characters with _s, and logs a warning.
56 # It also strips leading slashes from the name.
57 if name is not None:
58 new_name = _INVALID_TAG_CHARACTERS.sub('_', name)
59 new_name = new_name.lstrip('/') # Remove leading slashes
60 if new_name != name:
61 tf_logging.info('Summary name %s is illegal; using %s instead.' %
62 (name, new_name))
63 name = new_name
64 return name
67@contextlib.contextmanager
68def summary_scope(name, family=None, default_name=None, values=None):
69 """Enters a scope used for the summary and yields both the name and tag.
71 To ensure that the summary tag name is always unique, we create a name scope
72 based on `name` and use the full scope name in the tag.
74 If `family` is set, then the tag name will be '<family>/<scope_name>', where
75 `scope_name` is `<outer_scope>/<family>/<name>`. This ensures that `family`
76 is always the prefix of the tag (and unmodified), while ensuring the scope
77 respects the outer scope from this summary was created.
79 Args:
80 name: A name for the generated summary node.
81 family: Optional; if provided, used as the prefix of the summary tag name.
82 default_name: Optional; if provided, used as default name of the summary.
83 values: Optional; passed as `values` parameter to name_scope.
85 Yields:
86 A tuple `(tag, scope)`, both of which are unique and should be used for the
87 tag and the scope for the summary to output.
88 """
89 name = clean_tag(name)
90 family = clean_tag(family)
91 # Use family name in the scope to ensure uniqueness of scope/tag.
92 scope_base_name = name if family is None else '{}/{}'.format(family, name)
93 with ops.name_scope(
94 scope_base_name, default_name, values, skip_on_eager=False) as scope:
95 if family is None:
96 tag = scope.rstrip('/')
97 else:
98 # Prefix our scope with family again so it displays in the right tab.
99 tag = '{}/{}'.format(family, scope.rstrip('/'))
100 # Note: tag is not 100% unique if the user explicitly enters a scope with
101 # the same name as family, then later enter it again before summaries.
102 # This is very contrived though, and we opt here to let it be a runtime
103 # exception if tags do indeed collide.
104 yield (tag, scope)