Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Tetragramm
GitHub Repository: Tetragramm/opencv
Path: blob/master/modules/gapi/src/compiler/passes/helpers.cpp
16345 views
1
// This file is part of OpenCV project.
2
// It is subject to the license terms in the LICENSE file found in the top-level directory
3
// of this distribution and at http://opencv.org/license.html.
4
//
5
// Copyright (C) 2018 Intel Corporation
6
7
8
#include "precomp.hpp"
9
10
#include <algorithm> // copy
11
#include <unordered_map>
12
#include <unordered_set>
13
14
#include <ade/util/filter_range.hpp>
15
16
#include "opencv2/gapi/own/assert.hpp" // GAPI_Assert
17
#include "compiler/passes/helpers.hpp"
18
19
namespace {
20
namespace Cycles
21
{
22
// FIXME: This code is taken directly from ADE.
23
// export a bool(ade::Graph) function with pass instead
24
enum class TraverseState
25
{
26
visiting,
27
visited,
28
};
29
using state_t = std::unordered_map<ade::Node*, TraverseState>;
30
31
bool inline checkCycle(state_t& state, const ade::NodeHandle& node)
32
{
33
GAPI_Assert(nullptr != node);
34
state[node.get()] = TraverseState::visiting;
35
for (auto adj: node->outNodes())
36
{
37
auto it = state.find(adj.get());
38
if (state.end() == it) // not visited
39
{
40
// FIXME: use std::stack instead on-stack recursion
41
if (checkCycle(state, adj))
42
{
43
return true; // detected! (deeper frame)
44
}
45
}
46
else if (TraverseState::visiting == it->second)
47
{
48
return true; // detected! (this frame)
49
}
50
}
51
state[node.get()] = TraverseState::visited;
52
return false; // not detected
53
}
54
55
bool inline hasCycles(const ade::Graph &graph)
56
{
57
state_t state;
58
bool detected = false;
59
for (auto node: graph.nodes())
60
{
61
if (state.end() == state.find(node.get()))
62
{
63
// not yet visited during recursion
64
detected |= checkCycle(state, node);
65
if (detected) break;
66
}
67
}
68
return detected;
69
}
70
} // namespace Cycles
71
72
namespace TopoSort
73
{
74
using sorted_t = std::vector<ade::NodeHandle>;
75
using visited_t = std::unordered_set<ade::Node*>;
76
77
struct NonEmpty final
78
{
79
bool operator()(const ade::NodeHandle& node) const
80
{
81
return nullptr != node;
82
}
83
};
84
85
void inline visit(sorted_t& sorted, visited_t& visited, const ade::NodeHandle& node)
86
{
87
if (visited.end() == visited.find(node.get()))
88
{
89
for (auto adj: node->inNodes())
90
{
91
visit(sorted, visited, adj);
92
}
93
sorted.push_back(node);
94
visited.insert(node.get());
95
}
96
}
97
98
sorted_t inline topoSort(const ade::Graph &g)
99
{
100
sorted_t sorted;
101
visited_t visited;
102
for (auto node: g.nodes())
103
{
104
visit(sorted, visited, node);
105
}
106
107
auto r = ade::util::filter<NonEmpty>(ade::util::toRange(sorted));
108
return sorted_t(r.begin(), r.end());
109
}
110
} // namespace TopoSort
111
112
} // anonymous namespace
113
114
bool cv::gimpl::pass_helpers::hasCycles(const ade::Graph &g)
115
{
116
return Cycles::hasCycles(g);
117
}
118
119
std::vector<ade::NodeHandle> cv::gimpl::pass_helpers::topoSort(const ade::Graph &g)
120
{
121
return TopoSort::topoSort(g);
122
}
123
124