Skip to content

Commit

Permalink
Revert "projector: fix RunPaths result aliasing (#4479)" (#4506)
Browse files Browse the repository at this point in the history
Summary:
Some Google-internal, non-TensorBoard code depends on the projector and
monkey patches out its internals in a way that is not compatible with
the changes in #4479. This is clearly not ideal and should probably be
fixed downstream, but pending investigation we revert #4479 to unbreak.

This reverts commit 638014e.

Test Plan:
Test sync at this tree passes all tests.

wchargin-branch: projector-revert-4479
  • Loading branch information
wchargin authored Dec 22, 2020
1 parent b306651 commit 4c9a699
Showing 1 changed file with 37 additions and 43 deletions.
80 changes: 37 additions & 43 deletions tensorboard/plugins/projector/projector_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -242,8 +242,9 @@ def __init__(self, context):
self.multiplexer = context.multiplexer
self.logdir = context.logdir
self.readers = {}
self._run_paths = None
self.run_paths = None
self._configs = {}
self.old_num_run_paths = None
self.config_fpaths = None
self.tensor_cache = LRUCache(_TENSOR_CACHE_CAPACITY)

Expand All @@ -256,7 +257,8 @@ def __init__(self, context):
# active. If such a thread exists, do not start a duplicate thread.
self._thread_for_determining_is_active = None

self._update_run_paths()
if self.multiplexer:
self.run_paths = self.multiplexer.RunPaths()

def get_plugin_apps(self):
asset_prefix = "tf_projector_plugin"
Expand Down Expand Up @@ -320,52 +322,44 @@ def frontend_metadata(self):
disable_reload=True,
)

def _update_run_paths(self):
"""Updates `self._run_paths`, testing for updates.
Returns:
`True` if this call changed the value of `self._run_paths`,
else `False`.
"""
if self.multiplexer:
run_paths = dict(self.multiplexer.RunPaths())
else:
run_paths = None
changed = run_paths != self._run_paths
self._run_paths = run_paths
return changed

def _determine_is_active(self):
"""Determines whether the plugin is active.
This method is run in a separate thread so that the plugin can
offer an immediate response to whether it is active and
determine whether it should be active in a separate thread.
"""
self._update_configs()
if self._configs:
if self.configs:
self._is_active = True
self._thread_for_determining_is_active = None

def _update_configs(self):
"""Updates `self._configs`."""
run_paths_changed = self._update_run_paths()
run_path_pairs = list(self._run_paths.items())
@property
def configs(self):
"""Returns a map of run paths to `ProjectorConfig` protos."""
run_path_pairs = list(self.run_paths.items())
self._append_plugin_asset_directories(run_path_pairs)
# Also accept the root logdir as a model checkpoint directory,
# so that the projector still works when there are no runs.
# (Case on `run` rather than `path` to avoid issues with
# absolute/relative paths on any filesystems.)
if "." not in self._run_paths:
if not any(run == "." for (run, path) in run_path_pairs):
run_path_pairs.append((".", self.logdir))
if run_paths_changed or _latest_checkpoints_changed(
if self._run_paths_changed() or _latest_checkpoints_changed(
self._configs, run_path_pairs
):
self.readers = {}
self._configs, self.config_fpaths = self._read_latest_config_files(
run_path_pairs
)
self._augment_configs_with_checkpoint_info()
return self._configs

def _run_paths_changed(self):
num_run_paths = len(list(self.run_paths.keys()))
if num_run_paths != self.old_num_run_paths:
self.old_num_run_paths = num_run_paths
return True
return False

def _augment_configs_with_checkpoint_info(self):
for run, config in self._configs.items():
Expand Down Expand Up @@ -530,7 +524,7 @@ def _append_plugin_asset_directories(self, run_path_pairs):
if metadata.PROJECTOR_FILENAME not in assets:
continue
assets_dir = os.path.join(
self._run_paths[run],
self.run_paths[run],
metadata.PLUGINS_DIR,
metadata.PLUGIN_ASSETS_NAME,
)
Expand All @@ -548,8 +542,7 @@ def _serve_file(self, file_path, request):
@wrappers.Request.application
def _serve_runs(self, request):
"""Returns a list of runs that have embeddings."""
self._update_configs()
return Respond(request, list(self._configs.keys()), "application/json")
return Respond(request, list(self.configs.keys()), "application/json")

@wrappers.Request.application
def _serve_config(self, request):
Expand All @@ -558,12 +551,12 @@ def _serve_config(self, request):
return Respond(
request, 'query parameter "run" is required', "text/plain", 400
)
self._update_configs()
config = self._configs.get(run)
if config is None:
if run not in self.configs:
return Respond(
request, 'Unknown run: "%s"' % run, "text/plain", 400
)

config = self.configs[run]
return Respond(
request, json_format.MessageToJson(config), "application/json"
)
Expand Down Expand Up @@ -591,12 +584,12 @@ def _serve_metadata(self, request):
400,
)

self._update_configs()
config = self._configs.get(run)
if config is None:
if run not in self.configs:
return Respond(
request, 'Unknown run: "%s"' % run, "text/plain", 400
)

config = self.configs[run]
fpath = self._get_metadata_file_for_tensor(name, config)
if not fpath:
return Respond(
Expand Down Expand Up @@ -651,12 +644,13 @@ def _serve_tensor(self, request):
400,
)

self._update_configs()
config = self._configs.get(run)
if config is None:
if run not in self.configs:
return Respond(
request, 'Unknown run: "%s"' % run, "text/plain", 400
)

config = self.configs[run]

tensor = self.tensor_cache.get((run, name))
if tensor is None:
# See if there is a tensor file in the config.
Expand Down Expand Up @@ -717,12 +711,12 @@ def _serve_bookmarks(self, request):
request, 'query parameter "name" is required', "text/plain", 400
)

self._update_configs()
config = self._configs.get(run)
if config is None:
if run not in self.configs:
return Respond(
request, 'Unknown run: "%s"' % run, "text/plain", 400
)

config = self.configs[run]
fpath = self._get_bookmarks_file_for_tensor(name, config)
if not fpath:
return Respond(
Expand Down Expand Up @@ -760,14 +754,14 @@ def _serve_sprite_image(self, request):
request, 'query parameter "name" is required', "text/plain", 400
)

self._update_configs()
config = self._configs.get(run)
if config is None:
if run not in self.configs:
return Respond(
request, 'Unknown run: "%s"' % run, "text/plain", 400
)

config = self.configs[run]
embedding_info = self._get_embedding(name, config)

if not embedding_info or not embedding_info.sprite.image_path:
return Respond(
request,
Expand Down

0 comments on commit 4c9a699

Please sign in to comment.