1c8b59c046895fa5b6d79f73e0b5817330fcfbfc1A. Unique TensorFlower/* Copyright 2015 The TensorFlow Authors. All Rights Reserved. 29c3043ff3bf31a6a81810b4ce9e87ef936f1f529Manjunath Kudlur 39c3043ff3bf31a6a81810b4ce9e87ef936f1f529Manjunath KudlurLicensed under the Apache License, Version 2.0 (the "License"); 49c3043ff3bf31a6a81810b4ce9e87ef936f1f529Manjunath Kudluryou may not use this file except in compliance with the License. 59c3043ff3bf31a6a81810b4ce9e87ef936f1f529Manjunath KudlurYou may obtain a copy of the License at 69c3043ff3bf31a6a81810b4ce9e87ef936f1f529Manjunath Kudlur 79c3043ff3bf31a6a81810b4ce9e87ef936f1f529Manjunath Kudlur http://www.apache.org/licenses/LICENSE-2.0 89c3043ff3bf31a6a81810b4ce9e87ef936f1f529Manjunath Kudlur 99c3043ff3bf31a6a81810b4ce9e87ef936f1f529Manjunath KudlurUnless required by applicable law or agreed to in writing, software 109c3043ff3bf31a6a81810b4ce9e87ef936f1f529Manjunath Kudlurdistributed under the License is distributed on an "AS IS" BASIS, 119c3043ff3bf31a6a81810b4ce9e87ef936f1f529Manjunath KudlurWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 129c3043ff3bf31a6a81810b4ce9e87ef936f1f529Manjunath KudlurSee the License for the specific language governing permissions and 139c3043ff3bf31a6a81810b4ce9e87ef936f1f529Manjunath Kudlurlimitations under the License. 149c3043ff3bf31a6a81810b4ce9e87ef936f1f529Manjunath Kudlur==============================================================================*/ 159c3043ff3bf31a6a81810b4ce9e87ef936f1f529Manjunath Kudlur 16f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur#ifndef TENSORFLOW_GRAPH_ALGORITHM_H_ 17f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur#define TENSORFLOW_GRAPH_ALGORITHM_H_ 18f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur 19f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur#include <functional> 20f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur#include <unordered_set> 21b481783fe0e00a86f6feb20a8dcad5fc4fc936a4Josh Levenberg#include <vector> 22f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur 23f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur#include "tensorflow/core/graph/graph.h" 24965d620104d375c5fd2b18881f353eb41d9a63a2A. Unique TensorFlower#include "tensorflow/core/lib/gtl/array_slice.h" 25f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur 26f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlurnamespace tensorflow { 27f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur 28c71aea70f84e582854f365665899c3045d1a48f0Yunxing Dai// Comparator for two nodes. This is used in order to get a stable ording. 29c71aea70f84e582854f365665899c3045d1a48f0Yunxing Daiusing NodeComparator = std::function<bool(const Node*, const Node*)>; 30c71aea70f84e582854f365665899c3045d1a48f0Yunxing Dai 31c71aea70f84e582854f365665899c3045d1a48f0Yunxing Dai// Compares two node based on their ids. 32c71aea70f84e582854f365665899c3045d1a48f0Yunxing Daistruct NodeComparatorID { 33c71aea70f84e582854f365665899c3045d1a48f0Yunxing Dai bool operator()(const Node* n1, const Node* n2) const { 34c71aea70f84e582854f365665899c3045d1a48f0Yunxing Dai return n1->id() < n2->id(); 35c71aea70f84e582854f365665899c3045d1a48f0Yunxing Dai } 36c71aea70f84e582854f365665899c3045d1a48f0Yunxing Dai}; 37c71aea70f84e582854f365665899c3045d1a48f0Yunxing Dai 38c71aea70f84e582854f365665899c3045d1a48f0Yunxing Dai// Compare two nodes based on their names. 39c71aea70f84e582854f365665899c3045d1a48f0Yunxing Daistruct NodeComparatorName { 40c71aea70f84e582854f365665899c3045d1a48f0Yunxing Dai bool operator()(const Node* n1, const Node* n2) const { 41c71aea70f84e582854f365665899c3045d1a48f0Yunxing Dai return n1->name() < n2->name(); 42c71aea70f84e582854f365665899c3045d1a48f0Yunxing Dai } 43c71aea70f84e582854f365665899c3045d1a48f0Yunxing Dai}; 44c71aea70f84e582854f365665899c3045d1a48f0Yunxing Dai 45f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur// Perform a depth-first-search on g starting at the source node. 46f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur// If enter is not empty, calls enter(n) before visiting any children of n. 47f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur// If leave is not empty, calls leave(n) after visiting all children of n. 48c71aea70f84e582854f365665899c3045d1a48f0Yunxing Dai// If stable_comparator is set, a stable ordering of visit is achieved by 49c71aea70f84e582854f365665899c3045d1a48f0Yunxing Dai// sorting a node's neighbors first before visiting them. 50965d620104d375c5fd2b18881f353eb41d9a63a2A. Unique TensorFlowerextern void DFS(const Graph& g, const std::function<void(Node*)>& enter, 51c71aea70f84e582854f365665899c3045d1a48f0Yunxing Dai const std::function<void(Node*)>& leave, 52c71aea70f84e582854f365665899c3045d1a48f0Yunxing Dai const NodeComparator& stable_comparator = {}); 53f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur 5471184628900752e0602c93332918061c7c337f7aManjunath Kudlur// Perform a reverse depth-first-search on g starting at the sink node. 5571184628900752e0602c93332918061c7c337f7aManjunath Kudlur// If enter is not empty, calls enter(n) before visiting any parents of n. 5671184628900752e0602c93332918061c7c337f7aManjunath Kudlur// If leave is not empty, calls leave(n) after visiting all parents of n. 57c71aea70f84e582854f365665899c3045d1a48f0Yunxing Dai// If stable_comparator is set, a stable ordering of visit is achieved by 58c71aea70f84e582854f365665899c3045d1a48f0Yunxing Dai// sorting a node's neighbors first before visiting them. 59965d620104d375c5fd2b18881f353eb41d9a63a2A. Unique TensorFlowerextern void ReverseDFS(const Graph& g, const std::function<void(Node*)>& enter, 60c71aea70f84e582854f365665899c3045d1a48f0Yunxing Dai const std::function<void(Node*)>& leave, 61c71aea70f84e582854f365665899c3045d1a48f0Yunxing Dai const NodeComparator& stable_comparator = {}); 62965d620104d375c5fd2b18881f353eb41d9a63a2A. Unique TensorFlower 63965d620104d375c5fd2b18881f353eb41d9a63a2A. Unique TensorFlower// Perform a reverse depth-first-search on g starting at the 'start' nodes. 64965d620104d375c5fd2b18881f353eb41d9a63a2A. Unique TensorFlower// If enter is not empty, calls enter(n) before visiting any parents of n. 65965d620104d375c5fd2b18881f353eb41d9a63a2A. Unique TensorFlower// If leave is not empty, calls leave(n) after visiting all parents of n. 66c71aea70f84e582854f365665899c3045d1a48f0Yunxing Dai// If stable_comparator is set, a stable ordering of visit is achieved by 67c71aea70f84e582854f365665899c3045d1a48f0Yunxing Dai// sorting a node's neighbors first before visiting them. 68965d620104d375c5fd2b18881f353eb41d9a63a2A. Unique TensorFlowerextern void ReverseDFSFrom(const Graph& g, gtl::ArraySlice<Node*> start, 69965d620104d375c5fd2b18881f353eb41d9a63a2A. Unique TensorFlower const std::function<void(Node*)>& enter, 70c71aea70f84e582854f365665899c3045d1a48f0Yunxing Dai const std::function<void(Node*)>& leave, 71c71aea70f84e582854f365665899c3045d1a48f0Yunxing Dai const NodeComparator& stable_comparator = {}); 72dae1f7af9530b6f5ac752b6a55a3a2275550befcA. Unique TensorFlowerextern void ReverseDFSFrom(const Graph& g, gtl::ArraySlice<const Node*> start, 73dae1f7af9530b6f5ac752b6a55a3a2275550befcA. Unique TensorFlower const std::function<void(const Node*)>& enter, 74dae1f7af9530b6f5ac752b6a55a3a2275550befcA. Unique TensorFlower const std::function<void(const Node*)>& leave, 75dae1f7af9530b6f5ac752b6a55a3a2275550befcA. Unique TensorFlower const NodeComparator& stable_comparator = {}); 7671184628900752e0602c93332918061c7c337f7aManjunath Kudlur 77f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur// Stores in *order the post-order numbering of all nodes 78f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur// in graph found via a depth first search starting at the source node. 79f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur// 80ee40b6e6e646eb31adf1867fda370380a7dc74e8Manjunath Kudlur// Note that this is equivalent to reverse topological sorting when the 81f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur// graph does not have cycles. 82f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur// 83c71aea70f84e582854f365665899c3045d1a48f0Yunxing Dai// If stable_comparator is set, a stable ordering of visit is achieved by 84c71aea70f84e582854f365665899c3045d1a48f0Yunxing Dai// sorting a node's neighbors first before visiting them. 85c71aea70f84e582854f365665899c3045d1a48f0Yunxing Dai// 86f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur// REQUIRES: order is not NULL. 87c71aea70f84e582854f365665899c3045d1a48f0Yunxing Daivoid GetPostOrder(const Graph& g, std::vector<Node*>* order, 88c71aea70f84e582854f365665899c3045d1a48f0Yunxing Dai const NodeComparator& stable_comparator = {}); 89f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur 90f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur// Stores in *order the reverse post-order numbering of all nodes 91c71aea70f84e582854f365665899c3045d1a48f0Yunxing Dai// If stable_comparator is set, a stable ordering of visit is achieved by 92c71aea70f84e582854f365665899c3045d1a48f0Yunxing Dai// sorting a node's neighbors first before visiting them. 93c71aea70f84e582854f365665899c3045d1a48f0Yunxing Daivoid GetReversePostOrder(const Graph& g, std::vector<Node*>* order, 94c71aea70f84e582854f365665899c3045d1a48f0Yunxing Dai const NodeComparator& stable_comparator = {}); 95f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur 96f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur// Prune nodes in "g" that are not in some path from the source node 97fc7a945a602bab69e3824f514320ac9aea66f494A. Unique TensorFlower// to any node in 'nodes'. Returns true if changes were made to the graph. 98fc7a945a602bab69e3824f514320ac9aea66f494A. Unique TensorFlower// Does not fix up source and sink edges. 99fc7a945a602bab69e3824f514320ac9aea66f494A. Unique TensorFlowerbool PruneForReverseReachability(Graph* g, 100fc7a945a602bab69e3824f514320ac9aea66f494A. Unique TensorFlower std::unordered_set<const Node*> nodes); 101f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur 102f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur// Connect all nodes with no incoming edges to source. 103f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur// Connect all nodes with no outgoing edges to sink. 104e830638148e203a2d9cf491e4693d35661a360d1A. Unique TensorFlower// 105e830638148e203a2d9cf491e4693d35661a360d1A. Unique TensorFlower// Returns true if and only if 'g' is mutated. 106e830638148e203a2d9cf491e4693d35661a360d1A. Unique TensorFlowerbool FixupSourceAndSinkEdges(Graph* g); 107f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur 108f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur} // namespace tensorflow 109f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur 110f41959ccb2d9d4c722fe8fc3351401d53bcf490Manjunath Kudlur#endif // TENSORFLOW_GRAPH_ALGORITHM_H_ 111