Path: blob/master/modules/gapi/src/compiler/passes/helpers.cpp
16345 views
// This file is part of OpenCV project.1// It is subject to the license terms in the LICENSE file found in the top-level directory2// of this distribution and at http://opencv.org/license.html.3//4// Copyright (C) 2018 Intel Corporation567#include "precomp.hpp"89#include <algorithm> // copy10#include <unordered_map>11#include <unordered_set>1213#include <ade/util/filter_range.hpp>1415#include "opencv2/gapi/own/assert.hpp" // GAPI_Assert16#include "compiler/passes/helpers.hpp"1718namespace {19namespace Cycles20{21// FIXME: This code is taken directly from ADE.22// export a bool(ade::Graph) function with pass instead23enum class TraverseState24{25visiting,26visited,27};28using state_t = std::unordered_map<ade::Node*, TraverseState>;2930bool inline checkCycle(state_t& state, const ade::NodeHandle& node)31{32GAPI_Assert(nullptr != node);33state[node.get()] = TraverseState::visiting;34for (auto adj: node->outNodes())35{36auto it = state.find(adj.get());37if (state.end() == it) // not visited38{39// FIXME: use std::stack instead on-stack recursion40if (checkCycle(state, adj))41{42return true; // detected! (deeper frame)43}44}45else if (TraverseState::visiting == it->second)46{47return true; // detected! (this frame)48}49}50state[node.get()] = TraverseState::visited;51return false; // not detected52}5354bool inline hasCycles(const ade::Graph &graph)55{56state_t state;57bool detected = false;58for (auto node: graph.nodes())59{60if (state.end() == state.find(node.get()))61{62// not yet visited during recursion63detected |= checkCycle(state, node);64if (detected) break;65}66}67return detected;68}69} // namespace Cycles7071namespace TopoSort72{73using sorted_t = std::vector<ade::NodeHandle>;74using visited_t = std::unordered_set<ade::Node*>;7576struct NonEmpty final77{78bool operator()(const ade::NodeHandle& node) const79{80return nullptr != node;81}82};8384void inline visit(sorted_t& sorted, visited_t& visited, const ade::NodeHandle& node)85{86if (visited.end() == visited.find(node.get()))87{88for (auto adj: node->inNodes())89{90visit(sorted, visited, adj);91}92sorted.push_back(node);93visited.insert(node.get());94}95}9697sorted_t inline topoSort(const ade::Graph &g)98{99sorted_t sorted;100visited_t visited;101for (auto node: g.nodes())102{103visit(sorted, visited, node);104}105106auto r = ade::util::filter<NonEmpty>(ade::util::toRange(sorted));107return sorted_t(r.begin(), r.end());108}109} // namespace TopoSort110111} // anonymous namespace112113bool cv::gimpl::pass_helpers::hasCycles(const ade::Graph &g)114{115return Cycles::hasCycles(g);116}117118std::vector<ade::NodeHandle> cv::gimpl::pass_helpers::topoSort(const ade::Graph &g)119{120return TopoSort::topoSort(g);121}122123124