Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/tensorboard/summary/_tf/summary/__init__.py: 100%

27 statements  

« prev     ^ index     » next       coverage.py v7.4.0, created at 2024-01-03 07:57 +0000

1# Copyright 2019 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 

16# NOTE: This module exists to provide the `tf.summary` module in the TensorFlow 

17# API using symbols defined in TensorBoard. This works via a mechanism within 

18# TensorFlow's API construction logic called "component_api_helper" that imports 

19# an arbitrary module and inserts it into the TF APIs as a "component API". That 

20# logic is specifically hardcoded to look for this exact tensorboard module. 

21# 

22# This note is in a comment, not the module docstring, because the module 

23# docstring below is what users will see as the tf.summary docstring and in the 

24# generated API documentation, and this is just an implementation detail. 

25 

26"""Operations for writing summary data, for use in analysis and visualization. 

27 

28The `tf.summary` module provides APIs for writing summary data. This data can be 

29visualized in TensorBoard, the visualization toolkit that comes with TensorFlow. 

30See the [TensorBoard website](https://www.tensorflow.org/tensorboard) for more 

31detailed tutorials about how to use these APIs, or some quick examples below. 

32 

33Example usage with eager execution, the default in TF 2.0: 

34 

35```python 

36writer = tf.summary.create_file_writer("/tmp/mylogs") 

37with writer.as_default(): 

38 for step in range(100): 

39 # other model code would go here 

40 tf.summary.scalar("my_metric", 0.5, step=step) 

41 writer.flush() 

42``` 

43 

44Example usage with `tf.function` graph execution: 

45 

46```python 

47writer = tf.summary.create_file_writer("/tmp/mylogs") 

48 

49@tf.function 

50def my_func(step): 

51 # other model code would go here 

52 with writer.as_default(): 

53 tf.summary.scalar("my_metric", 0.5, step=step) 

54 

55for step in range(100): 

56 my_func(step) 

57 writer.flush() 

58``` 

59 

60Example usage with legacy TF 1.x graph execution: 

61 

62```python 

63with tf.compat.v1.Graph().as_default(): 

64 step = tf.Variable(0, dtype=tf.int64) 

65 step_update = step.assign_add(1) 

66 writer = tf.summary.create_file_writer("/tmp/mylogs") 

67 with writer.as_default(): 

68 tf.summary.scalar("my_metric", 0.5, step=step) 

69 all_summary_ops = tf.compat.v1.summary.all_v2_summary_ops() 

70 writer_flush = writer.flush() 

71 

72 sess = tf.compat.v1.Session() 

73 sess.run([writer.init(), step.initializer]) 

74 for i in range(100): 

75 sess.run(all_summary_ops) 

76 sess.run(step_update) 

77 sess.run(writer_flush) 

78``` 

79""" 

80 

81 

82# Keep this import outside the function below for internal sync reasons. 

83import tensorflow as tf 

84 

85 

86def reexport_tf_summary(): 

87 """Re-export all symbols from the original tf.summary. 

88 

89 This function finds the original tf.summary V2 API and re-exports all the 

90 symbols from it within this module as well, so that when this module is 

91 patched into the TF API namespace as the new tf.summary, the effect is an 

92 overlay that just adds TensorBoard-provided symbols to the module. 

93 

94 Finding the original tf.summary V2 API module reliably is a challenge, since 

95 this code runs *during* the overall TF API import process and depending on 

96 the order of imports (which is subject to change), different parts of the API 

97 may or may not be defined at the point in time we attempt to access them. This 

98 code also may be inserted into two places in the API (tf and tf.compat.v2) 

99 and may be re-executed multiple times even for the same place in the API (due 

100 to the TF module import system not populating sys.modules properly), so it 

101 needs to be robust to many different scenarios. 

102 

103 The one constraint we can count on is that everywhere this module is loaded 

104 (via the component_api_helper mechanism in TF), it's going to be the 'summary' 

105 submodule of a larger API package that already has a 'summary' attribute 

106 that contains the TF-only summary API symbols we need to re-export. This 

107 may either be the original TF-only summary module (the first time we load 

108 this module) or a pre-existing copy of this module (if we're re-loading this 

109 module again). We don't actually need to differentiate those two cases, 

110 because it's okay if we re-import our own TensorBoard-provided symbols; they 

111 will just be overwritten later on in this file. 

112 

113 So given that guarantee, the approach we take is to first attempt to locate 

114 a TF V2 API package that already has a 'summary' attribute (most likely this 

115 is the parent package into which we're being imported, but not necessarily), 

116 and then do the dynamic version of "from tf_api_package.summary import *". 

117 

118 Lastly, this logic is encapsulated in a function to avoid symbol leakage. 

119 """ 

120 import sys 

121 

122 # API packages to check for the original V2 summary API, in preference order 

123 # to avoid going "under the hood" to the _api packages unless necessary. 

124 # Skip the top-level `tensorflow` package since it's hard to confirm that it 

125 # is the actual v2 API (just checking tf.__version__ is not always enough). 

126 packages = [ 

127 "tensorflow.compat.v2", 

128 "tensorflow_core._api.v2", 

129 "tensorflow_core._api.v2.compat.v2", 

130 "tensorflow_core._api.v1.compat.v2", 

131 # Old names for `tensorflow_core._api.*`. 

132 "tensorflow._api.v2", 

133 "tensorflow._api.v2.compat.v2", 

134 "tensorflow._api.v1.compat.v2", 

135 ] 

136 

137 def dynamic_wildcard_import(module): 

138 """Implements the logic of "from module import *" for the given 

139 module.""" 

140 symbols = getattr(module, "__all__", None) 

141 if symbols is None: 

142 symbols = [ 

143 k for k in module.__dict__.keys() if not k.startswith("_") 

144 ] 

145 globals().update( 

146 {symbol: getattr(module, symbol) for symbol in symbols} 

147 ) 

148 

149 notfound = object() # sentinel value 

150 for package_name in packages: 

151 package = sys.modules.get(package_name, notfound) 

152 if package is notfound: 

153 # Either it isn't in this installation at all (e.g. the _api.vX packages 

154 # are only in API version X), it isn't imported yet, or it was imported 

155 # but not inserted into sys.modules under its user-facing name (for the 

156 # non-'_api' packages), at which point we continue down the list to look 

157 # "under the hood" for it via its '_api' package name. 

158 continue 

159 module = getattr(package, "summary", None) 

160 if module is None: 

161 # This happens if the package hasn't been fully imported yet. For example, 

162 # the 'tensorflow' package won't yet have 'summary' attribute if we are 

163 # loading this code via the 'tensorflow.compat...' path and 'compat' is 

164 # imported before 'summary' in the 'tensorflow' __init__.py file. 

165 continue 

166 # Success, we hope. Import all the public symbols into this module. 

167 dynamic_wildcard_import(module) 

168 return 

169 

170 

171reexport_tf_summary() 

172 

173from tensorboard.summary.v2 import audio # noqa: F401 

174from tensorboard.summary.v2 import histogram # noqa: F401 

175from tensorboard.summary.v2 import image # noqa: F401 

176from tensorboard.summary.v2 import scalar # noqa: F401 

177from tensorboard.summary.v2 import text # noqa: F401 

178 

179del tf, reexport_tf_summary