Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

profile: disable dashboard inside Colab #1914

Merged
merged 3 commits into from
Feb 28, 2019

Conversation

wchargin
Copy link
Contributor

@wchargin wchargin commented Feb 28, 2019

Summary:
The profile dashboard now shows a “disabled” message on the frontend
when we detect that we’re running in a Colab notebook. See #1913.

This commit does not cause the profile dashboard to be marked inactive
by the main TensorBoard UI. We might want to do that, but it’s less
straightforward: currently, the backend is responsible for telling the
frontend which plugins are active, and the backend can’t know whether
we’re running in Colab. As a quick hack, we could add special-case logic
in tf-tensorboard.html to check for the profile plugin specifically.
As a longer-term solution, we could let the tf_tensorboard.Dashboard
interface specify an isActive callback, defaulting to () => true.

Screenshot of the “Profiling isn’t yet supported in Colab” message

The implementation includes a small refactor to the profile dashboard to
make it easier to introduce a new state.

Test Plan:
Evaluate !!(window.TENSORBOARD_ENV || {}).IN_COLAB in both standalone
TensorBoard and Colab %tensorboard, and note that each evaluates to
the appropriate boolean.

Run TensorBoard locally with the profile plugin’s demo data, and note
that its behavior is unchanged. To trigger the loading state, it
suffices to load the dashboard, then throttle your network to “Slow 3G”,
then change the selected tool. To trigger the “no data” state, relaunch
TensorBoard pointing at a different log directory.

Then, test the Colab behavior by either pointing TensorBoard at a log
directory that does not contain profile data, then executing

window.TENSORBOARD_ENV = window.TENSORBOARD_ENV || {};
window.TENSORBOARD_ENV["IN_COLAB"] = true;

in the main TensorBoard pane before switching to the inactive profile
dashboard. Note that this is the same setup JavaScript as is injected
into the Colab output frame by notebook.py.

wchargin-branch: profile-disable-colab

Summary:
The profile dashboard now shows a “disabled” message on the frontend
when we detect that we’re running in a Colab notebook. See #1913.

This commit does _not_ cause the profile dashboard to be marked inactive
by the main TensorBoard UI. We might want to do that, but it’s less
straightforward: currently, the backend is responsible for telling the
frontend which plugins are active, and the backend can’t know whether
we’re running in Colab. As a quick hack, we could add special-case logic
in `tf-tensorboard.html` to check for the profile plugin specifically.
As a longer-term solution, we could let the `tf_tensorboard.Dashboard`
interface specify an `isActive` callback, defaulting to `() => true`.

![Screenshot of the “Profiling isn’t yet supported in Colab” message][s]

[s]: https://user-images.githubusercontent.com/4317806/53533696-a6497d80-3ab0-11e9-935d-56e857a687a8.png

The implementation includes a small refactor to the profile dashboard to
make it easier to introduce a new state.

Test Plan:
Evaluate `!!(window.TENSORBOARD_ENV || {}).IN_COLAB` in both standalone
TensorBoard and Colab `%tensorboard`, and note that each evaluates to
the appropriate boolean.

Run TensorBoard locally with the profile plugin’s demo data, and note
that its behavior is unchanged. To trigger the loading state, it
suffices to load the dashboard, then throttle your network to “Slow 3G”,
then change the selected tool. To trigger the “no data” state, relaunch
TensorBoard pointing at a different log directory.

Then, test the Colab behavior by either pointing TensorBoard at a log
directory that does not contain profile data, then executing

```js
window.TENSORBOARD_ENV = window.TENSORBOARD_ENV || {};
window.TENSORBOARD_ENV["IN_COLAB"] = true;
```

in the main TensorBoard pane before switching to the inactive profile
dashboard. Note that this is the same setup JavaScript as is injected
into the Colab output frame by `notebook.py`.

wchargin-branch: profile-disable-colab
return "IN_COLAB";
if (dataNotFound)
return "DATA_NOT_FOUND";
if (!progress || progress.value < 100)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can now remove _isNotComplete() since its logic was inlined here and it's not called anywhere else

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point; done.

wchargin-branch: profile-disable-colab
@GalOshri
Copy link
Contributor

nit on the error message: "Profiling isn't yet supported in Colab" sounds less natural to me than "Profiling isn't supported in Colab yet".

Relevant question: I think the profiling (creating the right logs) is supported, right? It's just displaying them in the dashboard that isn't.

Additionally, does this affect only Colab or also Jupyter?

@wchargin
Copy link
Contributor Author

nit on the error message: "Profiling isn't yet supported in Colab"
sounds less natural to me than "Profiling isn't supported in Colab
yet".

Sure; can change.

Relevant question: I think the profiling (creating the right logs) is
supported, right? It's just displaying them in the dashboard that
isn't.

Correct; we generate the logs (though the autoprofiler, triggered from
TensorBoard, of course can’t run if TensorBoard can’t show the
profiler). I think that the wording is fine, because the profiling
experience is certainly broken given that you can’t consume what you
produce. But I’d accept a PR to change it.

Additionally, does this affect only Colab or also Jupyter?

Colab only. Jupyter puts all of TensorBoard in an iframe with direct
network access; another iframe within that iframe is fine because there
is no service worker proxy to contend with. (This also means that
hparams should work fine with POSTs.)

wchargin-branch: profile-disable-colab
@wchargin
Copy link
Contributor Author

Proof of life for Jupyter:

Screenshot of a happy trace viewer in Jupyter.

@wchargin wchargin merged commit 5101522 into master Feb 28, 2019
@wchargin wchargin deleted the wchargin-profile-disable-colab branch February 28, 2019 04:47
@@ -43,13 +43,23 @@

<dom-module id="tf-profile-dashboard">
<template>
<template is="dom-if" if="[[_isNotComplete(progress)]]">
<template is="dom-if" if="[[_isState(_topLevelState, 'IN_COLAB')]]">
<div style="max-width: 540px; margin: 80px auto 0 auto;">
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:( prefer not to use inline style.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is copy-pasted from below…which is indeed a reasonable argument for
making it a class. :-)

_topLevelState: {
type: String,
computed: '_computeTopLevelState(_inColab, _dataNotFound, progress)',
readOnly: true,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good to know; thanks.

@@ -235,6 +274,17 @@ <h3>No profile data was found.</h3>
type: Array,
observer: '_activeHostsChanged'
},
_inColab: {
type: Boolean,
value: () => !!(window.TENSORBOARD_ENV || {}).IN_COLAB,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of !!, use Boolean((window.TENSORBOARD_ENV || {}).IN_COLAB) though I understand both with ease.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

http://go/tsstyle explicitly says that !! is okay; jsstyle has no mention.

wchargin added a commit that referenced this pull request Feb 28, 2019
Summary:
Not only is opening in new tabs a better user experience, it’s necessary
in notebook contexts so that we don’t try to load the GitHub docs in an
iframe, which would fail because GitHub sets `frame-ancestors 'none'`.
(When I tested #1914 in Colab, I instinctively Ctrl-clicked the link,
thus not hitting this issue.)

Test Plan:
Tested that in both Jupyter and Colab, clicking on a help link before
this change yields a white frame with a “Refused to display…” console
error, while after this change it opens the appropriate link in a new
tab.

Checked statically that each link has `rel="noopener" target="_blank"`:

```shell
$ <./tensorboard/plugins/profile/tf_profile_dashboard/tf-profile-dashboard.html tee \
> >(grep 'href=' | grep -Fcv '<link') \
> >(grep -Fc 'rel="noopener"') \
> >(grep -Fc 'target="_blank"') \
> >/dev/null
6
6
6
```

wchargin-branch: profile-help-in-new-tab
wchargin added a commit that referenced this pull request Feb 28, 2019
Summary:
Not only is opening in new tabs a better user experience, it’s necessary
in notebook contexts so that we don’t try to load the GitHub docs in an
iframe, which would fail because GitHub sets `frame-ancestors 'none'`.
(When I tested #1914 in Colab, I instinctively Ctrl-clicked the link,
thus not hitting this issue.)

Test Plan:
Tested that in both Jupyter and Colab, clicking on a help link before
this change yields a white frame with a “Refused to display…” console
error, while after this change it opens the appropriate link in a new
tab.

Checked statically that each link has `rel="noopener" target="_blank"`:

```shell
$ <./tensorboard/plugins/profile/tf_profile_dashboard/tf-profile-dashboard.html tee \
> >(grep 'href=' | grep -Fcv '<link') \
> >(grep -Fc 'rel="noopener"') \
> >(grep -Fc 'target="_blank"') \
> >/dev/null
6
6
6
```

wchargin-branch: profile-help-in-new-tab
wchargin added a commit that referenced this pull request Mar 2, 2019
Summary:
The profile dashboard had an existing bug that was revealed by #1914:
the loading progress bar never actually finishes. Prior to #1914, you
could actually see the loading bar if you made your window narrow
enough:
![Screenshot of a zombie progress bar](https://user-images.githubusercontent.com/4317806/53674700-95317580-3c44-11e9-924f-82f6dc8d5f18.png)

This was because the prior version of the dashboard rendered the main
tool irrespective of whether the data had actually finished loading. As
of #1914, the “loading” and “active” states are mutually exclusive, so
instead of just having a zombie progress bar we actually block the view.

The cause of the bug is a promise that never resolves. (The executor
provided to the `Promise` constructor’s return value is ignored; only
the `resolve` and `reject` callbacks can fulfill a promise.)

This was not caught while testing #1914 because it cannot be reproduced
with the demo data present at that commit; with that more complete set
of data, there are other code paths that clobber the progress value to
100% (which is really a separate issue, but that’s not important right
now), such as `_maybeUpdateData`.

Test Plan:
Regenerate profile plugin demo data if you haven’t done so since #1942,
then launch TensorBoard:

```
$ rm -rf /tmp/profile_demo/
$ bazel run //tensorboard/plugins/profile:profile_demo
$ bazel run //tensorboard -- --logdir /tmp/profile_demo
```

The trace viewer should be displayed (prior to this commit, it wasn’t).

wchargin-branch: profile-broken-promises
wchargin added a commit that referenced this pull request Mar 2, 2019
Summary:
The profile dashboard had an existing bug that was revealed by #1914:
the loading progress bar never actually finishes. Prior to #1914, you
could actually see the loading bar if you made your window narrow
enough:
![Screenshot of a zombie progress bar](https://user-images.githubusercontent.com/4317806/53674700-95317580-3c44-11e9-924f-82f6dc8d5f18.png)

This was because the prior version of the dashboard rendered the main
tool irrespective of whether the data had actually finished loading. As
of #1914, the “loading” and “active” states are mutually exclusive, so
instead of just having a zombie progress bar we actually block the view.

The cause of the bug is a promise that never resolves. (The executor
provided to the `Promise` constructor’s return value is ignored; only
the `resolve` and `reject` callbacks can fulfill a promise.)

This was not caught while testing #1914 because it cannot be reproduced
with the demo data present at that commit; with that more complete set
of data, there are other code paths that clobber the progress value to
100% (which is really a separate issue, but that’s not important right
now), such as `_maybeUpdateData`.

Test Plan:
Regenerate profile plugin demo data if you haven’t done so since #1942,
then launch TensorBoard:

```
$ rm -rf /tmp/profile_demo/
$ bazel run //tensorboard/plugins/profile:profile_demo
$ bazel run //tensorboard -- --logdir /tmp/profile_demo
```

The trace viewer should be displayed (prior to this commit, it wasn’t).

wchargin-branch: profile-broken-promises
wchargin added a commit to wchargin/tensorboard that referenced this pull request Mar 5, 2019
Summary:
The profile dashboard now shows a “disabled” message on the frontend
when we detect that we’re running in a Colab notebook. See tensorflow#1913.

This commit does _not_ cause the profile dashboard to be marked inactive
by the main TensorBoard UI. We might want to do that, but it’s less
straightforward: currently, the backend is responsible for telling the
frontend which plugins are active, and the backend can’t know whether
we’re running in Colab. As a quick hack, we could add special-case logic
in `tf-tensorboard.html` to check for the profile plugin specifically.
As a longer-term solution, we could let the `tf_tensorboard.Dashboard`
interface specify an `isActive` callback, defaulting to `() => true`.

![Screenshot of the “Profiling isn’t yet supported in Colab” message][s]

[s]: https://user-images.githubusercontent.com/4317806/53541886-b83b1880-3ad0-11e9-9501-299f5e671d7a.png

The implementation includes a small refactor to the profile dashboard to
make it easier to introduce a new state.

Test Plan:
Evaluate `!!(window.TENSORBOARD_ENV || {}).IN_COLAB` in both standalone
TensorBoard and Colab `%tensorboard`, and note that each evaluates to
the appropriate boolean.

Run TensorBoard locally with the profile plugin’s demo data, and note
that its behavior is unchanged. To trigger the loading state, it
suffices to load the dashboard, then throttle your network to “Slow 3G”,
then change the selected tool. To trigger the “no data” state, relaunch
TensorBoard pointing at a different log directory.

Then, test the Colab behavior by either pointing TensorBoard at a log
directory that does not contain profile data, then executing

```js
window.TENSORBOARD_ENV = window.TENSORBOARD_ENV || {};
window.TENSORBOARD_ENV["IN_COLAB"] = true;
```

in the main TensorBoard pane before switching to the inactive profile
dashboard. Note that this is the same setup JavaScript as is injected
into the Colab output frame by `notebook.py`.

wchargin-branch: profile-disable-colab
wchargin added a commit to wchargin/tensorboard that referenced this pull request Mar 5, 2019
Summary:
Not only is opening in new tabs a better user experience, it’s necessary
in notebook contexts so that we don’t try to load the GitHub docs in an
iframe, which would fail because GitHub sets `frame-ancestors 'none'`.
(When I tested tensorflow#1914 in Colab, I instinctively Ctrl-clicked the link,
thus not hitting this issue.)

Test Plan:
Tested that in both Jupyter and Colab, clicking on a help link before
this change yields a white frame with a “Refused to display…” console
error, while after this change it opens the appropriate link in a new
tab.

Checked statically that each link has `rel="noopener" target="_blank"`:

```shell
$ <./tensorboard/plugins/profile/tf_profile_dashboard/tf-profile-dashboard.html tee \
> >(grep 'href=' | grep -Fcv '<link') \
> >(grep -Fc 'rel="noopener"') \
> >(grep -Fc 'target="_blank"') \
> >/dev/null
6
6
6
```

wchargin-branch: profile-help-in-new-tab
wchargin added a commit to wchargin/tensorboard that referenced this pull request Mar 5, 2019
Summary:
The profile dashboard had an existing bug that was revealed by tensorflow#1914:
the loading progress bar never actually finishes. Prior to tensorflow#1914, you
could actually see the loading bar if you made your window narrow
enough:
![Screenshot of a zombie progress bar](https://user-images.githubusercontent.com/4317806/53674700-95317580-3c44-11e9-924f-82f6dc8d5f18.png)

This was because the prior version of the dashboard rendered the main
tool irrespective of whether the data had actually finished loading. As
of tensorflow#1914, the “loading” and “active” states are mutually exclusive, so
instead of just having a zombie progress bar we actually block the view.

The cause of the bug is a promise that never resolves. (The executor
provided to the `Promise` constructor’s return value is ignored; only
the `resolve` and `reject` callbacks can fulfill a promise.)

This was not caught while testing tensorflow#1914 because it cannot be reproduced
with the demo data present at that commit; with that more complete set
of data, there are other code paths that clobber the progress value to
100% (which is really a separate issue, but that’s not important right
now), such as `_maybeUpdateData`.

Test Plan:
Regenerate profile plugin demo data if you haven’t done so since tensorflow#1942,
then launch TensorBoard:

```
$ rm -rf /tmp/profile_demo/
$ bazel run //tensorboard/plugins/profile:profile_demo
$ bazel run //tensorboard -- --logdir /tmp/profile_demo
```

The trace viewer should be displayed (prior to this commit, it wasn’t).

wchargin-branch: profile-broken-promises
@wchargin wchargin mentioned this pull request Mar 5, 2019
wchargin added a commit that referenced this pull request Mar 6, 2019
Summary:
The profile dashboard now shows a “disabled” message on the frontend
when we detect that we’re running in a Colab notebook. See #1913.

This commit does _not_ cause the profile dashboard to be marked inactive
by the main TensorBoard UI. We might want to do that, but it’s less
straightforward: currently, the backend is responsible for telling the
frontend which plugins are active, and the backend can’t know whether
we’re running in Colab. As a quick hack, we could add special-case logic
in `tf-tensorboard.html` to check for the profile plugin specifically.
As a longer-term solution, we could let the `tf_tensorboard.Dashboard`
interface specify an `isActive` callback, defaulting to `() => true`.

![Screenshot of the “Profiling isn’t yet supported in Colab” message][s]

[s]: https://user-images.githubusercontent.com/4317806/53541886-b83b1880-3ad0-11e9-9501-299f5e671d7a.png

The implementation includes a small refactor to the profile dashboard to
make it easier to introduce a new state.

Test Plan:
Evaluate `!!(window.TENSORBOARD_ENV || {}).IN_COLAB` in both standalone
TensorBoard and Colab `%tensorboard`, and note that each evaluates to
the appropriate boolean.

Run TensorBoard locally with the profile plugin’s demo data, and note
that its behavior is unchanged. To trigger the loading state, it
suffices to load the dashboard, then throttle your network to “Slow 3G”,
then change the selected tool. To trigger the “no data” state, relaunch
TensorBoard pointing at a different log directory.

Then, test the Colab behavior by either pointing TensorBoard at a log
directory that does not contain profile data, then executing

```js
window.TENSORBOARD_ENV = window.TENSORBOARD_ENV || {};
window.TENSORBOARD_ENV["IN_COLAB"] = true;
```

in the main TensorBoard pane before switching to the inactive profile
dashboard. Note that this is the same setup JavaScript as is injected
into the Colab output frame by `notebook.py`.

wchargin-branch: profile-disable-colab
wchargin added a commit that referenced this pull request Mar 6, 2019
Summary:
Not only is opening in new tabs a better user experience, it’s necessary
in notebook contexts so that we don’t try to load the GitHub docs in an
iframe, which would fail because GitHub sets `frame-ancestors 'none'`.
(When I tested #1914 in Colab, I instinctively Ctrl-clicked the link,
thus not hitting this issue.)

Test Plan:
Tested that in both Jupyter and Colab, clicking on a help link before
this change yields a white frame with a “Refused to display…” console
error, while after this change it opens the appropriate link in a new
tab.

Checked statically that each link has `rel="noopener" target="_blank"`:

```shell
$ <./tensorboard/plugins/profile/tf_profile_dashboard/tf-profile-dashboard.html tee \
> >(grep 'href=' | grep -Fcv '<link') \
> >(grep -Fc 'rel="noopener"') \
> >(grep -Fc 'target="_blank"') \
> >/dev/null
6
6
6
```

wchargin-branch: profile-help-in-new-tab
wchargin added a commit that referenced this pull request Mar 6, 2019
Summary:
The profile dashboard had an existing bug that was revealed by #1914:
the loading progress bar never actually finishes. Prior to #1914, you
could actually see the loading bar if you made your window narrow
enough:
![Screenshot of a zombie progress bar](https://user-images.githubusercontent.com/4317806/53674700-95317580-3c44-11e9-924f-82f6dc8d5f18.png)

This was because the prior version of the dashboard rendered the main
tool irrespective of whether the data had actually finished loading. As
of #1914, the “loading” and “active” states are mutually exclusive, so
instead of just having a zombie progress bar we actually block the view.

The cause of the bug is a promise that never resolves. (The executor
provided to the `Promise` constructor’s return value is ignored; only
the `resolve` and `reject` callbacks can fulfill a promise.)

This was not caught while testing #1914 because it cannot be reproduced
with the demo data present at that commit; with that more complete set
of data, there are other code paths that clobber the progress value to
100% (which is really a separate issue, but that’s not important right
now), such as `_maybeUpdateData`.

Test Plan:
Regenerate profile plugin demo data if you haven’t done so since #1942,
then launch TensorBoard:

```
$ rm -rf /tmp/profile_demo/
$ bazel run //tensorboard/plugins/profile:profile_demo
$ bazel run //tensorboard -- --logdir /tmp/profile_demo
```

The trace viewer should be displayed (prior to this commit, it wasn’t).

wchargin-branch: profile-broken-promises
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants