From 2d121a5e73db8891e3ed9d6ba450502bae06dd0a Mon Sep 17 00:00:00 2001 From: Jie-Wei Wu Date: Wed, 6 Oct 2021 21:49:40 -0700 Subject: [PATCH 1/9] wip --- .../tensorboard_plugin_example/plugin.py | 43 +++++++++++++------ 1 file changed, 30 insertions(+), 13 deletions(-) diff --git a/tensorboard/examples/plugins/example_basic/tensorboard_plugin_example/plugin.py b/tensorboard/examples/plugins/example_basic/tensorboard_plugin_example/plugin.py index 1f2dfcfeab..aa6caa2350 100644 --- a/tensorboard/examples/plugins/example_basic/tensorboard_plugin_example/plugin.py +++ b/tensorboard/examples/plugins/example_basic/tensorboard_plugin_example/plugin.py @@ -20,6 +20,7 @@ from tensorboard.plugins import base_plugin from tensorboard.util import tensor_util +from tensorboard import plugin_util import werkzeug from werkzeug import wrappers @@ -35,7 +36,7 @@ def __init__(self, context): Args: context: A base_plugin.TBContext instance. """ - self._multiplexer = context.multiplexer + self.data_provider = context.data_provider def is_active(self): """Returns whether there is relevant data for the plugin to process. @@ -43,9 +44,9 @@ def is_active(self): When there are no runs with greeting data, TensorBoard will hide the plugin from the main navigation bar. """ - return bool( - self._multiplexer.PluginRunToTagToContent(metadata.PLUGIN_NAME) - ) + # not sure abouot this + return False # `list_plugins` as called by TB core suffices + def get_plugin_apps(self): return { @@ -69,17 +70,30 @@ def _serve_js(self, request): @wrappers.Request.application def _serve_tags(self, request): - del request # unused - mapping = self._multiplexer.PluginRunToTagToContent( - metadata.PLUGIN_NAME + # del request # unused + + ctx = plugin_util.context(request.environ) + experiment = plugin_util.experiment_id(request.environ) + + # mapping = self.multiplexer.PluginRunToTagToContent( + # metadata.PLUGIN_NAME + # ) + # empty mapping + mapping = self.data_provider.list_tensors( + ctx, experiment_id=experiment, plugin_name=metadata.PLUGIN_NAME ) - result = {run: {} for run in self._multiplexer.Runs()} + + print('mapping', mapping) + #result = {run: {} for run in self.multiplexer.Runs()} + result = {run: {} for run in mapping} for (run, tag_to_content) in mapping.items(): for tag in tag_to_content: - summary_metadata = self._multiplexer.SummaryMetadata(run, tag) - result[run][tag] = { - "description": summary_metadata.summary_description, - } + print('tag', tag) + # not sure the replacement of SummaryMetadata yet + # summary_metadata = self.multiplexer.SummaryMetadata(run, tag) + # result[run][tag] = { + # "description": summary_metadata.summary_description, + # } contents = json.dumps(result, sort_keys=True) return werkzeug.Response(contents, content_type="application/json") @@ -92,6 +106,8 @@ def _serve_greetings(self, request): """ run = request.args.get("run") tag = request.args.get("tag") + run_tag_filter = {'run': run, 'tag': tag} + print('run_tag_filter', run_tag_filter) if run is None or tag is None: raise werkzeug.exceptions.BadRequest("Must specify run and tag") try: @@ -99,7 +115,8 @@ def _serve_greetings(self, request): tensor_util.make_ndarray(event.tensor_proto) .item() .decode("utf-8") - for event in self._multiplexer.Tensors(run, tag) + for event in self.data_provider.list_tensors(run_tag_filter=run_tag_filter) + # for event in self.data_provider.Tensors(run, tag) ] except KeyError: raise werkzeug.exceptions.BadRequest("Invalid run or tag") From e7dc1777d6f5582ad0da7a826917f829c981235d Mon Sep 17 00:00:00 2001 From: Jie-Wei Wu Date: Thu, 7 Oct 2021 14:58:49 -0700 Subject: [PATCH 2/9] read tensors and clean up --- .../tensorboard_plugin_example/plugin.py | 45 +++++++++---------- .../tensorboard_plugin_example/summary_v2.py | 1 + 2 files changed, 22 insertions(+), 24 deletions(-) diff --git a/tensorboard/examples/plugins/example_basic/tensorboard_plugin_example/plugin.py b/tensorboard/examples/plugins/example_basic/tensorboard_plugin_example/plugin.py index aa6caa2350..1901954edf 100644 --- a/tensorboard/examples/plugins/example_basic/tensorboard_plugin_example/plugin.py +++ b/tensorboard/examples/plugins/example_basic/tensorboard_plugin_example/plugin.py @@ -18,6 +18,7 @@ import json import os +from tensorboard.data import provider from tensorboard.plugins import base_plugin from tensorboard.util import tensor_util from tensorboard import plugin_util @@ -44,7 +45,6 @@ def is_active(self): When there are no runs with greeting data, TensorBoard will hide the plugin from the main navigation bar. """ - # not sure abouot this return False # `list_plugins` as called by TB core suffices @@ -70,30 +70,19 @@ def _serve_js(self, request): @wrappers.Request.application def _serve_tags(self, request): - # del request # unused - ctx = plugin_util.context(request.environ) experiment = plugin_util.experiment_id(request.environ) - # mapping = self.multiplexer.PluginRunToTagToContent( - # metadata.PLUGIN_NAME - # ) - # empty mapping mapping = self.data_provider.list_tensors( ctx, experiment_id=experiment, plugin_name=metadata.PLUGIN_NAME ) - print('mapping', mapping) - #result = {run: {} for run in self.multiplexer.Runs()} result = {run: {} for run in mapping} - for (run, tag_to_content) in mapping.items(): - for tag in tag_to_content: - print('tag', tag) - # not sure the replacement of SummaryMetadata yet - # summary_metadata = self.multiplexer.SummaryMetadata(run, tag) - # result[run][tag] = { - # "description": summary_metadata.summary_description, - # } + for (run, tag_to_timeseries) in mapping.items(): + for (tag, timeseries) in tag_to_timeseries.items(): + result[run][tag] = { + "description": timeseries.description, + } contents = json.dumps(result, sort_keys=True) return werkzeug.Response(contents, content_type="application/json") @@ -106,19 +95,27 @@ def _serve_greetings(self, request): """ run = request.args.get("run") tag = request.args.get("tag") - run_tag_filter = {'run': run, 'tag': tag} - print('run_tag_filter', run_tag_filter) + ctx = plugin_util.context(request.environ) + experiment = plugin_util.experiment_id(request.environ) + if run is None or tag is None: raise werkzeug.exceptions.BadRequest("Must specify run and tag") try: - data = [ - tensor_util.make_ndarray(event.tensor_proto) + read_result = self.data_provider.read_tensors( + ctx, + downsample=1, + plugin_name=metadata.PLUGIN_NAME, + experiment_id=experiment, + run_tag_filter=provider.RunTagFilter(runs=[run], tags=[tag]) + ) + + data = read_result.get(run, {}).get(tag, {}) + event_data = [ + data[0].numpy .item() .decode("utf-8") - for event in self.data_provider.list_tensors(run_tag_filter=run_tag_filter) - # for event in self.data_provider.Tensors(run, tag) ] except KeyError: raise werkzeug.exceptions.BadRequest("Invalid run or tag") - contents = json.dumps(data, sort_keys=True) + contents = json.dumps(event_data, sort_keys=True) return werkzeug.Response(contents, content_type="application/json") diff --git a/tensorboard/examples/plugins/example_basic/tensorboard_plugin_example/summary_v2.py b/tensorboard/examples/plugins/example_basic/tensorboard_plugin_example/summary_v2.py index 1e9ba16708..5a94108e2e 100644 --- a/tensorboard/examples/plugins/example_basic/tensorboard_plugin_example/summary_v2.py +++ b/tensorboard/examples/plugins/example_basic/tensorboard_plugin_example/summary_v2.py @@ -62,4 +62,5 @@ def _create_summary_metadata(description): plugin_name=metadata.PLUGIN_NAME, content=b"", # no need for summary-specific metadata ), + data_class=summary_pb2.DATA_CLASS_TENSOR, ) From 98bf43db8d96567e704c8a7bc73a1f7c3761bb0f Mon Sep 17 00:00:00 2001 From: Jie-Wei Wu Date: Thu, 7 Oct 2021 15:54:21 -0700 Subject: [PATCH 3/9] py lint --- .../example_basic/tensorboard_plugin_example/plugin.py | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/tensorboard/examples/plugins/example_basic/tensorboard_plugin_example/plugin.py b/tensorboard/examples/plugins/example_basic/tensorboard_plugin_example/plugin.py index 1901954edf..fe46cab9c2 100644 --- a/tensorboard/examples/plugins/example_basic/tensorboard_plugin_example/plugin.py +++ b/tensorboard/examples/plugins/example_basic/tensorboard_plugin_example/plugin.py @@ -47,7 +47,6 @@ def is_active(self): """ return False # `list_plugins` as called by TB core suffices - def get_plugin_apps(self): return { "/index.js": self._serve_js, @@ -106,15 +105,11 @@ def _serve_greetings(self, request): downsample=1, plugin_name=metadata.PLUGIN_NAME, experiment_id=experiment, - run_tag_filter=provider.RunTagFilter(runs=[run], tags=[tag]) + run_tag_filter=provider.RunTagFilter(runs=[run], tags=[tag]), ) data = read_result.get(run, {}).get(tag, {}) - event_data = [ - data[0].numpy - .item() - .decode("utf-8") - ] + event_data = [data[0].numpy.item().decode("utf-8")] except KeyError: raise werkzeug.exceptions.BadRequest("Invalid run or tag") contents = json.dumps(event_data, sort_keys=True) From 2673b245718f3eee813a12fa915de26c29a823c7 Mon Sep 17 00:00:00 2001 From: Jie-Wei Wu Date: Thu, 7 Oct 2021 15:55:49 -0700 Subject: [PATCH 4/9] lint --- .../plugins/example_basic/tensorboard_plugin_example/plugin.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tensorboard/examples/plugins/example_basic/tensorboard_plugin_example/plugin.py b/tensorboard/examples/plugins/example_basic/tensorboard_plugin_example/plugin.py index fe46cab9c2..34679cc63e 100644 --- a/tensorboard/examples/plugins/example_basic/tensorboard_plugin_example/plugin.py +++ b/tensorboard/examples/plugins/example_basic/tensorboard_plugin_example/plugin.py @@ -20,7 +20,6 @@ from tensorboard.data import provider from tensorboard.plugins import base_plugin -from tensorboard.util import tensor_util from tensorboard import plugin_util import werkzeug from werkzeug import wrappers From 670ff79621d7fbdcca43ce757e292adda37544f1 Mon Sep 17 00:00:00 2001 From: Jie-Wei Wu Date: Thu, 7 Oct 2021 17:06:22 -0700 Subject: [PATCH 5/9] move import order --- .../plugins/example_basic/tensorboard_plugin_example/plugin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tensorboard/examples/plugins/example_basic/tensorboard_plugin_example/plugin.py b/tensorboard/examples/plugins/example_basic/tensorboard_plugin_example/plugin.py index 34679cc63e..ac0a4945ed 100644 --- a/tensorboard/examples/plugins/example_basic/tensorboard_plugin_example/plugin.py +++ b/tensorboard/examples/plugins/example_basic/tensorboard_plugin_example/plugin.py @@ -18,9 +18,9 @@ import json import os +from tensorboard import plugin_util from tensorboard.data import provider from tensorboard.plugins import base_plugin -from tensorboard import plugin_util import werkzeug from werkzeug import wrappers From e72492fe8ed7f902152e18845dedbfa89de26769 Mon Sep 17 00:00:00 2001 From: Jie-Wei Wu Date: Thu, 7 Oct 2021 17:19:36 -0700 Subject: [PATCH 6/9] add description column --- .../example_basic/tensorboard_plugin_example/static/index.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tensorboard/examples/plugins/example_basic/tensorboard_plugin_example/static/index.js b/tensorboard/examples/plugins/example_basic/tensorboard_plugin_example/static/index.js index 4ac1a561b7..8cc293f57e 100644 --- a/tensorboard/examples/plugins/example_basic/tensorboard_plugin_example/static/index.js +++ b/tensorboard/examples/plugins/example_basic/tensorboard_plugin_example/static/index.js @@ -27,6 +27,7 @@ export async function render() { run, tag, greetings, + description: tagToDescription[tag].description, })) ) ) @@ -61,16 +62,18 @@ export async function render() { createElement('th', 'Run'), createElement('th', 'Tag'), createElement('th', 'Greetings'), + createElement('th', 'Description'), ]) ), createElement( 'tbody', - data.flatMap(({run, tag, greetings}) => + data.flatMap(({run, tag, greetings, description}) => greetings.map((guest, i) => createElement('tr', [ createElement('td', i === 0 ? run : null), createElement('td', i === 0 ? tag : null), createElement('td', guest), + createElement('td', description), ]) ) ) From d722d8be54d1953f31ef7187afd3c73c390c67e2 Mon Sep 17 00:00:00 2001 From: Jie-Wei Wu Date: Wed, 27 Oct 2021 16:04:06 -0700 Subject: [PATCH 7/9] fix downsample number to show all summary data; adjust error handling --- .../tensorboard_plugin_example/demo.py | 1 + .../tensorboard_plugin_example/plugin.py | 24 +++++++++---------- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/tensorboard/examples/plugins/example_basic/tensorboard_plugin_example/demo.py b/tensorboard/examples/plugins/example_basic/tensorboard_plugin_example/demo.py index d3333380d4..d86db5dad9 100644 --- a/tensorboard/examples/plugins/example_basic/tensorboard_plugin_example/demo.py +++ b/tensorboard/examples/plugins/example_basic/tensorboard_plugin_example/demo.py @@ -36,6 +36,7 @@ def main(unused_argv): summary_v2.greeting("guestbook", "Cheryl", step=2) summary_v2.greeting("more_names", "David", step=4) + writer.close() if __name__ == "__main__": app.run(main) diff --git a/tensorboard/examples/plugins/example_basic/tensorboard_plugin_example/plugin.py b/tensorboard/examples/plugins/example_basic/tensorboard_plugin_example/plugin.py index ac0a4945ed..faf01c2646 100644 --- a/tensorboard/examples/plugins/example_basic/tensorboard_plugin_example/plugin.py +++ b/tensorboard/examples/plugins/example_basic/tensorboard_plugin_example/plugin.py @@ -98,18 +98,18 @@ def _serve_greetings(self, request): if run is None or tag is None: raise werkzeug.exceptions.BadRequest("Must specify run and tag") - try: - read_result = self.data_provider.read_tensors( - ctx, - downsample=1, - plugin_name=metadata.PLUGIN_NAME, - experiment_id=experiment, - run_tag_filter=provider.RunTagFilter(runs=[run], tags=[tag]), - ) - - data = read_result.get(run, {}).get(tag, {}) - event_data = [data[0].numpy.item().decode("utf-8")] - except KeyError: + read_result = self.data_provider.read_tensors( + ctx, + downsample=1000, + plugin_name=metadata.PLUGIN_NAME, + experiment_id=experiment, + run_tag_filter=provider.RunTagFilter(runs=[run], tags=[tag]), + ) + + data = read_result.get(run, {}).get(tag, []) + if not data: raise werkzeug.exceptions.BadRequest("Invalid run or tag") + event_data = [datum.numpy.item().decode("utf-8") for datum in data] + contents = json.dumps(event_data, sort_keys=True) return werkzeug.Response(contents, content_type="application/json") From e739ba334dcf73be18b77935e3827ee88635210c Mon Sep 17 00:00:00 2001 From: Jie-Wei Wu Date: Wed, 27 Oct 2021 16:14:26 -0700 Subject: [PATCH 8/9] py lint --- .../plugins/example_basic/tensorboard_plugin_example/demo.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tensorboard/examples/plugins/example_basic/tensorboard_plugin_example/demo.py b/tensorboard/examples/plugins/example_basic/tensorboard_plugin_example/demo.py index d86db5dad9..5cfac86fcf 100644 --- a/tensorboard/examples/plugins/example_basic/tensorboard_plugin_example/demo.py +++ b/tensorboard/examples/plugins/example_basic/tensorboard_plugin_example/demo.py @@ -38,5 +38,6 @@ def main(unused_argv): writer.close() + if __name__ == "__main__": app.run(main) From 5b6b8c44be82833bda468e8ddf8d1de1b5e96235 Mon Sep 17 00:00:00 2001 From: Jie-Wei Wu Date: Wed, 27 Oct 2021 16:39:49 -0700 Subject: [PATCH 9/9] omit writer.close() --- .../plugins/example_basic/tensorboard_plugin_example/demo.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/tensorboard/examples/plugins/example_basic/tensorboard_plugin_example/demo.py b/tensorboard/examples/plugins/example_basic/tensorboard_plugin_example/demo.py index 5cfac86fcf..d3333380d4 100644 --- a/tensorboard/examples/plugins/example_basic/tensorboard_plugin_example/demo.py +++ b/tensorboard/examples/plugins/example_basic/tensorboard_plugin_example/demo.py @@ -36,8 +36,6 @@ def main(unused_argv): summary_v2.greeting("guestbook", "Cheryl", step=2) summary_v2.greeting("more_names", "David", step=4) - writer.close() - if __name__ == "__main__": app.run(main)