diff options
Diffstat (limited to 'tensorflow/tensorboard/components/tf-graph-loader/tf-graph-loader.html')
-rw-r--r-- | tensorflow/tensorboard/components/tf-graph-loader/tf-graph-loader.html | 172 |
1 files changed, 172 insertions, 0 deletions
diff --git a/tensorflow/tensorboard/components/tf-graph-loader/tf-graph-loader.html b/tensorflow/tensorboard/components/tf-graph-loader/tf-graph-loader.html new file mode 100644 index 0000000000..3f290f2152 --- /dev/null +++ b/tensorflow/tensorboard/components/tf-graph-loader/tf-graph-loader.html @@ -0,0 +1,172 @@ +<link rel="import" href="../../bower_components/polymer/polymer.html"> + +<!-- +An element which provides a filter parsing for pbtxt to graph output. +--> +<dom-module id="tf-graph-loader"> +</dom-module> + +<script> +Polymer({ + + is: 'tf-graph-loader', + + properties: { + /** + * @type {value: number, msg: string} + * + * A number between 0 and 100 denoting the % of progress + * for the progress bar and the displayed message. + */ + progress: { + type: Object, + notify: true, + readOnly: true // Produces, does not consume. + }, + datasets: Array, + hasStats: { + type: Boolean, + readOnly: true, // This property produces data. + notify: true + }, + selectedDataset: Number, + selectedFile: { + type: Object, + observer: '_selectedFileChanged' + }, + outGraphHierarchy: { + type: Object, + readOnly: true, //readonly so outsider can't change this via binding + notify: true + }, + outGraph: { + type: Object, + readOnly: true, //readonly so outsider can't change this via binding + notify: true + }, + outGraphName: { + type: String, + readOnly: true, + notify: true + } + }, + observers: [ + '_selectedDatasetChanged(selectedDataset, datasets)' + ], + _parseAndConstructHierarchicalGraph: function(dataset, pbTxtContent) { + var self = this; + // Reset the progress bar to 0. + self._setProgress({ + value: 0, + msg: '' + }); + var tracker = { + setMessage: function(msg) { + self._setProgress({ + value: self.progress.value, + msg: msg + }); + }, + updateProgress: function(value) { + self._setProgress({ + value: self.progress.value + value, + msg: self.progress.msg + }); + }, + reportError: function(msg) { + self._setProgress({ + value: self.progress.value, + msg: msg, + error: true + }); + }, + }; + var statsJson; + var dataTracker = tf.getSubtaskTracker(tracker, 30, 'Data'); + tf.graph.parser.readAndParseData(dataset, pbTxtContent, dataTracker) + .then(function(result) { + // Build the flat graph (consists only of Op nodes). + var nodes = result.nodes; + statsJson = result.statsJson; + + // This is the whitelist of inputs on op types that are considered + // reference edges. "Assign 0" indicates that the first input to + // an OpNode with operation type "Assign" is a reference edge. + var refEdges = {}; + refEdges["Assign 0"] = true; + refEdges["AssignAdd 0"] = true; + refEdges["AssignSub 0"] = true; + refEdges["assign 0"] = true; + refEdges["assign_add 0"] = true; + refEdges["assign_sub 0"] = true; + refEdges["count_up_to 0"] = true; + refEdges["ScatterAdd 0"] = true; + refEdges["ScatterSub 0"] = true; + refEdges["ScatterUpdate 0"] = true; + refEdges["scatter_add 0"] = true; + refEdges["scatter_sub 0"] = true; + refEdges["scatter_update 0"] = true; + var buildParams = { + enableEmbedding: true, + inEmbeddingTypes: ['Const'], + outEmbeddingTypes: ['^[a-zA-Z]+Summary$'], + refEdges: refEdges + }; + var graphTracker = tf.getSubtaskTracker(tracker, 20, + 'Graph'); + return tf.graph.build(nodes, buildParams, graphTracker); + }) + .then(function(graph) { + this._setOutGraph(graph); + if (statsJson) { + // If there are associated stats, join them with the graph. + tf.time('Joining stats info with graph...', function() { + tf.graph.joinStatsInfoWithGraph(graph, statsJson); + }); + } + var hierarchyParams = { + verifyTemplate: true, + groupSeries: true, + }; + var hierarchyTracker = tf.getSubtaskTracker(tracker, 50, + 'Namespace hierarchy'); + return tf.graph.hierarchy.build(graph, hierarchyParams, hierarchyTracker); + }.bind(this)) + .then(function(graphHierarchy) { + // Update the properties which notify the parent with the + // graph hierarchy and whether the data has live stats or not. + this._setHasStats(statsJson != null); + this._setOutGraphHierarchy(graphHierarchy); + }.bind(this)) + .catch(function(reason) { + tracker.reportError("Graph visualization failed: " + reason); + }); + }, + _selectedDatasetChanged: function(datasetIndex, datasets) { + var dataset = datasets[datasetIndex]; + this._parseAndConstructHierarchicalGraph(dataset); + this._setOutGraphName(dataset.name); + }, + _selectedFileChanged: function(e) { + if (!e) { + return; + } + var file = e.target.files[0]; + if (!file) { + return; + } + + // Clear out the value of the file chooser. This ensures that if the user + // selects the same file, we'll re-read it. + e.target.value = ''; + + var reader = new FileReader(); + + reader.onload = function(e) { + this._parseAndConstructHierarchicalGraph(null, e.target.result); + }.bind(this); + + reader.readAsText(file); + } +}); +</script> |