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