tensorbored 2.21.0rc1769983804__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (271) hide show
  1. tensorbored/__init__.py +112 -0
  2. tensorbored/_vendor/__init__.py +0 -0
  3. tensorbored/_vendor/bleach/__init__.py +125 -0
  4. tensorbored/_vendor/bleach/_vendor/__init__.py +0 -0
  5. tensorbored/_vendor/bleach/_vendor/html5lib/__init__.py +35 -0
  6. tensorbored/_vendor/bleach/_vendor/html5lib/_ihatexml.py +289 -0
  7. tensorbored/_vendor/bleach/_vendor/html5lib/_inputstream.py +918 -0
  8. tensorbored/_vendor/bleach/_vendor/html5lib/_tokenizer.py +1735 -0
  9. tensorbored/_vendor/bleach/_vendor/html5lib/_trie/__init__.py +5 -0
  10. tensorbored/_vendor/bleach/_vendor/html5lib/_trie/_base.py +40 -0
  11. tensorbored/_vendor/bleach/_vendor/html5lib/_trie/py.py +67 -0
  12. tensorbored/_vendor/bleach/_vendor/html5lib/_utils.py +159 -0
  13. tensorbored/_vendor/bleach/_vendor/html5lib/constants.py +2946 -0
  14. tensorbored/_vendor/bleach/_vendor/html5lib/filters/__init__.py +0 -0
  15. tensorbored/_vendor/bleach/_vendor/html5lib/filters/alphabeticalattributes.py +29 -0
  16. tensorbored/_vendor/bleach/_vendor/html5lib/filters/base.py +12 -0
  17. tensorbored/_vendor/bleach/_vendor/html5lib/filters/inject_meta_charset.py +73 -0
  18. tensorbored/_vendor/bleach/_vendor/html5lib/filters/lint.py +93 -0
  19. tensorbored/_vendor/bleach/_vendor/html5lib/filters/optionaltags.py +207 -0
  20. tensorbored/_vendor/bleach/_vendor/html5lib/filters/sanitizer.py +916 -0
  21. tensorbored/_vendor/bleach/_vendor/html5lib/filters/whitespace.py +38 -0
  22. tensorbored/_vendor/bleach/_vendor/html5lib/html5parser.py +2795 -0
  23. tensorbored/_vendor/bleach/_vendor/html5lib/serializer.py +409 -0
  24. tensorbored/_vendor/bleach/_vendor/html5lib/treeadapters/__init__.py +30 -0
  25. tensorbored/_vendor/bleach/_vendor/html5lib/treeadapters/genshi.py +54 -0
  26. tensorbored/_vendor/bleach/_vendor/html5lib/treeadapters/sax.py +50 -0
  27. tensorbored/_vendor/bleach/_vendor/html5lib/treebuilders/__init__.py +88 -0
  28. tensorbored/_vendor/bleach/_vendor/html5lib/treebuilders/base.py +417 -0
  29. tensorbored/_vendor/bleach/_vendor/html5lib/treebuilders/dom.py +239 -0
  30. tensorbored/_vendor/bleach/_vendor/html5lib/treebuilders/etree.py +343 -0
  31. tensorbored/_vendor/bleach/_vendor/html5lib/treebuilders/etree_lxml.py +392 -0
  32. tensorbored/_vendor/bleach/_vendor/html5lib/treewalkers/__init__.py +154 -0
  33. tensorbored/_vendor/bleach/_vendor/html5lib/treewalkers/base.py +252 -0
  34. tensorbored/_vendor/bleach/_vendor/html5lib/treewalkers/dom.py +43 -0
  35. tensorbored/_vendor/bleach/_vendor/html5lib/treewalkers/etree.py +131 -0
  36. tensorbored/_vendor/bleach/_vendor/html5lib/treewalkers/etree_lxml.py +215 -0
  37. tensorbored/_vendor/bleach/_vendor/html5lib/treewalkers/genshi.py +69 -0
  38. tensorbored/_vendor/bleach/_vendor/parse.py +1078 -0
  39. tensorbored/_vendor/bleach/callbacks.py +32 -0
  40. tensorbored/_vendor/bleach/html5lib_shim.py +757 -0
  41. tensorbored/_vendor/bleach/linkifier.py +633 -0
  42. tensorbored/_vendor/bleach/parse_shim.py +1 -0
  43. tensorbored/_vendor/bleach/sanitizer.py +638 -0
  44. tensorbored/_vendor/bleach/six_shim.py +19 -0
  45. tensorbored/_vendor/webencodings/__init__.py +342 -0
  46. tensorbored/_vendor/webencodings/labels.py +231 -0
  47. tensorbored/_vendor/webencodings/mklabels.py +59 -0
  48. tensorbored/_vendor/webencodings/x_user_defined.py +325 -0
  49. tensorbored/assets.py +36 -0
  50. tensorbored/auth.py +102 -0
  51. tensorbored/backend/__init__.py +0 -0
  52. tensorbored/backend/application.py +604 -0
  53. tensorbored/backend/auth_context_middleware.py +38 -0
  54. tensorbored/backend/client_feature_flags.py +113 -0
  55. tensorbored/backend/empty_path_redirect.py +46 -0
  56. tensorbored/backend/event_processing/__init__.py +0 -0
  57. tensorbored/backend/event_processing/data_ingester.py +276 -0
  58. tensorbored/backend/event_processing/data_provider.py +535 -0
  59. tensorbored/backend/event_processing/directory_loader.py +142 -0
  60. tensorbored/backend/event_processing/directory_watcher.py +272 -0
  61. tensorbored/backend/event_processing/event_accumulator.py +950 -0
  62. tensorbored/backend/event_processing/event_file_inspector.py +463 -0
  63. tensorbored/backend/event_processing/event_file_loader.py +292 -0
  64. tensorbored/backend/event_processing/event_multiplexer.py +521 -0
  65. tensorbored/backend/event_processing/event_util.py +68 -0
  66. tensorbored/backend/event_processing/io_wrapper.py +223 -0
  67. tensorbored/backend/event_processing/plugin_asset_util.py +104 -0
  68. tensorbored/backend/event_processing/plugin_event_accumulator.py +721 -0
  69. tensorbored/backend/event_processing/plugin_event_multiplexer.py +522 -0
  70. tensorbored/backend/event_processing/reservoir.py +266 -0
  71. tensorbored/backend/event_processing/tag_types.py +29 -0
  72. tensorbored/backend/experiment_id.py +71 -0
  73. tensorbored/backend/experimental_plugin.py +51 -0
  74. tensorbored/backend/http_util.py +263 -0
  75. tensorbored/backend/json_util.py +70 -0
  76. tensorbored/backend/path_prefix.py +67 -0
  77. tensorbored/backend/process_graph.py +74 -0
  78. tensorbored/backend/security_validator.py +202 -0
  79. tensorbored/compat/__init__.py +69 -0
  80. tensorbored/compat/proto/__init__.py +0 -0
  81. tensorbored/compat/proto/allocation_description_pb2.py +35 -0
  82. tensorbored/compat/proto/api_def_pb2.py +82 -0
  83. tensorbored/compat/proto/attr_value_pb2.py +80 -0
  84. tensorbored/compat/proto/cluster_pb2.py +58 -0
  85. tensorbored/compat/proto/config_pb2.py +271 -0
  86. tensorbored/compat/proto/coordination_config_pb2.py +45 -0
  87. tensorbored/compat/proto/cost_graph_pb2.py +87 -0
  88. tensorbored/compat/proto/cpp_shape_inference_pb2.py +70 -0
  89. tensorbored/compat/proto/debug_pb2.py +65 -0
  90. tensorbored/compat/proto/event_pb2.py +149 -0
  91. tensorbored/compat/proto/full_type_pb2.py +74 -0
  92. tensorbored/compat/proto/function_pb2.py +157 -0
  93. tensorbored/compat/proto/graph_debug_info_pb2.py +111 -0
  94. tensorbored/compat/proto/graph_pb2.py +41 -0
  95. tensorbored/compat/proto/histogram_pb2.py +39 -0
  96. tensorbored/compat/proto/meta_graph_pb2.py +254 -0
  97. tensorbored/compat/proto/node_def_pb2.py +61 -0
  98. tensorbored/compat/proto/op_def_pb2.py +81 -0
  99. tensorbored/compat/proto/resource_handle_pb2.py +48 -0
  100. tensorbored/compat/proto/rewriter_config_pb2.py +93 -0
  101. tensorbored/compat/proto/rpc_options_pb2.py +35 -0
  102. tensorbored/compat/proto/saved_object_graph_pb2.py +193 -0
  103. tensorbored/compat/proto/saver_pb2.py +38 -0
  104. tensorbored/compat/proto/step_stats_pb2.py +116 -0
  105. tensorbored/compat/proto/struct_pb2.py +144 -0
  106. tensorbored/compat/proto/summary_pb2.py +111 -0
  107. tensorbored/compat/proto/tensor_description_pb2.py +38 -0
  108. tensorbored/compat/proto/tensor_pb2.py +68 -0
  109. tensorbored/compat/proto/tensor_shape_pb2.py +46 -0
  110. tensorbored/compat/proto/tfprof_log_pb2.py +307 -0
  111. tensorbored/compat/proto/trackable_object_graph_pb2.py +90 -0
  112. tensorbored/compat/proto/types_pb2.py +105 -0
  113. tensorbored/compat/proto/variable_pb2.py +62 -0
  114. tensorbored/compat/proto/verifier_config_pb2.py +38 -0
  115. tensorbored/compat/proto/versions_pb2.py +35 -0
  116. tensorbored/compat/tensorflow_stub/__init__.py +38 -0
  117. tensorbored/compat/tensorflow_stub/app.py +124 -0
  118. tensorbored/compat/tensorflow_stub/compat/__init__.py +131 -0
  119. tensorbored/compat/tensorflow_stub/compat/v1/__init__.py +20 -0
  120. tensorbored/compat/tensorflow_stub/dtypes.py +692 -0
  121. tensorbored/compat/tensorflow_stub/error_codes.py +169 -0
  122. tensorbored/compat/tensorflow_stub/errors.py +507 -0
  123. tensorbored/compat/tensorflow_stub/flags.py +124 -0
  124. tensorbored/compat/tensorflow_stub/io/__init__.py +17 -0
  125. tensorbored/compat/tensorflow_stub/io/gfile.py +1011 -0
  126. tensorbored/compat/tensorflow_stub/pywrap_tensorflow.py +285 -0
  127. tensorbored/compat/tensorflow_stub/tensor_shape.py +1035 -0
  128. tensorbored/context.py +129 -0
  129. tensorbored/data/__init__.py +0 -0
  130. tensorbored/data/grpc_provider.py +365 -0
  131. tensorbored/data/ingester.py +46 -0
  132. tensorbored/data/proto/__init__.py +0 -0
  133. tensorbored/data/proto/data_provider_pb2.py +517 -0
  134. tensorbored/data/proto/data_provider_pb2_grpc.py +374 -0
  135. tensorbored/data/provider.py +1365 -0
  136. tensorbored/data/server_ingester.py +301 -0
  137. tensorbored/data_compat.py +159 -0
  138. tensorbored/dataclass_compat.py +224 -0
  139. tensorbored/default.py +124 -0
  140. tensorbored/errors.py +130 -0
  141. tensorbored/lazy.py +99 -0
  142. tensorbored/main.py +48 -0
  143. tensorbored/main_lib.py +62 -0
  144. tensorbored/manager.py +487 -0
  145. tensorbored/notebook.py +441 -0
  146. tensorbored/plugin_util.py +266 -0
  147. tensorbored/plugins/__init__.py +0 -0
  148. tensorbored/plugins/audio/__init__.py +0 -0
  149. tensorbored/plugins/audio/audio_plugin.py +229 -0
  150. tensorbored/plugins/audio/metadata.py +69 -0
  151. tensorbored/plugins/audio/plugin_data_pb2.py +37 -0
  152. tensorbored/plugins/audio/summary.py +230 -0
  153. tensorbored/plugins/audio/summary_v2.py +124 -0
  154. tensorbored/plugins/base_plugin.py +367 -0
  155. tensorbored/plugins/core/__init__.py +0 -0
  156. tensorbored/plugins/core/core_plugin.py +981 -0
  157. tensorbored/plugins/custom_scalar/__init__.py +0 -0
  158. tensorbored/plugins/custom_scalar/custom_scalars_plugin.py +320 -0
  159. tensorbored/plugins/custom_scalar/layout_pb2.py +85 -0
  160. tensorbored/plugins/custom_scalar/metadata.py +35 -0
  161. tensorbored/plugins/custom_scalar/summary.py +79 -0
  162. tensorbored/plugins/debugger_v2/__init__.py +0 -0
  163. tensorbored/plugins/debugger_v2/debug_data_multiplexer.py +631 -0
  164. tensorbored/plugins/debugger_v2/debug_data_provider.py +634 -0
  165. tensorbored/plugins/debugger_v2/debugger_v2_plugin.py +504 -0
  166. tensorbored/plugins/distribution/__init__.py +0 -0
  167. tensorbored/plugins/distribution/compressor.py +158 -0
  168. tensorbored/plugins/distribution/distributions_plugin.py +116 -0
  169. tensorbored/plugins/distribution/metadata.py +19 -0
  170. tensorbored/plugins/graph/__init__.py +0 -0
  171. tensorbored/plugins/graph/graph_util.py +129 -0
  172. tensorbored/plugins/graph/graphs_plugin.py +336 -0
  173. tensorbored/plugins/graph/keras_util.py +328 -0
  174. tensorbored/plugins/graph/metadata.py +42 -0
  175. tensorbored/plugins/histogram/__init__.py +0 -0
  176. tensorbored/plugins/histogram/histograms_plugin.py +144 -0
  177. tensorbored/plugins/histogram/metadata.py +63 -0
  178. tensorbored/plugins/histogram/plugin_data_pb2.py +34 -0
  179. tensorbored/plugins/histogram/summary.py +234 -0
  180. tensorbored/plugins/histogram/summary_v2.py +292 -0
  181. tensorbored/plugins/hparams/__init__.py +14 -0
  182. tensorbored/plugins/hparams/_keras.py +93 -0
  183. tensorbored/plugins/hparams/api.py +130 -0
  184. tensorbored/plugins/hparams/api_pb2.py +208 -0
  185. tensorbored/plugins/hparams/backend_context.py +606 -0
  186. tensorbored/plugins/hparams/download_data.py +158 -0
  187. tensorbored/plugins/hparams/error.py +26 -0
  188. tensorbored/plugins/hparams/get_experiment.py +71 -0
  189. tensorbored/plugins/hparams/hparams_plugin.py +206 -0
  190. tensorbored/plugins/hparams/hparams_util_pb2.py +69 -0
  191. tensorbored/plugins/hparams/json_format_compat.py +38 -0
  192. tensorbored/plugins/hparams/list_metric_evals.py +57 -0
  193. tensorbored/plugins/hparams/list_session_groups.py +1040 -0
  194. tensorbored/plugins/hparams/metadata.py +125 -0
  195. tensorbored/plugins/hparams/metrics.py +41 -0
  196. tensorbored/plugins/hparams/plugin_data_pb2.py +69 -0
  197. tensorbored/plugins/hparams/summary.py +205 -0
  198. tensorbored/plugins/hparams/summary_v2.py +597 -0
  199. tensorbored/plugins/image/__init__.py +0 -0
  200. tensorbored/plugins/image/images_plugin.py +232 -0
  201. tensorbored/plugins/image/metadata.py +65 -0
  202. tensorbored/plugins/image/plugin_data_pb2.py +34 -0
  203. tensorbored/plugins/image/summary.py +159 -0
  204. tensorbored/plugins/image/summary_v2.py +130 -0
  205. tensorbored/plugins/mesh/__init__.py +14 -0
  206. tensorbored/plugins/mesh/mesh_plugin.py +292 -0
  207. tensorbored/plugins/mesh/metadata.py +152 -0
  208. tensorbored/plugins/mesh/plugin_data_pb2.py +37 -0
  209. tensorbored/plugins/mesh/summary.py +251 -0
  210. tensorbored/plugins/mesh/summary_v2.py +214 -0
  211. tensorbored/plugins/metrics/__init__.py +0 -0
  212. tensorbored/plugins/metrics/metadata.py +17 -0
  213. tensorbored/plugins/metrics/metrics_plugin.py +623 -0
  214. tensorbored/plugins/pr_curve/__init__.py +0 -0
  215. tensorbored/plugins/pr_curve/metadata.py +75 -0
  216. tensorbored/plugins/pr_curve/plugin_data_pb2.py +34 -0
  217. tensorbored/plugins/pr_curve/pr_curves_plugin.py +241 -0
  218. tensorbored/plugins/pr_curve/summary.py +574 -0
  219. tensorbored/plugins/profile_redirect/__init__.py +0 -0
  220. tensorbored/plugins/profile_redirect/profile_redirect_plugin.py +49 -0
  221. tensorbored/plugins/projector/__init__.py +67 -0
  222. tensorbored/plugins/projector/metadata.py +26 -0
  223. tensorbored/plugins/projector/projector_config_pb2.py +54 -0
  224. tensorbored/plugins/projector/projector_plugin.py +795 -0
  225. tensorbored/plugins/projector/tf_projector_plugin/index.js +32 -0
  226. tensorbored/plugins/projector/tf_projector_plugin/projector_binary.html +524 -0
  227. tensorbored/plugins/projector/tf_projector_plugin/projector_binary.js +15536 -0
  228. tensorbored/plugins/scalar/__init__.py +0 -0
  229. tensorbored/plugins/scalar/metadata.py +60 -0
  230. tensorbored/plugins/scalar/plugin_data_pb2.py +34 -0
  231. tensorbored/plugins/scalar/scalars_plugin.py +181 -0
  232. tensorbored/plugins/scalar/summary.py +109 -0
  233. tensorbored/plugins/scalar/summary_v2.py +124 -0
  234. tensorbored/plugins/text/__init__.py +0 -0
  235. tensorbored/plugins/text/metadata.py +62 -0
  236. tensorbored/plugins/text/plugin_data_pb2.py +34 -0
  237. tensorbored/plugins/text/summary.py +114 -0
  238. tensorbored/plugins/text/summary_v2.py +124 -0
  239. tensorbored/plugins/text/text_plugin.py +288 -0
  240. tensorbored/plugins/wit_redirect/__init__.py +0 -0
  241. tensorbored/plugins/wit_redirect/wit_redirect_plugin.py +49 -0
  242. tensorbored/program.py +910 -0
  243. tensorbored/summary/__init__.py +35 -0
  244. tensorbored/summary/_output.py +124 -0
  245. tensorbored/summary/_tf/__init__.py +14 -0
  246. tensorbored/summary/_tf/summary/__init__.py +178 -0
  247. tensorbored/summary/_writer.py +105 -0
  248. tensorbored/summary/v1.py +51 -0
  249. tensorbored/summary/v2.py +25 -0
  250. tensorbored/summary/writer/__init__.py +13 -0
  251. tensorbored/summary/writer/event_file_writer.py +291 -0
  252. tensorbored/summary/writer/record_writer.py +50 -0
  253. tensorbored/util/__init__.py +0 -0
  254. tensorbored/util/encoder.py +116 -0
  255. tensorbored/util/grpc_util.py +311 -0
  256. tensorbored/util/img_mime_type_detector.py +40 -0
  257. tensorbored/util/io_util.py +20 -0
  258. tensorbored/util/lazy_tensor_creator.py +110 -0
  259. tensorbored/util/op_evaluator.py +104 -0
  260. tensorbored/util/platform_util.py +20 -0
  261. tensorbored/util/tb_logging.py +24 -0
  262. tensorbored/util/tensor_util.py +617 -0
  263. tensorbored/util/timing.py +122 -0
  264. tensorbored/version.py +21 -0
  265. tensorbored/webfiles.zip +0 -0
  266. tensorbored-2.21.0rc1769983804.dist-info/METADATA +49 -0
  267. tensorbored-2.21.0rc1769983804.dist-info/RECORD +271 -0
  268. tensorbored-2.21.0rc1769983804.dist-info/WHEEL +5 -0
  269. tensorbored-2.21.0rc1769983804.dist-info/entry_points.txt +6 -0
  270. tensorbored-2.21.0rc1769983804.dist-info/licenses/LICENSE +739 -0
  271. tensorbored-2.21.0rc1769983804.dist-info/top_level.txt +1 -0
@@ -0,0 +1,114 @@
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
+ """Text summaries and TensorFlow operations to create them."""
16
+
17
+ from tensorbored.plugins.text import metadata
18
+ from tensorbored.plugins.text import summary_v2
19
+
20
+ # Export V2 versions.
21
+ text = summary_v2.text
22
+ text_pb = summary_v2.text_pb
23
+
24
+
25
+ def op(name, data, display_name=None, description=None, collections=None):
26
+ """Create a legacy text summary op.
27
+
28
+ Text data summarized via this plugin will be visible in the Text Dashboard
29
+ in TensorBoard. The standard TensorBoard Text Dashboard will render markdown
30
+ in the strings, and will automatically organize 1D and 2D tensors into tables.
31
+ If a tensor with more than 2 dimensions is provided, a 2D subarray will be
32
+ displayed along with a warning message. (Note that this behavior is not
33
+ intrinsic to the text summary API, but rather to the default TensorBoard text
34
+ plugin.)
35
+
36
+ Args:
37
+ name: A name for the generated node. Will also serve as a series name in
38
+ TensorBoard.
39
+ data: A string-type Tensor to summarize. The text must be encoded in UTF-8.
40
+ display_name: Optional name for this summary in TensorBoard, as a
41
+ constant `str`. Defaults to `name`.
42
+ description: Optional long-form description for this summary, as a
43
+ constant `str`. Markdown is supported. Defaults to empty.
44
+ collections: Optional list of ops.GraphKeys. The collections to which to add
45
+ the summary. Defaults to [Graph Keys.SUMMARIES].
46
+
47
+ Returns:
48
+ A TensorSummary op that is configured so that TensorBoard will recognize
49
+ that it contains textual data. The TensorSummary is a scalar `Tensor` of
50
+ type `string` which contains `Summary` protobufs.
51
+
52
+ Raises:
53
+ ValueError: If tensor has the wrong type.
54
+ """
55
+ # TODO(nickfelt): remove on-demand imports once dep situation is fixed.
56
+ import tensorflow.compat.v1 as tf
57
+
58
+ if display_name is None:
59
+ display_name = name
60
+ summary_metadata = metadata.create_summary_metadata(
61
+ display_name=display_name, description=description
62
+ )
63
+ with tf.name_scope(name):
64
+ with tf.control_dependencies([tf.assert_type(data, tf.string)]):
65
+ return tf.summary.tensor_summary(
66
+ name="text_summary",
67
+ tensor=data,
68
+ collections=collections,
69
+ summary_metadata=summary_metadata,
70
+ )
71
+
72
+
73
+ def pb(name, data, display_name=None, description=None):
74
+ """Create a legacy text summary protobuf.
75
+
76
+ Arguments:
77
+ name: A name for the generated node. Will also serve as a series name in
78
+ TensorBoard.
79
+ data: A Python bytestring (of type bytes), or Unicode string. Or a numpy
80
+ data array of those types.
81
+ display_name: Optional name for this summary in TensorBoard, as a
82
+ `str`. Defaults to `name`.
83
+ description: Optional long-form description for this summary, as a
84
+ `str`. Markdown is supported. Defaults to empty.
85
+
86
+ Raises:
87
+ ValueError: If the type of the data is unsupported.
88
+
89
+ Returns:
90
+ A `tf.Summary` protobuf object.
91
+ """
92
+ # TODO(nickfelt): remove on-demand imports once dep situation is fixed.
93
+ import tensorflow.compat.v1 as tf
94
+
95
+ try:
96
+ tensor = tf.make_tensor_proto(data, dtype=tf.string)
97
+ except TypeError as e:
98
+ raise ValueError(e)
99
+
100
+ if display_name is None:
101
+ display_name = name
102
+ summary_metadata = metadata.create_summary_metadata(
103
+ display_name=display_name, description=description
104
+ )
105
+ tf_summary_metadata = tf.SummaryMetadata.FromString(
106
+ summary_metadata.SerializeToString()
107
+ )
108
+ summary = tf.Summary()
109
+ summary.value.add(
110
+ tag="%s/text_summary" % name,
111
+ metadata=tf_summary_metadata,
112
+ tensor=tensor,
113
+ )
114
+ return summary
@@ -0,0 +1,124 @@
1
+ # Copyright 2018 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
+ """Text summaries and TensorFlow operations to create them, V2 versions."""
16
+
17
+ import numpy as np
18
+
19
+ from tensorbored.compat import tf2 as tf
20
+ from tensorbored.compat.proto import summary_pb2
21
+ from tensorbored.plugins.text import metadata
22
+ from tensorbored.util import tensor_util
23
+
24
+
25
+ def text(name, data, step=None, description=None):
26
+ r"""Write a text summary.
27
+
28
+ See also `tf.summary.scalar`, `tf.summary.SummaryWriter`, `tf.summary.image`.
29
+
30
+ Writes text Tensor values for later visualization and analysis in TensorBoard.
31
+ Writes go to the current default summary writer. Like `tf.summary.scalar`
32
+ points, text points are each associated with a `step` and a `name`.
33
+ All the points with the same `name` constitute a time series of text values.
34
+
35
+ For Example:
36
+ ```python
37
+ test_summary_writer = tf.summary.create_file_writer('test/logdir')
38
+ with test_summary_writer.as_default():
39
+ tf.summary.text('first_text', 'hello world!', step=0)
40
+ tf.summary.text('first_text', 'nice to meet you!', step=1)
41
+ ```
42
+
43
+ The text summary can also contain Markdown, and TensorBoard will render the text
44
+ as such.
45
+
46
+ ```python
47
+ with test_summary_writer.as_default():
48
+ text_data = '''
49
+ | *hello* | *there* |
50
+ |---------|---------|
51
+ | this | is |
52
+ | a | table |
53
+ '''
54
+ text_data = '\n'.join(l.strip() for l in text_data.splitlines())
55
+ tf.summary.text('markdown_text', text_data, step=0)
56
+ ```
57
+
58
+ Since text is Tensor valued, each text point may be a Tensor of string values.
59
+ rank-1 and rank-2 Tensors are rendered as tables in TensorBoard. For higher ranked
60
+ Tensors, you'll see just a 2D slice of the data. To avoid this, reshape the Tensor
61
+ to at most rank-2 prior to passing it to this function.
62
+
63
+ Demo notebook at
64
+ ["Displaying text data in TensorBoard"](https://www.tensorflow.org/tensorboard/text_summaries).
65
+
66
+ Arguments:
67
+ name: A name for this summary. The summary tag used for TensorBoard will
68
+ be this name prefixed by any active name scopes.
69
+ data: A UTF-8 string Tensor value.
70
+ step: Explicit `int64`-castable monotonic step value for this summary. If
71
+ omitted, this defaults to `tf.summary.experimental.get_step()`, which must
72
+ not be None.
73
+ description: Optional long-form description for this summary, as a
74
+ constant `str`. Markdown is supported. Defaults to empty.
75
+
76
+ Returns:
77
+ True on success, or false if no summary was emitted because no default
78
+ summary writer was available.
79
+
80
+ Raises:
81
+ ValueError: if a default writer exists, but no step was provided and
82
+ `tf.summary.experimental.get_step()` is None.
83
+ """
84
+ summary_metadata = metadata.create_summary_metadata(
85
+ display_name=None, description=description
86
+ )
87
+ # TODO(https://github.com/tensorflow/tensorboard/issues/2109): remove fallback
88
+ summary_scope = (
89
+ getattr(tf.summary.experimental, "summary_scope", None)
90
+ or tf.summary.summary_scope
91
+ )
92
+ with summary_scope(name, "text_summary", values=[data, step]) as (tag, _):
93
+ tf.debugging.assert_type(data, tf.string)
94
+ return tf.summary.write(
95
+ tag=tag, tensor=data, step=step, metadata=summary_metadata
96
+ )
97
+
98
+
99
+ def text_pb(tag, data, description=None):
100
+ """Create a text tf.Summary protobuf.
101
+
102
+ Arguments:
103
+ tag: String tag for the summary.
104
+ data: A Python bytestring (of type bytes), a Unicode string, or a numpy data
105
+ array of those types.
106
+ description: Optional long-form description for this summary, as a `str`.
107
+ Markdown is supported. Defaults to empty.
108
+
109
+ Raises:
110
+ TypeError: If the type of the data is unsupported.
111
+
112
+ Returns:
113
+ A `tf.Summary` protobuf object.
114
+ """
115
+ try:
116
+ tensor = tensor_util.make_tensor_proto(data, dtype=np.object_)
117
+ except TypeError as e:
118
+ raise TypeError("tensor must be of type string", e)
119
+ summary_metadata = metadata.create_summary_metadata(
120
+ display_name=None, description=description
121
+ )
122
+ summary = summary_pb2.Summary()
123
+ summary.value.add(tag=tag, metadata=summary_metadata, tensor=tensor)
124
+ return summary
@@ -0,0 +1,288 @@
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
+ """The TensorBoard Text plugin."""
16
+
17
+ import textwrap
18
+
19
+ # pylint: disable=g-bad-import-order
20
+ # Necessary for an internal test with special behavior for numpy.
21
+ import numpy as np
22
+
23
+ # pylint: enable=g-bad-import-order
24
+
25
+ from werkzeug import wrappers
26
+
27
+ from tensorbored import plugin_util
28
+ from tensorbored.backend import http_util
29
+ from tensorbored.data import provider
30
+ from tensorbored.plugins import base_plugin
31
+ from tensorbored.plugins.text import metadata
32
+
33
+ # HTTP routes
34
+ TAGS_ROUTE = "/tags"
35
+ TEXT_ROUTE = "/text"
36
+
37
+
38
+ WARNING_TEMPLATE = textwrap.dedent(
39
+ """\
40
+ **Warning:** This text summary contained data of dimensionality %d, but only \
41
+ 2d tables are supported. Showing a 2d slice of the data instead."""
42
+ )
43
+
44
+ _DEFAULT_DOWNSAMPLING = 100 # text tensors per time series
45
+
46
+
47
+ def make_table_row(contents, tag="td"):
48
+ """Given an iterable of string contents, make a table row.
49
+
50
+ Args:
51
+ contents: An iterable yielding strings.
52
+ tag: The tag to place contents in. Defaults to 'td', you might want 'th'.
53
+
54
+ Returns:
55
+ A string containing the content strings, organized into a table row.
56
+
57
+ Example: make_table_row(['one', 'two', 'three']) == '''
58
+ <tr>
59
+ <td>one</td>
60
+ <td>two</td>
61
+ <td>three</td>
62
+ </tr>'''
63
+ """
64
+ columns = ("<%s>%s</%s>\n" % (tag, s, tag) for s in contents)
65
+ return "<tr>\n" + "".join(columns) + "</tr>\n"
66
+
67
+
68
+ def make_table(contents, headers=None):
69
+ """Given a numpy ndarray of strings, concatenate them into a html table.
70
+
71
+ Args:
72
+ contents: A np.ndarray of strings. May be 1d or 2d. In the 1d case, the
73
+ table is laid out vertically (i.e. row-major).
74
+ headers: A np.ndarray or list of string header names for the table.
75
+
76
+ Returns:
77
+ A string containing all of the content strings, organized into a table.
78
+
79
+ Raises:
80
+ ValueError: If contents is not a np.ndarray.
81
+ ValueError: If contents is not 1d or 2d.
82
+ ValueError: If contents is empty.
83
+ ValueError: If headers is present and not a list, tuple, or ndarray.
84
+ ValueError: If headers is not 1d.
85
+ ValueError: If number of elements in headers does not correspond to number
86
+ of columns in contents.
87
+ """
88
+ if not isinstance(contents, np.ndarray):
89
+ raise ValueError("make_table contents must be a numpy ndarray")
90
+
91
+ if contents.ndim not in [1, 2]:
92
+ raise ValueError(
93
+ "make_table requires a 1d or 2d numpy array, was %dd"
94
+ % contents.ndim
95
+ )
96
+
97
+ if headers:
98
+ if isinstance(headers, (list, tuple)):
99
+ headers = np.array(headers)
100
+ if not isinstance(headers, np.ndarray):
101
+ raise ValueError(
102
+ "Could not convert headers %s into np.ndarray" % headers
103
+ )
104
+ if headers.ndim != 1:
105
+ raise ValueError("Headers must be 1d, is %dd" % headers.ndim)
106
+ expected_n_columns = contents.shape[1] if contents.ndim == 2 else 1
107
+ if headers.shape[0] != expected_n_columns:
108
+ raise ValueError(
109
+ "Number of headers %d must match number of columns %d"
110
+ % (headers.shape[0], expected_n_columns)
111
+ )
112
+ header = "<thead>\n%s</thead>\n" % make_table_row(headers, tag="th")
113
+ else:
114
+ header = ""
115
+
116
+ n_rows = contents.shape[0]
117
+ if contents.ndim == 1:
118
+ # If it's a vector, we need to wrap each element in a new list, otherwise
119
+ # we would turn the string itself into a row (see test code)
120
+ rows = (make_table_row([contents[i]]) for i in range(n_rows))
121
+ else:
122
+ rows = (make_table_row(contents[i, :]) for i in range(n_rows))
123
+
124
+ return "<table>\n%s<tbody>\n%s</tbody>\n</table>" % (header, "".join(rows))
125
+
126
+
127
+ def reduce_to_2d(arr):
128
+ """Given a np.npdarray with nDims > 2, reduce it to 2d.
129
+
130
+ It does this by selecting the zeroth coordinate for every dimension greater
131
+ than two.
132
+
133
+ Args:
134
+ arr: a numpy ndarray of dimension at least 2.
135
+
136
+ Returns:
137
+ A two-dimensional subarray from the input array.
138
+
139
+ Raises:
140
+ ValueError: If the argument is not a numpy ndarray, or the dimensionality
141
+ is too low.
142
+ """
143
+ if not isinstance(arr, np.ndarray):
144
+ raise ValueError("reduce_to_2d requires a numpy.ndarray")
145
+
146
+ ndims = len(arr.shape)
147
+ if ndims < 2:
148
+ raise ValueError("reduce_to_2d requires an array of dimensionality >=2")
149
+ # slice(None) is equivalent to `:`, so we take arr[0,0,...0,:,:]
150
+ slices = ([0] * (ndims - 2)) + [slice(None), slice(None)]
151
+ return arr[tuple(slices)]
152
+
153
+
154
+ def text_array_to_html(text_arr, enable_markdown):
155
+ """Take a numpy.ndarray containing strings, and convert it into html.
156
+
157
+ If the ndarray contains a single scalar string, that string is converted to
158
+ html via our sanitized markdown parser. If it contains an array of strings,
159
+ the strings are individually converted to html and then composed into a table
160
+ using make_table. If the array contains dimensionality greater than 2,
161
+ all but two of the dimensions are removed, and a warning message is prefixed
162
+ to the table.
163
+
164
+ Args:
165
+ text_arr: A numpy.ndarray containing strings.
166
+ enable_markdown: boolean, whether to enable Markdown
167
+
168
+ Returns:
169
+ The array converted to html.
170
+ """
171
+ if not text_arr.shape:
172
+ # It is a scalar. No need to put it in a table.
173
+ if enable_markdown:
174
+ return plugin_util.markdown_to_safe_html(text_arr.item())
175
+ else:
176
+ return plugin_util.safe_html(text_arr.item())
177
+ warning = ""
178
+ if len(text_arr.shape) > 2:
179
+ warning = plugin_util.markdown_to_safe_html(
180
+ WARNING_TEMPLATE % len(text_arr.shape)
181
+ )
182
+ text_arr = reduce_to_2d(text_arr)
183
+ if enable_markdown:
184
+ table = plugin_util.markdowns_to_safe_html(
185
+ text_arr.reshape(-1),
186
+ lambda xs: make_table(np.array(xs).reshape(text_arr.shape)),
187
+ )
188
+ else:
189
+ # Convert utf-8 bytes to str. The built-in np.char.decode doesn't work on
190
+ # object arrays, and converting to an numpy chararray is lossy.
191
+ decode = lambda bs: bs.decode("utf-8") if isinstance(bs, bytes) else bs
192
+ text_arr_str = np.array(
193
+ [decode(bs) for bs in text_arr.reshape(-1)]
194
+ ).reshape(text_arr.shape)
195
+ table = plugin_util.safe_html(make_table(text_arr_str))
196
+ return warning + table
197
+
198
+
199
+ def process_event(wall_time, step, string_ndarray, enable_markdown):
200
+ """Convert a text event into a JSON-compatible response."""
201
+ html = text_array_to_html(string_ndarray, enable_markdown)
202
+ return {
203
+ "wall_time": wall_time,
204
+ "step": step,
205
+ "text": html,
206
+ }
207
+
208
+
209
+ class TextPlugin(base_plugin.TBPlugin):
210
+ """Text Plugin for TensorBoard."""
211
+
212
+ plugin_name = metadata.PLUGIN_NAME
213
+
214
+ def __init__(self, context):
215
+ """Instantiates TextPlugin via TensorBoard core.
216
+
217
+ Args:
218
+ context: A base_plugin.TBContext instance.
219
+ """
220
+ self._downsample_to = (context.sampling_hints or {}).get(
221
+ self.plugin_name, _DEFAULT_DOWNSAMPLING
222
+ )
223
+ self._data_provider = context.data_provider
224
+ self._version_checker = plugin_util._MetadataVersionChecker(
225
+ data_kind="text",
226
+ latest_known_version=0,
227
+ )
228
+
229
+ def is_active(self):
230
+ return False # `list_plugins` as called by TB core suffices
231
+
232
+ def frontend_metadata(self):
233
+ return base_plugin.FrontendMetadata(element_name="tf-text-dashboard")
234
+
235
+ def index_impl(self, ctx, experiment):
236
+ mapping = self._data_provider.list_tensors(
237
+ ctx,
238
+ experiment_id=experiment,
239
+ plugin_name=metadata.PLUGIN_NAME,
240
+ )
241
+ result = {run: [] for run in mapping}
242
+ for run, tag_to_content in mapping.items():
243
+ for tag, metadatum in tag_to_content.items():
244
+ md = metadata.parse_plugin_metadata(metadatum.plugin_content)
245
+ if not self._version_checker.ok(md.version, run, tag):
246
+ continue
247
+ result[run].append(tag)
248
+ return result
249
+
250
+ @wrappers.Request.application
251
+ def tags_route(self, request):
252
+ ctx = plugin_util.context(request.environ)
253
+ experiment = plugin_util.experiment_id(request.environ)
254
+ index = self.index_impl(ctx, experiment)
255
+ return http_util.Respond(request, index, "application/json")
256
+
257
+ def text_impl(self, ctx, run, tag, experiment, enable_markdown):
258
+ all_text = self._data_provider.read_tensors(
259
+ ctx,
260
+ experiment_id=experiment,
261
+ plugin_name=metadata.PLUGIN_NAME,
262
+ downsample=self._downsample_to,
263
+ run_tag_filter=provider.RunTagFilter(runs=[run], tags=[tag]),
264
+ )
265
+ text = all_text.get(run, {}).get(tag, None)
266
+ if text is None:
267
+ return []
268
+ return [
269
+ process_event(d.wall_time, d.step, d.numpy, enable_markdown)
270
+ for d in text
271
+ ]
272
+
273
+ @wrappers.Request.application
274
+ def text_route(self, request):
275
+ ctx = plugin_util.context(request.environ)
276
+ experiment = plugin_util.experiment_id(request.environ)
277
+ run = request.args.get("run")
278
+ tag = request.args.get("tag")
279
+ markdown_arg = request.args.get("markdown")
280
+ enable_markdown = markdown_arg != "false" # Default to enabled.
281
+ response = self.text_impl(ctx, run, tag, experiment, enable_markdown)
282
+ return http_util.Respond(request, response, "application/json")
283
+
284
+ def get_plugin_apps(self):
285
+ return {
286
+ TAGS_ROUTE: self.tags_route,
287
+ TEXT_ROUTE: self.text_route,
288
+ }
File without changes
@@ -0,0 +1,49 @@
1
+ # Copyright 2020 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
+ """Plugin that only displays a message with installation instructions."""
16
+
17
+ from tensorbored.plugins import base_plugin
18
+
19
+
20
+ class WITRedirectPluginLoader(base_plugin.TBLoader):
21
+ """Load the redirect notice iff the dynamic plugin is unavailable."""
22
+
23
+ def load(self, context):
24
+ try:
25
+ import tensorboard_plugin_wit # noqa: F401
26
+
27
+ # If we successfully load the dynamic plugin, don't show
28
+ # this redirect plugin at all.
29
+ return None
30
+ except ImportError:
31
+ return _WITRedirectPlugin(context)
32
+
33
+
34
+ class _WITRedirectPlugin(base_plugin.TBPlugin):
35
+ """Redirect notice pointing users to the new dynamic LIT plugin."""
36
+
37
+ plugin_name = "wit_redirect"
38
+
39
+ def get_plugin_apps(self):
40
+ return {}
41
+
42
+ def is_active(self):
43
+ return False
44
+
45
+ def frontend_metadata(self):
46
+ return base_plugin.FrontendMetadata(
47
+ element_name="tf-wit-redirect-dashboard",
48
+ tab_name="What-If Tool",
49
+ )