MCPcopy Create free account
hub / github.com/DeepRec-AI/DeepRec / StrongConnect

Function StrongConnect

tensorflow/core/grappler/utils/scc.cc:57–115  ·  view source on GitHub ↗

Core DFS step of Tarjan's Strongly Connected Component algorithm (implemented using iteration instead of recursion).

Source from the content-addressed store, hash-verified

55// Core DFS step of Tarjan's Strongly Connected Component algorithm
56// (implemented using iteration instead of recursion).
57void StrongConnect(SCCNodeData* v, std::stack<SCCNodeData*>* stack, int* index,
58 std::unordered_map<const NodeDef*, int>* components,
59 int* scc_index) {
60 // Iterative version of Tarjan's StrongConnect function.
61 // The "call stack" state is composed of a SCCNodeData's caller and
62 // caller_loop_location properties.
63 v->ResetStack(*index /* index */, nullptr /* caller */);
64 ++*index;
65 stack->push(v);
66
67 // No one put v on a StrongConnect call stack, reset caller values.
68 v->caller = nullptr;
69 v->caller_loop_location = 0;
70
71 SCCNodeData* last = v;
72 while (true) {
73 if (last->caller_loop_location < last->children.size()) {
74 // Recursive equivalent: Looping over the children of v (possibly
75 // continuing at v->caller_loop_location after having finished a
76 // recursive call.
77 SCCNodeData* w = last->children[last->caller_loop_location];
78 ++(last->caller_loop_location); // For loop iterator increment
79 if (w->index == -1) {
80 w->ResetStack(*index /* index */, last /* caller */);
81 ++*index;
82 stack->push(w);
83 last = w;
84 } else if (w->onstack == true) {
85 last->lowlink = std::min(last->lowlink, w->index);
86 }
87 } else {
88 // At the end of v's children
89 if (last->lowlink == last->index) {
90 // v is the root of a strongly connected component
91 SCCNodeData* top;
92 while (true) {
93 top = stack->top();
94 stack->pop();
95 top->onstack = false;
96 (*components)[top->node] = *scc_index;
97 if (top == last) {
98 break;
99 }
100 }
101 ++*scc_index;
102 }
103
104 // Go up the recursive call stack
105 SCCNodeData* next_last = last->caller;
106 if (next_last == nullptr) {
107 // All nodes have been seen; finished.
108 break;
109 } else {
110 next_last->lowlink = std::min(next_last->lowlink, last->lowlink);
111 last = next_last;
112 }
113 }
114 }

Callers 1

Calls 5

ResetStackMethod · 0.80
minFunction · 0.50
pushMethod · 0.45
sizeMethod · 0.45
popMethod · 0.45

Tested by

no test coverage detected