From 4fcf863963ccb8191d0bd84ed5b4a852e1961ef8 Mon Sep 17 00:00:00 2001 From: "A. Unique TensorFlower" Date: Mon, 23 May 2016 13:47:48 -0800 Subject: [PATCH 01/55] 1.Add bzl function if_android and if_not_android. 2.Make core/platform/google/build_config:gtest portable. Change: 123039572 --- tensorflow/tensorflow.bzl | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/tensorflow/tensorflow.bzl b/tensorflow/tensorflow.bzl index c7fcbc81e85..acc01eae849 100644 --- a/tensorflow/tensorflow.bzl +++ b/tensorflow/tensorflow.bzl @@ -86,10 +86,22 @@ def tf_proto_text_protos_relative(): return [p for p in tf_android_core_proto_sources_relative() if p not in ("util/test_log.proto")] -def if_android_arm(a, b=[]): +def if_android_arm(a): return select({ "//tensorflow:android_arm": a, - "//conditions:default": b, + "//conditions:default": [], + }) + +def if_not_android(a): + return select({ + "//tensorflow:android": [], + "//conditions:default": a, + }) + +def if_android(a): + return select({ + "//tensorflow:android": a, + "//conditions:default": [], }) def tf_copts(): From aec225cbc1d6c2dd9ee51e09996a38c868e9e2dd Mon Sep 17 00:00:00 2001 From: Derek Murray Date: Mon, 23 May 2016 13:57:58 -0800 Subject: [PATCH 02/55] Suppresses AssertionError when using InteractiveSession. The following code would previously raise an AssertionError in the garbage collector: ```python sess = tf.InteractiveSession() sess = tf.InteractiveSession() ``` This happens because the second session will be installed on the default session stack before the first session is destroyed, which leads to the assertion (of strict nesting) failing. Since this is common behavior in IPython notebooks, we suppress this error for InteractiveSession objects. Fixes #2474. Change: 123040755 --- tensorflow/python/client/session.py | 2 ++ tensorflow/python/client/session_test.py | 24 +++++++++++++++++++++++- tensorflow/python/framework/ops.py | 20 +++++++++++++++++--- 3 files changed, 42 insertions(+), 4 deletions(-) diff --git a/tensorflow/python/client/session.py b/tensorflow/python/client/session.py index e327fec3304..32f0e3f6ceb 100644 --- a/tensorflow/python/client/session.py +++ b/tensorflow/python/client/session.py @@ -900,10 +900,12 @@ class InteractiveSession(BaseSession): super(InteractiveSession, self).__init__(target, graph, config) self._default_session = self.as_default() + self._default_session.enforce_nesting = False self._default_session.__enter__() self._explicit_graph = graph if self._explicit_graph is not None: self._default_graph = graph.as_default() + self._default_graph.enforce_nesting = False self._default_graph.__enter__() def close(self): diff --git a/tensorflow/python/client/session_test.py b/tensorflow/python/client/session_test.py index c2e69ea1131..c3cce65a9bf 100644 --- a/tensorflow/python/client/session_test.py +++ b/tensorflow/python/client/session_test.py @@ -1138,11 +1138,33 @@ class SessionTest(test_util.TensorFlowTestCase): d = math_ops.mul(c, c) for step in xrange(120): run_metadata = config_pb2.RunMetadata() - sess.run(d, feed_dict={a: 1.0}, options=run_options, run_metadata=run_metadata) + sess.run(d, feed_dict={a: 1.0}, + options=run_options, run_metadata=run_metadata) if step == 99: self.assertTrue(run_metadata.HasField('cost_graph')) else: self.assertFalse(run_metadata.HasField('cost_graph')) + def testNonInteractiveSessionNesting(self): + sess1 = session.Session() + sess1_controller = sess1.as_default() + sess1_controller.__enter__() + + sess2 = session.Session() + sess2_controller = sess2.as_default() + sess2_controller.__enter__() + + with self.assertRaisesRegexp(AssertionError, 'Nesting violated'): + sess1_controller.__exit__(None, None, None) + + ops._default_session_stack.reset() + + def testInteractiveSessionNesting(self): + sess1 = session.InteractiveSession() + sess2 = session.InteractiveSession() + del sess1 + del sess2 + + if __name__ == '__main__': googletest.main() diff --git a/tensorflow/python/framework/ops.py b/tensorflow/python/framework/ops.py index 2667b544cce..9a0234dd164 100644 --- a/tensorflow/python/framework/ops.py +++ b/tensorflow/python/framework/ops.py @@ -3306,6 +3306,7 @@ class _DefaultStack(threading.local): def __init__(self): super(_DefaultStack, self).__init__() + self._enforce_nesting = True self.stack = [] def get_default(self): @@ -3314,6 +3315,14 @@ class _DefaultStack(threading.local): def reset(self): self.stack = [] + @property + def enforce_nesting(self): + return self._enforce_nesting + + @enforce_nesting.setter + def enforce_nesting(self, value): + self._enforce_nesting = value + @contextlib.contextmanager def get_controller(self, default): """A context manager for manipulating a default stack.""" @@ -3321,9 +3330,14 @@ class _DefaultStack(threading.local): self.stack.append(default) yield default finally: - assert self.stack[-1] is default - self.stack.pop() - + if self._enforce_nesting: + if self.stack[-1] is not default: + raise AssertionError( + "Nesting violated for default stack of %s objects" + % type(default)) + self.stack.pop() + else: + self.stack.remove(default) _default_session_stack = _DefaultStack() From 6e95013e505db08916c8cff0e8b585c29899c0c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dan=20Man=C3=A9?= Date: Mon, 23 May 2016 14:38:11 -0800 Subject: [PATCH 03/55] Fix a bug where the scalar chart would print errors to console. Should not have any visible change to users who don't open their consoles. Change: 123045624 --- .../tensorboard/components/tf-event-dashboard/tf-chart.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tensorflow/tensorboard/components/tf-event-dashboard/tf-chart.ts b/tensorflow/tensorboard/components/tf-event-dashboard/tf-chart.ts index 852369abbbe..21daf50800f 100644 --- a/tensorflow/tensorboard/components/tf-event-dashboard/tf-chart.ts +++ b/tensorflow/tensorboard/components/tf-event-dashboard/tf-chart.ts @@ -293,7 +293,8 @@ module TF { let points = plot.datasets().map( (dataset) => this.findClosestPoint(target, dataset)); let pointsToCircle = points.filter( - (p) => Plottable.Utils.DOM.intersectsBBox(p.x, p.y, centerBBox)); + (p) => p != null && + Plottable.Utils.DOM.intersectsBBox(p.x, p.y, centerBBox)); let pts: any = pointsComponent.content().selectAll('.point').data( pointsToCircle, (p: Point) => p.dataset.metadata().run); if (points.length !== 0) { From d142d4f3941fe95ef3877a006d3a653c44e71643 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dan=20Man=C3=A9?= Date: Mon, 23 May 2016 14:40:52 -0800 Subject: [PATCH 04/55] Fix bug where tf-run-selector would not update on click properly if run names have periods. It is because Polymer.notifyPath doesn't work on keys that contain periods, see: https://github.com/Polymer/polymer/issues/3675 Fix the issue (hackily) by just cloning the array. Change: 123045948 --- .../components/tf-multi-checkbox/tf-multi-checkbox.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tensorflow/tensorboard/components/tf-multi-checkbox/tf-multi-checkbox.html b/tensorflow/tensorboard/components/tf-multi-checkbox/tf-multi-checkbox.html index a5db63a5e2a..6ae2a573624 100644 --- a/tensorflow/tensorboard/components/tf-multi-checkbox/tf-multi-checkbox.html +++ b/tensorflow/tensorboard/components/tf-multi-checkbox/tf-multi-checkbox.html @@ -200,7 +200,8 @@ handle these situations gracefully. var name = e.srcElement.name; var checked = e.srcElement.checked; this.runToIsCheckedMapping[name] = checked; - this.notifyPath("runToIsCheckedMapping." + name, checked); + // n.b. notifyPath won't work because run names may have periods. + this.runToIsCheckedMapping = _.clone(this.runToIsCheckedMapping); }, _isChecked: function(item, outSelectedChange) { return this.runToIsCheckedMapping[item]; From 5ab5d97710e27022b789939b26f63386abdfb526 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dan=20Man=C3=A9?= Date: Mon, 23 May 2016 14:50:45 -0800 Subject: [PATCH 05/55] Autogenerated Change: Release TensorBoard at TAG: 20 Change: 123047093 --- WORKSPACE | 4 +- tensorflow/tensorboard/TAG | 2 +- tensorflow/tensorboard/bower.json | 4 +- .../tensorboard/dist/tf-tensorboard.html | 241 +++++++++++++++--- 4 files changed, 212 insertions(+), 39 deletions(-) diff --git a/WORKSPACE b/WORKSPACE index 649af646031..1156a45a39e 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -117,7 +117,7 @@ new_git_repository( name = "iron_fit_behavior", build_file = "bower.BUILD", remote = "https://github.com/polymerelements/iron-fit-behavior.git", - tag = "v1.2.1", + tag = "v1.2.2", ) new_git_repository( @@ -194,7 +194,7 @@ new_git_repository( name = "iron_range_behavior", build_file = "bower.BUILD", remote = "https://github.com/polymerelements/iron-range-behavior.git", - tag = "v1.0.4", + tag = "v1.0.5", ) new_git_repository( diff --git a/tensorflow/tensorboard/TAG b/tensorflow/tensorboard/TAG index 209e3ef4b62..aabe6ec3909 100644 --- a/tensorflow/tensorboard/TAG +++ b/tensorflow/tensorboard/TAG @@ -1 +1 @@ -20 +21 diff --git a/tensorflow/tensorboard/bower.json b/tensorflow/tensorboard/bower.json index 0522cb8dff9..1a082fbb816 100644 --- a/tensorflow/tensorboard/bower.json +++ b/tensorflow/tensorboard/bower.json @@ -55,7 +55,7 @@ "iron-list": "PolymerElements/iron-list#1.1.7", "iron-menu-behavior": "PolymerElements/iron-menu-behavior#1.1.5", "iron-meta": "PolymerElements/iron-meta#1.1.1", - "iron-overlay-behavior": "PolymerElements/iron-overlay-behavior#1.7.2", + "iron-overlay-behavior": "PolymerElements/iron-overlay-behavior#1.7.6", "iron-range-behavior": "PolymerElements/iron-range-behavior#1.0.4", "iron-resizable-behavior": "PolymerElements/iron-resizable-behavior#1.0.3", "iron-selector": "PolymerElements/iron-selector#1.2.4", @@ -129,7 +129,7 @@ "iron-list": "1.1.7", "iron-menu-behavior": "1.1.5", "iron-meta": "1.1.1", - "iron-overlay-behavior": "1.7.2", + "iron-overlay-behavior": "1.7.6", "iron-range-behavior": "1.0.4", "iron-resizable-behavior": "1.0.3", "iron-selector": "1.2.4", diff --git a/tensorflow/tensorboard/dist/tf-tensorboard.html b/tensorflow/tensorboard/dist/tf-tensorboard.html index be22f17b4f4..b54882c373b 100644 --- a/tensorflow/tensorboard/dist/tf-tensorboard.html +++ b/tensorflow/tensorboard/dist/tf-tensorboard.html @@ -358,7 +358,8 @@ var TF; var name = e.srcElement.name; var checked = e.srcElement.checked; this.runToIsCheckedMapping[name] = checked; - this.notifyPath("runToIsCheckedMapping." + name, checked); + // n.b. notifyPath won't work because run names may have periods. + this.runToIsCheckedMapping = _.clone(this.runToIsCheckedMapping); }, _isChecked: function(item, outSelectedChange) { return this.runToIsCheckedMapping[item]; @@ -453,6 +454,7 @@ var TF; --tb-grey-lighter: #f3f3f3; --tb-ui-dark-accent: #757575; --tb-ui-light-accent: #e0e0e0; + --tb-graph-faded: #e0d4b3; } @@ -1541,7 +1543,8 @@ var TF; }; var centerBBox = _this.gridlines.content().node().getBBox(); var points = plot.datasets().map(function (dataset) { return _this.findClosestPoint(target, dataset); }); - var pointsToCircle = points.filter(function (p) { return Plottable.Utils.DOM.intersectsBBox(p.x, p.y, centerBBox); }); + var pointsToCircle = points.filter(function (p) { return p != null && + Plottable.Utils.DOM.intersectsBBox(p.x, p.y, centerBBox); }); var pts = pointsComponent.content().selectAll('.point').data(pointsToCircle, function (p) { return p.dataset.metadata().run; }); if (points.length !== 0) { pts.enter().append('circle').classed('point', true); @@ -3697,16 +3700,16 @@ Polymer({ }, observers: [ '_selectedDatasetChanged(selectedDataset, datasets)', - '_readAndParseMetadata(selectedDataset, selectedMetadataTag, datasets)' + '_readAndParseMetadata(selectedMetadataTag)' ], - _readAndParseMetadata: function(datasetIndex, metadataIndex, datasets) { - if (metadataIndex == -1 || datasets[datasetIndex] == null || - datasets[datasetIndex].runMetadata == null || - datasets[datasetIndex].runMetadata[metadataIndex] == null) { + _readAndParseMetadata: function(metadataIndex) { + if (metadataIndex == -1 || this.datasets[this.selectedDataset] == null || + this.datasets[this.selectedDataset].runMetadata == null || + this.datasets[this.selectedDataset].runMetadata[metadataIndex] == null) { this._setOutStats(null); return; } - var path = datasets[datasetIndex].runMetadata[metadataIndex].path; + var path = this.datasets[this.selectedDataset].runMetadata[metadataIndex].path; // Reset the progress bar to 0. this.set('progress', { value: 0, @@ -6577,8 +6580,9 @@ var tf; * for each node in the graph. */ var RenderGraphInfo = (function () { - function RenderGraphInfo(hierarchy) { + function RenderGraphInfo(hierarchy, displayingStats) { this.hierarchy = hierarchy; + this.displayingStats = displayingStats; this.index = {}; this.computeScales(); // Maps node name to whether the rendering hierarchy was already @@ -6663,6 +6667,9 @@ var tf; renderInfo.computeTimeColor = this.computeTimeScale(node.stats.totalMicros); } + // We only fade nodes when we're displaying stats. + renderInfo.isFadedOut = this.displayingStats && + !tf.graph.util.hasDisplayableNodeStats(node.stats); if (node.isGroupNode) { // Make a list of tuples (device, proportion), where proportion // is the fraction of op nodes that have that device. @@ -6768,6 +6775,8 @@ var tf; _.each(metagraph.edges(), function (edgeObj) { var metaedge = metagraph.edge(edgeObj); var renderMetaedgeInfo = new RenderMetaedgeInfo(metaedge); + renderMetaedgeInfo.isFadedOut = + _this.index[edgeObj.v].isFadedOut || _this.index[edgeObj.w].isFadedOut; coreGraph.setEdge(edgeObj.v, edgeObj.w, renderMetaedgeInfo); }); if (PARAMS.enableExtraction && @@ -7220,6 +7229,8 @@ var tf; this.isInExtract = false; this.isOutExtract = false; this.coreBox = { width: 0, height: 0 }; + // By default, we don't fade nodes out. Default to false for safety. + this.isFadedOut = false; } RenderNodeInfo.prototype.isInCore = function () { return !this.isInExtract && !this.isOutExtract; @@ -7237,6 +7248,7 @@ var tf; this.adjoiningMetaedge = null; this.structural = false; this.weight = 1; + this.isFadedOut = false; } return RenderMetaedgeInfo; }()); @@ -8197,6 +8209,7 @@ var tf; * d's label property will be a RenderMetaedgeInfo object. */ function stylize(edgeGroup, d, stylize) { + edgeGroup.classed('faded', d.label.isFadedOut); var metaedge = d.label.metaedge; edgeGroup.select('path.' + scene.Class.Edge.LINE) .classed('control-dep', metaedge && !metaedge.numRegularEdges); @@ -8600,7 +8613,10 @@ var tf; stampType = groupNodeInfo.node.hasNonControlEdges ? 'vertical' : 'horizontal'; } - scene.selectOrCreateChild(shapeGroup, 'use', scene.Class.Node.COLOR_TARGET) + scene + .selectOrCreateChild(shapeGroup, 'use', scene.Class.Node.COLOR_TARGET + ' ' + groupNodeInfo.isFadedOut ? + 'faded-ellipse' : + '') .attr('xlink:href', '#op-series-' + stampType + '-stamp'); scene.selectOrCreateChild(shapeGroup, 'rect', scene.Class.Node.COLOR_TARGET) .attr({ rx: d.radius, ry: d.radius }); @@ -8782,10 +8798,12 @@ var tf; var isSelected = sceneElement.isNodeSelected(renderInfo.node.name); var isExtract = renderInfo.isInExtract || renderInfo.isOutExtract; var isExpanded = renderInfo.expanded; + var isFadedOut = renderInfo.isFadedOut; nodeGroup.classed('highlighted', isHighlighted); nodeGroup.classed('selected', isSelected); nodeGroup.classed('extract', isExtract); nodeGroup.classed('expanded', isExpanded); + nodeGroup.classed('faded', isFadedOut); // Main node always exists here and it will be reached before subscene, // so d3 selection is fine here. var node = nodeGroup.select('.' + nodeClass + ' .' + scene.Class.Node.COLOR_TARGET); @@ -9677,6 +9695,14 @@ var tf; return (value.toPrecision(3) - 0) + ' ' + units[unitIndex].symbol; } util.convertUnitsToHumanReadable = convertUnitsToHumanReadable; + function hasDisplayableNodeStats(stats) { + if (stats && + (stats.totalBytes > 0 || stats.totalMicros > 0 || stats.outputSize)) { + return true; + } + return false; + } + util.hasDisplayableNodeStats = hasDisplayableNodeStats; })(util = graph.util || (graph.util = {})); })(graph = tf.graph || (tf.graph = {})); })(tf || (tf = {})); @@ -10083,6 +10109,34 @@ Polymer({ stroke-width: 4; } +::content .faded, +::content .faded rect, +::content .faded ellipse, +::content .faded path, +::content #rectHatch line, +::content #ellipseHatch line { + color: var(--tb-graph-faded) !important; + fill: white; + stroke: var(--tb-graph-faded) !important; +} + + +::content .faded path { + stroke-width: 1px !important; +} + +::content .faded rect { + fill: url("#rectHatch") !important; +} + +::content .faded ellipse { + fill: url("#ellipseHatch") !important; +} + +::content .faded text { + opacity: 0; +} + /* --- Op Node --- */ @@ -10232,10 +10286,18 @@ Polymer({ marker-end: url("#annotation-arrowhead"); } +::content .faded .annotation > .annotation-edge { + marker-end: url("#annotation-arrowhead-faded"); +} + ::content .annotation > .annotation-edge.refline { marker-start: url("#ref-annotation-arrowhead"); } +::content .faded .annotation > .annotation-edge.refline { + marker-start: url("#ref-annotation-arrowhead-faded"); +} + ::content .annotation > .annotation-control-edge { stroke-dasharray: 1, 1; } @@ -10244,10 +10306,18 @@ Polymer({ fill: #aaa; } +::content #annotation-arrowhead-faded { + fill: var(--tb-graph-faded); +} + ::content #ref-annotation-arrowhead { fill: #aaa; } +::content #ref-annotation-arrowhead-faded { + fill: var(--tb-graph-faded); +} + ::content .annotation > .annotation-label { font-size: 5px; cursor: pointer; @@ -10398,9 +10468,15 @@ Polymer({ + + + + + + @@ -10428,6 +10504,14 @@ Polymer({ + + + + + + + + @@ -10908,9 +10992,12 @@ Polymer({ '_buildRenderHierarchy(graphHierarchy)' ], _statsChanged: function(stats) { - if (stats != null) { - tf.graph.joinStatsInfoWithGraph(this.basicGraph, stats); - tf.graph.hierarchy.joinAndAggregateStats(this.graphHierarchy, stats); + if (this.graphHierarchy) { + if (stats != null) { + tf.graph.joinStatsInfoWithGraph(this.basicGraph, stats); + tf.graph.hierarchy.joinAndAggregateStats(this.graphHierarchy, stats); + } + // Recompute the rendering information. this._buildRenderHierarchy(this.graphHierarchy); } @@ -10923,7 +11010,8 @@ Polymer({ // and thus mistakenly pass non-metanode to this module. return; } - var renderGraph = new tf.graph.render.RenderGraphInfo(graphHierarchy); + var renderGraph = new tf.graph.render.RenderGraphInfo( + graphHierarchy, !!this.stats /** displayingStats */); // Producing the 'color by' parameters to be consumed // by the tf-graph-controls panel. It contains information about the // min and max values and their respective colors, as well as list @@ -11083,6 +11171,19 @@ Polymer({ }); +