aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--WORKSPACE9
-rw-r--r--bower.BUILD8
-rw-r--r--tensorflow/tensorboard/bower.json2
-rw-r--r--tensorflow/tensorboard/bower/BUILD1
-rw-r--r--tensorflow/tensorboard/components/tf-graph-board/tf-graph-board.html1
-rw-r--r--tensorflow/tensorboard/components/tf-graph-common/lib/graph.ts12
-rw-r--r--tensorflow/tensorboard/components/tf-graph-common/lib/util.ts34
-rw-r--r--tensorflow/tensorboard/components/tf-graph-common/test/index.html1
-rw-r--r--tensorflow/tensorboard/components/tf-graph-common/test/util-test.ts46
-rw-r--r--tensorflow/tensorboard/components/tf-graph-dashboard/tf-graph-dashboard.html2
-rw-r--r--tensorflow/tensorboard/components/tf-graph/demo/tf-graph-demo.html2
-rw-r--r--tensorflow/tensorboard/components/tf-graph/tf-graph-controls.html318
-rw-r--r--tensorflow/tensorboard/components/tf-graph/tf-graph.html14
13 files changed, 333 insertions, 117 deletions
diff --git a/WORKSPACE b/WORKSPACE
index a7ee39ed5e..82e209bbbe 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -70,7 +70,7 @@ new_git_repository(
name = "iron_a11y_keys_behavior",
build_file = "bower.BUILD",
remote = "https://github.com/polymerelements/iron-a11y-keys-behavior.git",
- tag = "v1.1.4",
+ tag = "v1.1.5",
)
new_git_repository(
@@ -389,6 +389,13 @@ new_git_repository(
)
new_git_repository(
+ name = "paper_tooltip",
+ build_file = "bower.BUILD",
+ remote = "https://github.com/polymerelements/paper-tooltip.git",
+ tag = "v1.1.2",
+)
+
+new_git_repository(
name = "plottable",
build_file = "bower.BUILD",
remote = "https://github.com/palantir/plottable.git",
diff --git a/bower.BUILD b/bower.BUILD
index ea393cafe3..1a4b6158a4 100644
--- a/bower.BUILD
+++ b/bower.BUILD
@@ -533,6 +533,14 @@ filegroup(
)
filegroup(
+ name = "paper_tooltip",
+ srcs = [
+ "index.html",
+ "paper-tooltip.html",
+ ],
+)
+
+filegroup(
name = "plottable",
srcs = [
"plottable.css",
diff --git a/tensorflow/tensorboard/bower.json b/tensorflow/tensorboard/bower.json
index b470a75f71..c410fd8dc0 100644
--- a/tensorflow/tensorboard/bower.json
+++ b/tensorflow/tensorboard/bower.json
@@ -84,6 +84,7 @@
"paper-tabs": "PolymerElements/paper-tabs#1.6.2",
"paper-toggle-button": "PolymerElements/paper-toggle-button#1.1.2",
"paper-toolbar": "PolymerElements/paper-toolbar#1.1.4",
+ "paper-tooltip": "PolymerElements/paper-tooltip#1.1.2",
"plottable": "1.16.1",
"polymer": "1.5.0",
"promise-polyfill": "polymerlabs/promise-polyfill#1.0.0",
@@ -158,6 +159,7 @@
"paper-tabs": "1.6.2",
"paper-toggle-button": "1.1.2",
"paper-toolbar": "1.1.4",
+ "paper-tooltip": "1.1.2",
"plottable": "1.16.1",
"polymer": "1.5.0",
"promise-polyfill": "1.0.0",
diff --git a/tensorflow/tensorboard/bower/BUILD b/tensorflow/tensorboard/bower/BUILD
index 10d5b464e8..90d9910205 100644
--- a/tensorflow/tensorboard/bower/BUILD
+++ b/tensorflow/tensorboard/bower/BUILD
@@ -57,6 +57,7 @@ filegroup(
"@paper_tabs//:paper_tabs",
"@paper_toggle_button//:paper_toggle_button",
"@paper_toolbar//:paper_toolbar",
+ "@paper_tooltip//:paper_tooltip",
"@plottable//:plottable",
"@polymer//:polymer",
"@promise_polyfill//:promise_polyfill",
diff --git a/tensorflow/tensorboard/components/tf-graph-board/tf-graph-board.html b/tensorflow/tensorboard/components/tf-graph-board/tf-graph-board.html
index e352038ea6..61e42982a7 100644
--- a/tensorflow/tensorboard/components/tf-graph-board/tf-graph-board.html
+++ b/tensorflow/tensorboard/components/tf-graph-board/tf-graph-board.html
@@ -117,6 +117,7 @@ paper-progress {
basic-graph="[[graph]]"
hierarchy-params="[[hierarchyParams]]"
render-hierarchy="{{_renderHierarchy}}"
+ devices-for-stats="[[devicesForStats]]"
stats="[[stats]]"
selected-node="{{_selectedNode}}"
highlighted-node="{{_highlightedNode}}"
diff --git a/tensorflow/tensorboard/components/tf-graph-common/lib/graph.ts b/tensorflow/tensorboard/components/tf-graph-common/lib/graph.ts
index d843aafec4..d3567641e6 100644
--- a/tensorflow/tensorboard/components/tf-graph-common/lib/graph.ts
+++ b/tensorflow/tensorboard/components/tf-graph-common/lib/graph.ts
@@ -379,8 +379,16 @@ export function createMetanode(name: string, opt = {}): Metanode {
* graph information.
*/
export function joinStatsInfoWithGraph(
- graph: SlimGraph, stats: tf.graph.proto.StepStats): void {
+ graph: SlimGraph, stats: tf.graph.proto.StepStats,
+ devicesForStats?: {[device: string]: boolean}): void {
+ // Reset stats for each node.
+ _.each(graph.nodes, node => { node.stats = null; });
+
_.each(stats.dev_stats, devStats => {
+ // Ignore devices that are not selected.
+ if (devicesForStats && !devicesForStats[devStats.device]) {
+ return;
+ }
_.each(devStats.node_stats, nodeStats => {
// Lookup the node in the graph by its original name, e.g. A. If not
// found, lookup by the rewritten name A/(A) in case the name is both
@@ -484,7 +492,7 @@ export class NodeStats {
* Total number of bytes used for the node. Sum of all children
* if it is a Group node.
*/
- totalBytes: number;
+ totalBytes = 0;
/**
* Total number of compute time in microseconds used for the node.
* Sum of all children if it is a Group node. Null if it is unknown.
diff --git a/tensorflow/tensorboard/components/tf-graph-common/lib/util.ts b/tensorflow/tensorboard/components/tf-graph-common/lib/util.ts
index 8e6e92361d..1625c723c2 100644
--- a/tensorflow/tensorboard/components/tf-graph-common/lib/util.ts
+++ b/tensorflow/tensorboard/components/tf-graph-common/lib/util.ts
@@ -193,4 +193,38 @@ module tf.graph.util {
}
return false;
}
+
+ /**
+ * Given a list of strings, it returns a new list of strings with the longest
+ * common prefix removed. If the common prefix is one of the strings in the
+ * list, it returns the original strings.
+ */
+ export function removeCommonPrefix(strings: string[]) {
+ if (strings.length < 2) {
+ return strings;
+ }
+
+ let index = 0;
+ let largestIndex = 0;
+ // Find the shortest name across all strings.
+ let minLength = _.min(_.map(strings, str => str.length));
+ while (true) {
+ index++;
+ let prefixes = _.map(strings, str => str.substring(0, index));
+ let allTheSame = prefixes.every((prefix, i) => {
+ return (i === 0 ? true : prefix === prefixes[i - 1]);
+ });
+ if (allTheSame) {
+ if (index >= minLength) {
+ // There is a string whose whole name is a prefix to other string.
+ // In this case, we return the original list of string.
+ return strings;
+ }
+ largestIndex = index;
+ } else {
+ break;
+ }
+ }
+ return _.map(strings, str => str.substring(largestIndex));
+ }
}
diff --git a/tensorflow/tensorboard/components/tf-graph-common/test/index.html b/tensorflow/tensorboard/components/tf-graph-common/test/index.html
index 927d2fef93..1897893833 100644
--- a/tensorflow/tensorboard/components/tf-graph-common/test/index.html
+++ b/tensorflow/tensorboard/components/tf-graph-common/test/index.html
@@ -11,5 +11,6 @@
<script src="graph-test.js"></script>
<script src="hierarchy-test.js"></script>
<script src="layout-test.js"></script>
+ <script src="util-test.js"></script>
</body>
</html>
diff --git a/tensorflow/tensorboard/components/tf-graph-common/test/util-test.ts b/tensorflow/tensorboard/components/tf-graph-common/test/util-test.ts
new file mode 100644
index 0000000000..0b8d9c9d49
--- /dev/null
+++ b/tensorflow/tensorboard/components/tf-graph-common/test/util-test.ts
@@ -0,0 +1,46 @@
+/* Copyright 2016 The TensorFlow Authors. All Rights Reserved.
+
+Licensed under the Apache License, Version 2.0 (the 'License');
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an 'AS IS' BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+==============================================================================*/
+
+suite('util', () => {
+ let assert = chai.assert;
+
+ test('remove common prefix', () => {
+
+ // Empty array.
+ let result = tf.graph.util.removeCommonPrefix([]);
+ assert.deepEqual(result, []);
+
+ // No common prefix.
+ result = tf.graph.util.removeCommonPrefix(['a', 'b', 'c']);
+ assert.deepEqual(result, ['a', 'b', 'c']);
+
+ // One of the elements is empty string.
+ result = tf.graph.util.removeCommonPrefix(['a/b', '', 'a/c']);
+ assert.deepEqual(result, ['a/b', '', 'a/c']);
+
+ // Only one string.
+ result = tf.graph.util.removeCommonPrefix(['a/b/c']);
+ assert.deepEqual(result, ['a/b/c']);
+
+ // `q/w/` is the common prefix. Expect `q/w/` to be removed.
+ result = tf.graph.util.removeCommonPrefix(['q/w/a', 'q/w/b', 'q/w/c/f']);
+ assert.deepEqual(result, ['a', 'b', 'c/f']);
+
+ // `q/w/` is the common prefix and also an element. Expect nothing to be
+ // removed since the common prefix is also an element in the array.
+ result = tf.graph.util.removeCommonPrefix(['q/w/', 'q/w/b', 'q/w/c/f']);
+ assert.deepEqual(result, ['q/w/', 'q/w/b', 'q/w/c/f']);
+ });
+});
diff --git a/tensorflow/tensorboard/components/tf-graph-dashboard/tf-graph-dashboard.html b/tensorflow/tensorboard/components/tf-graph-dashboard/tf-graph-dashboard.html
index 42e2e44b73..3697c97597 100644
--- a/tensorflow/tensorboard/components/tf-graph-dashboard/tf-graph-dashboard.html
+++ b/tensorflow/tensorboard/components/tf-graph-dashboard/tf-graph-dashboard.html
@@ -26,6 +26,7 @@ by default. The user can select a different run from a dropdown menu.
<tf-dashboard-layout>
<div class="sidebar">
<tf-graph-controls id="controls"
+ devices-for-stats="{{_devicesForStats}}"
color-by-params="[[_colorByParams]]"
stats="[[_stats]]"
color-by="{{_colorBy}}",
@@ -48,6 +49,7 @@ by default. The user can select a different run from a dropdown menu.
</div>
<div class="center">
<tf-graph-board id="graphboard"
+ devices-for-stats="[[_devicesForStats]]"
graph-hierarchy="[[_graphHierarchy]]"
graph="[[_graph]]"
stats="[[_stats]]"
diff --git a/tensorflow/tensorboard/components/tf-graph/demo/tf-graph-demo.html b/tensorflow/tensorboard/components/tf-graph/demo/tf-graph-demo.html
index 05256ba399..7bd31d6208 100644
--- a/tensorflow/tensorboard/components/tf-graph/demo/tf-graph-demo.html
+++ b/tensorflow/tensorboard/components/tf-graph/demo/tf-graph-demo.html
@@ -44,6 +44,7 @@ Example
<div class="all">
<div class="side">
<tf-graph-controls
+ devices-for-stats="{{_devicesForStats}}"
color-by-params="[[colorByParams]]"
stats="[[stats]]"
color-by="{{colorBy}}"
@@ -66,6 +67,7 @@ Example
</div>
<div class="main">
<tf-graph-board id="graphboard"
+ devices-for-stats="[[_devicesForStats]]"
graph-hierarchy="[[graphHierarchy]]"
graph="[[graph]]"
stats="[[stats]]"
diff --git a/tensorflow/tensorboard/components/tf-graph/tf-graph-controls.html b/tensorflow/tensorboard/components/tf-graph/tf-graph-controls.html
index 8e445dff1c..09bcff9630 100644
--- a/tensorflow/tensorboard/components/tf-graph/tf-graph-controls.html
+++ b/tensorflow/tensorboard/components/tf-graph/tf-graph-controls.html
@@ -2,6 +2,7 @@
<link rel="import" href="../paper-menu/paper-menu.html">
<link rel="import" href="../paper-dropdown-menu/paper-dropdown-menu.html">
<link rel="import" href="../paper-radio-group/paper-radio-group.html">
+<link rel="import" href="../paper-tooltip/paper-tooltip.html">
<link rel="import" href="../tf-dashboard-common/tensorboard-color.html">
<dom-module id="tf-graph-controls">
@@ -108,6 +109,12 @@ svg.icon {
height: 24px;
}
+.help-icon {
+ height: 15px;
+ margin: 0;
+ padding: 0;
+}
+
.gray {
color: #666;
}
@@ -121,7 +128,7 @@ svg.icon {
font-weight: normal;
}
.deviceList {
- max-height: 100px;
+ max-height: 200px;
overflow-y: auto;
}
@@ -267,7 +274,7 @@ span.counter {
</paper-radio-group>
</div>
<div>
- <template is="dom-if" if="[[_isGradientColoring(colorBy)]]">
+ <template is="dom-if" if="[[_isGradientColoring(stats, colorBy)]]">
<svg width="140" height="20" style="margin: 0 5px" class="color-text">
<defs>
<linearGradient id="linearGradient" x1="0%" y1="0%" x2="100%" y2="0%">
@@ -285,6 +292,27 @@ span.counter {
<div class="domainEnd">[[_currentGradientParams.maxValue]]</div>
</div>
<br style="clear: both">
+ <div>Devices included in stats:</div>
+ <div class="deviceList">
+ <table>
+ <template is="dom-repeat" items="[[_getDevices(devicesForStats)]]">
+ <tr>
+ <td>
+ <input type="checkbox" value$="[[item.device]]" checked$="[[item.used]]" on-click="_deviceCheckboxClicked"/>
+ </td>
+ <td>
+ <div>
+ <span>[[item.suffix]]</span>
+ <template is="dom-if" if="[[item.ignoredMsg]]">
+ <paper-icon-button icon="help" class="help-icon"></paper-icon-button>
+ <paper-tooltip position="right" animation-delay="0">[[item.ignoredMsg]]</paper-tooltip>
+ </template>
+ </div>
+ </td>
+ </tr>
+ </template>
+ </table>
+ </div>
</template>
<template is="dom-if" if="[[_equals(colorBy, 'structure')]]">
<div class="color-text">
@@ -339,115 +367,143 @@ span.counter {
</div>
</template>
</div>
- <div class="legend-holder">
- <table>
- <tr>
- <td><div class="title">Graph</div></td>
- <td>(* = expandable)</td>
- </tr>
- <tr>
- <td>
- <svg class="icon">
- <rect transform="translate(3, 1)" height="14" width="35"
- rx="5" ry="5"/>
- </svg>
- </td>
- <td>Namespace<span class="gray">*</span></td>
- </tr>
- <tr>
- <td>
- <svg class="icon" preserveAspectRatio="xMinYMid meet"
- viewBox="0 0 10 10">
- <use xlink:href="#op-node-stamp" fill="white" stroke="#ccc" x="9.5"
- y="6" />
- </svg>
- </td>
- <td>OpNode</td>
- </tr>
- <tr>
- <td>
- <svg class="icon" height="15px" preserveAspectRatio="xMinYMid meet"
- viewBox="0 0 12 12">
- <use xlink:href="#op-series-horizontal-stamp" fill="white"
- stroke="#ccc" x="2" y="2"/>
- </svg>
- </td>
- <td>Unconnected series<span class="gray">*</span></td>
- </tr>
- <tr>
- <td>
- <svg class="icon" height="15px"
- preserveAspectRatio="xMinYMid meet" viewBox="0 0 15 15">
- <use xlink:href="#op-series-vertical-stamp"
- fill="white" stroke="#ccc" x="2" y="2"/>
- </svg>
- </td>
- <td>Connected series<span class="gray">*</span></td>
- </tr>
- <tr>
- <td>
- <svg class="icon">
- <circle fill="white" stroke="#848484" cx="10" cy="10" r="5"/>
- </svg>
- </td>
- <td>Constant</td>
- </tr>
- <tr>
- <td>
- <svg class="image-icon" viewBox="0 0 12 12" width="24" height="24">
- <use x="0" y="0" class="image-icon" xlink:href="#summary-icon"/>
- </svg>
- </td>
- <td>Summary</td>
- </tr>
- <tr>
- <td>
- <svg class="icon" height="15px"
- preserveAspectRatio="xMinYMid meet" viewBox="0 0 15 15">
- <defs>
- <marker id="ref-arrowhead-legend" fill="#bbb" markerWidth="10"
- markerHeight="10" refX="1" refY="5" orient="auto">
- <path d="M 10,0 L 0,5 L 10,10 C 7,7 7,3 10,0"/>
- </marker>
- </defs>
- <path stroke="#bbb"
- d="M2 9 l 23 0" stroke-linecap="round" />
- </svg>
- </td>
- <td>Dataflow edge</td>
- </tr>
- <tr>
- <td>
- <svg class="icon" height="15px"
- preserveAspectRatio="xMinYMid meet" viewBox="0 0 15 15">
- <path stroke="#bbb"
- d="M2 9 l 23 0" stroke-linecap="round" stroke-dasharray="2, 2" />
- </svg>
- </td>
- <td>Control dependency edge</td>
- </tr>
- <tr>
- <td>
- <svg class="icon" height="15px"
- preserveAspectRatio="xMinYMid meet" viewBox="0 0 15 15">
- <path marker-start="url(#ref-arrowhead-legend)"
- stroke="#bbb" d="M2 9 l 23 0"
- stroke-linecap="round" />
- </svg>
- </td>
- <td>Reference edge</td>
- </tr>
- </table>
- </div>
+ <!--
+ Due to limited vertical space on the left sidebar, hide the legend whenever
+ we show a list of devices to include in stats.
+ -->
+ <template is="dom-if" if="[[!_isGradientColoring(stats, colorBy)]]">
+ <div class="legend-holder">
+ <table>
+ <tr>
+ <td><div class="title">Graph</div></td>
+ <td>(* = expandable)</td>
+ </tr>
+ <tr>
+ <td>
+ <svg class="icon">
+ <rect transform="translate(3, 1)" height="14" width="35"
+ rx="5" ry="5"/>
+ </svg>
+ </td>
+ <td>Namespace<span class="gray">*</span></td>
+ </tr>
+ <tr>
+ <td>
+ <svg class="icon" preserveAspectRatio="xMinYMid meet"
+ viewBox="0 0 10 10">
+ <use xlink:href="#op-node-stamp" fill="white" stroke="#ccc" x="9.5"
+ y="6" />
+ </svg>
+ </td>
+ <td>OpNode</td>
+ </tr>
+ <tr>
+ <td>
+ <svg class="icon" height="15px" preserveAspectRatio="xMinYMid meet"
+ viewBox="0 0 12 12">
+ <use xlink:href="#op-series-horizontal-stamp" fill="white"
+ stroke="#ccc" x="2" y="2"/>
+ </svg>
+ </td>
+ <td>Unconnected series<span class="gray">*</span></td>
+ </tr>
+ <tr>
+ <td>
+ <svg class="icon" height="15px"
+ preserveAspectRatio="xMinYMid meet" viewBox="0 0 15 15">
+ <use xlink:href="#op-series-vertical-stamp"
+ fill="white" stroke="#ccc" x="2" y="2"/>
+ </svg>
+ </td>
+ <td>Connected series<span class="gray">*</span></td>
+ </tr>
+ <tr>
+ <td>
+ <svg class="icon">
+ <circle fill="white" stroke="#848484" cx="10" cy="10" r="5"/>
+ </svg>
+ </td>
+ <td>Constant</td>
+ </tr>
+ <tr>
+ <td>
+ <svg class="image-icon" viewBox="0 0 12 12" width="24" height="24">
+ <use x="0" y="0" class="image-icon" xlink:href="#summary-icon"/>
+ </svg>
+ </td>
+ <td>Summary</td>
+ </tr>
+ <tr>
+ <td>
+ <svg class="icon" height="15px"
+ preserveAspectRatio="xMinYMid meet" viewBox="0 0 15 15">
+ <defs>
+ <marker id="ref-arrowhead-legend" fill="#bbb" markerWidth="10"
+ markerHeight="10" refX="1" refY="5" orient="auto">
+ <path d="M 10,0 L 0,5 L 10,10 C 7,7 7,3 10,0"/>
+ </marker>
+ </defs>
+ <path stroke="#bbb"
+ d="M2 9 l 23 0" stroke-linecap="round" />
+ </svg>
+ </td>
+ <td>Dataflow edge</td>
+ </tr>
+ <tr>
+ <td>
+ <svg class="icon" height="15px"
+ preserveAspectRatio="xMinYMid meet" viewBox="0 0 15 15">
+ <path stroke="#bbb"
+ d="M2 9 l 23 0" stroke-linecap="round" stroke-dasharray="2, 2" />
+ </svg>
+ </td>
+ <td>Control dependency edge</td>
+ </tr>
+ <tr>
+ <td>
+ <svg class="icon" height="15px"
+ preserveAspectRatio="xMinYMid meet" viewBox="0 0 15 15">
+ <path marker-start="url(#ref-arrowhead-legend)"
+ stroke="#bbb" d="M2 9 l 23 0"
+ stroke-linecap="round" />
+ </svg>
+ </td>
+ <td>Reference edge</td>
+ </tr>
+ </table>
+ </div>
+ </template>
</div>
</template>
<script>
(function() { // Private scope.
+/**
+ * Stats from device names that match these regexes will be excluded by default.
+ * The user can still turn on a device by selecting the checkbox in the device list.
+ * See b/29089982 for context.
+ */
+var DEVICE_NAMES_EXCLUDE = [
+ {
+ regex: /gpu:[0-9]+$/,
+ msg: 'Excluded by default since this is a CPU thread setting up GPU kernels.'
+ }
+];
+
Polymer({
is: 'tf-graph-controls',
properties: {
// Public API.
- stats: Object,
+ stats: {
+ value: null,
+ type: Object,
+ observer: '_statsChanged'
+ },
+ devicesForStats: {
+ value: null,
+ type: Object,
+ notify: true,
+ readonly: true,
+ },
colorBy: {
type: String,
value: 'structure',
@@ -486,6 +542,55 @@ Polymer({
_statsNotNull: function(stats) {
return stats != null;
},
+ _statsChanged: function(stats) {
+ if (stats == null) {
+ return;
+ }
+ var devicesForStats = {};
+ var devices = _.each(stats.dev_stats, function(d) {
+ // Avoid device names that are ignored by default.
+ var exclude = _.some(DEVICE_NAMES_EXCLUDE, function(rule) {
+ return rule.regex.test(d.device);
+ });
+ if (!exclude) {
+ devicesForStats[d.device] = true;
+ }
+ });
+ this.set('devicesForStats', devicesForStats);
+ },
+ _getDevices: function(devicesForStats) {
+ var devices = _.map(this.stats.dev_stats, function(d) {
+ return d.device;
+ });
+ // Devices names can be long so we remove the longest common prefix
+ // before showing the devices in a list.
+ var suffixes = tf.graph.util.removeCommonPrefix(devices);
+ return _.map(devices, function(device, i) {
+ var ignoredMsg = null;
+ _.each(DEVICE_NAMES_EXCLUDE, function(rule) {
+ if (rule.regex.test(device)) {
+ ignoredMsg = rule.msg;
+ }
+ });
+ return {
+ device: device,
+ suffix: suffixes[i],
+ used: devicesForStats[device],
+ ignoredMsg: ignoredMsg
+ };
+ });
+ },
+ _deviceCheckboxClicked: function(checkbox) {
+ // Update the device map.
+ var devicesForStats = _.extend({}, this.devicesForStats);
+ var device = checkbox.target.value;
+ if (checkbox.target.checked) {
+ devicesForStats[device] = true;
+ } else {
+ delete devicesForStats[device];
+ }
+ this.set('devicesForStats', devicesForStats);
+ },
_numSessionRuns: function(metadataTags) {
return metadataTags != null ? metadataTags.length : 0;
},
@@ -495,14 +600,15 @@ Polymer({
fit: function() {
document.querySelector('#scene').fit();
},
- _isGradientColoring: function(colorBy) {
- return ["compute_time", "memory"].indexOf(colorBy) !== -1;
+ _isGradientColoring: function(stats, colorBy) {
+ return ["compute_time", "memory"].indexOf(colorBy) !== -1
+ && stats != null;
},
_equals: function(a, b) {
return a === b;
},
_getCurrentGradientParams: function(colorByParams, colorBy) {
- if (!this._isGradientColoring(colorBy)) {
+ if (!this._isGradientColoring(this.stats, colorBy)) {
return;
}
var params = colorByParams[colorBy];
diff --git a/tensorflow/tensorboard/components/tf-graph/tf-graph.html b/tensorflow/tensorboard/components/tf-graph/tf-graph.html
index bf7785bd20..883ce5d14c 100644
--- a/tensorflow/tensorboard/components/tf-graph/tf-graph.html
+++ b/tensorflow/tensorboard/components/tf-graph/tf-graph.html
@@ -62,10 +62,8 @@ Polymer({
observer: '_graphChanged'
},
basicGraph: Object,
- stats: {
- type: Object,
- observer: '_statsChanged'
- },
+ stats: Object,
+ devicesForStats: Object,
hierarchyParams: Object,
progress: {
type: Object,
@@ -102,15 +100,15 @@ Polymer({
},
},
observers: [
+ '_statsChanged(stats, devicesForStats)',
'_buildRenderHierarchy(graphHierarchy)'
],
- _statsChanged: function(stats) {
+ _statsChanged: function(stats, devicesForStats) {
if (this.graphHierarchy) {
- if (stats != null) {
- tf.graph.joinStatsInfoWithGraph(this.basicGraph, stats);
+ if (stats && devicesForStats) {
+ tf.graph.joinStatsInfoWithGraph(this.basicGraph, stats, devicesForStats);
tf.graph.hierarchy.joinAndAggregateStats(this.graphHierarchy, stats);
}
-
// Recompute the rendering information.
this._buildRenderHierarchy(this.graphHierarchy);
}