• Andrey Golubev's avatar
    Merge pull request #15313 from andrey-golubev:map_subst_to_pattern · 9f4f9000
    Andrey Golubev authored
    G-API: add transformation logic to GCompiler
    
    * Introduce transformation logic to GCOmpiler
    
    * Remove partialOk() method
    
    * Fix minor issues
    
    * Refactor code according to code review
    
    1. Re-design matchPatternToSubstitute logic
    2. Update transformations order
    3. Replace check_transformations pass with a
       one time check in GCompiler ctor
    
    * Revert unused nodes handling in pattern matching
    
    * Address minor code review issues
    
    * Address code review comments:
    
    1) Fix some mistakes
    2) Add new tests for endless loops
    3) Update GCompiler's transformations logic
    
    * Simplify GCompiler check for endless loops
    
    1. Simplify transformations endless loops check:
     - Original idea wasn't a full solution
     - Need to develop a good method (heuristic?) to find loops
       in general case (TODO)
    2. Remove irrelevant Endless Loops tests
    3. Add new "bad arg" tests and unit tests
    
    * Update comments
    9f4f9000
pattern_matching.hpp 3.22 KB
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
//
// Copyright (C) 2019 Intel Corporation


#ifndef OPENCV_GAPI_PATTERN_MATCHING_HPP
#define OPENCV_GAPI_PATTERN_MATCHING_HPP

#include <unordered_map>
#include <unordered_set>
#include <vector>
#include <list>

#include "compiler/gmodel.hpp"

namespace cv {
namespace gimpl {

    struct SubgraphMatch {
        using M =  std::unordered_map< ade::NodeHandle              // Pattern graph node
                                     , ade::NodeHandle              // Test graph node
                                     , ade::HandleHasher<ade::Node>
                                     >;
        using S =  std::unordered_set< ade::NodeHandle
                                     , ade::HandleHasher<ade::Node>
                                     >;
        M inputDataNodes;
        M startOpNodes;
        M finishOpNodes;
        M outputDataNodes;

        std::vector<ade::NodeHandle> inputTestDataNodes;
        std::vector<ade::NodeHandle> outputTestDataNodes;

        std::list<ade::NodeHandle> internalLayers;

        // FIXME: switch to operator bool() instead
        bool ok() const {
            return    !inputDataNodes.empty() && !startOpNodes.empty()
                   && !finishOpNodes.empty() && !outputDataNodes.empty()
                   && !inputTestDataNodes.empty() && !outputTestDataNodes.empty();
        }

       S nodes() const {
           S allNodes {};

           allNodes.insert(inputTestDataNodes.begin(), inputTestDataNodes.end());

           for (const auto& startOpMatch : startOpNodes) {
               allNodes.insert(startOpMatch.second);
           }

           for (const auto& finishOpMatch : finishOpNodes) {
               allNodes.insert(finishOpMatch.second);
           }

           allNodes.insert(outputTestDataNodes.begin(), outputTestDataNodes.end());

           allNodes.insert(internalLayers.begin(), internalLayers.end());

           return allNodes;
       }

       S startOps() {
            S sOps;
            for (const auto& opMatch : startOpNodes) {
               sOps.insert(opMatch.second);
            }
            return sOps;
       }

       S finishOps() {
            S fOps;
            for (const auto& opMatch : finishOpNodes) {
               fOps.insert(opMatch.second);
            }
            return fOps;
       }

       std::vector<ade::NodeHandle> protoIns() {
           return inputTestDataNodes;
       }


       std::vector<ade::NodeHandle> protoOuts() {
           return outputTestDataNodes;
       }
    };

    GAPI_EXPORTS SubgraphMatch findMatches(const cv::gimpl::GModel::Graph& patternGraph,
                                           const cv::gimpl::GModel::Graph& compGraph);

    GAPI_EXPORTS void performSubstitution(cv::gimpl::GModel::Graph& graph,
                                          const cv::gimpl::Protocol& patternP,
                                          const cv::gimpl::Protocol& substituteP,
                                          const cv::gimpl::SubgraphMatch& patternToGraphMatch);

} //namespace gimpl
} //namespace cv
#endif // OPENCV_GAPI_PATTERN_MATCHING_HPP