Path: blob/master/modules/gapi/src/api/gcomputation.cpp
16339 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"8#include <algorithm> // remove_if9#include <cctype> // isspace (non-locale version)10#include <ade/util/algorithm.hpp>1112#include "logger.hpp" // GAPI_LOG1314#include "opencv2/gapi/gcomputation.hpp"15#include "opencv2/gapi/gkernel.hpp"1617#include "api/gcomputation_priv.hpp"18#include "api/gcall_priv.hpp"19#include "api/gnode_priv.hpp"2021#include "compiler/gmodelbuilder.hpp"22#include "compiler/gcompiler.hpp"2324// cv::GComputation private implementation /////////////////////////////////////25// <none>2627// cv::GComputation public implementation //////////////////////////////////////28cv::GComputation::GComputation(const Generator& gen)29: m_priv(gen().m_priv)30{31}3233cv::GComputation::GComputation(GMat in, GMat out)34: cv::GComputation(cv::GIn(in), cv::GOut(out))35{36}373839cv::GComputation::GComputation(GMat in, GScalar out)40: cv::GComputation(cv::GIn(in), cv::GOut(out))41{42}4344cv::GComputation::GComputation(GMat in1, GMat in2, GMat out)45: cv::GComputation(cv::GIn(in1, in2), cv::GOut(out))46{47}4849cv::GComputation::GComputation(GMat in1, GMat in2, GScalar out)50: cv::GComputation(cv::GIn(in1, in2), cv::GOut(out))51{52}5354cv::GComputation::GComputation(const std::vector<GMat> &ins,55const std::vector<GMat> &outs)56: m_priv(new Priv())57{58const auto wrap = [](cv::GMat m) { return GProtoArg(m); };59ade::util::transform(ins, std::back_inserter(m_priv->m_ins), wrap);60ade::util::transform(outs, std::back_inserter(m_priv->m_outs), wrap);61}6263cv::GComputation::GComputation(cv::GProtoInputArgs &&ins,64cv::GProtoOutputArgs &&outs)65: m_priv(new Priv())66{67m_priv->m_ins = std::move(ins.m_args);68m_priv->m_outs = std::move(outs.m_args);69}7071cv::GCompiled cv::GComputation::compile(GMetaArgs &&metas, GCompileArgs &&args)72{73// FIXME: Cache gcompiled per parameters here?74cv::gimpl::GCompiler comp(*this, std::move(metas), std::move(args));75return comp.compile();76}7778void cv::GComputation::apply(GRunArgs &&ins, GRunArgsP &&outs, GCompileArgs &&args)79{80const auto in_metas = descr_of(ins);81// FIXME Graph should be recompiled when GCompileArgs have changed82if (m_priv->m_lastMetas != in_metas)83{84// FIXME: Had to construct temporary object as compile() takes && (r-value)85m_priv->m_lastCompiled = compile(GMetaArgs(in_metas), std::move(args));86m_priv->m_lastMetas = in_metas; // Update only here, if compile() was ok87}88m_priv->m_lastCompiled(std::move(ins), std::move(outs));89}9091void cv::GComputation::apply(const std::vector<cv::gapi::own::Mat> &ins,92const std::vector<cv::gapi::own::Mat> &outs,93GCompileArgs &&args)94{95GRunArgs call_ins;96GRunArgsP call_outs;9798auto tmp = outs;99for (const cv::gapi::own::Mat &m : ins) { call_ins.emplace_back(m); }100for ( cv::gapi::own::Mat &m : tmp) { call_outs.emplace_back(&m); }101102apply(std::move(call_ins), std::move(call_outs), std::move(args));103}104105#if !defined(GAPI_STANDALONE)106void cv::GComputation::apply(cv::Mat in, cv::Mat &out, GCompileArgs &&args)107{108apply(cv::gin(in), cv::gout(out), std::move(args));109// FIXME: The following doesn't work!110// Operation result is not replicated into user's object111// apply({GRunArg(in)}, {GRunArg(out)});112}113114void cv::GComputation::apply(cv::Mat in, cv::Scalar &out, GCompileArgs &&args)115{116apply(cv::gin(in), cv::gout(out), std::move(args));117}118119void cv::GComputation::apply(cv::Mat in1, cv::Mat in2, cv::Mat &out, GCompileArgs &&args)120{121apply(cv::gin(in1, in2), cv::gout(out), std::move(args));122}123124void cv::GComputation::apply(cv::Mat in1, cv::Mat in2, cv::Scalar &out, GCompileArgs &&args)125{126apply(cv::gin(in1, in2), cv::gout(out), std::move(args));127}128129void cv::GComputation::apply(const std::vector<cv::Mat> &ins,130const std::vector<cv::Mat> &outs,131GCompileArgs &&args)132{133GRunArgs call_ins;134GRunArgsP call_outs;135136// Make a temporary copy of vector outs - cv::Mats are copies anyway137auto tmp = outs;138for (const cv::Mat &m : ins) { call_ins.emplace_back(m); }139for ( cv::Mat &m : tmp) { call_outs.emplace_back(&m); }140141apply(std::move(call_ins), std::move(call_outs), std::move(args));142}143#endif // !defined(GAPI_STANDALONE)144145cv::GComputation::Priv& cv::GComputation::priv()146{147return *m_priv;148}149150const cv::GComputation::Priv& cv::GComputation::priv() const151{152return *m_priv;153}154155// Islands /////////////////////////////////////////////////////////////////////156157void cv::gapi::island(const std::string &name,158GProtoInputArgs &&ins,159GProtoOutputArgs &&outs)160{161{162// Island must have a printable name.163// Forbid names which contain only spaces.164GAPI_Assert(!name.empty());165const auto first_printable_it = std::find_if_not(name.begin(), name.end(), isspace);166const bool likely_printable = first_printable_it != name.end();167GAPI_Assert(likely_printable);168}169// Even if the name contains spaces, keep it unmodified as user will170// then use this string to assign affinity, etc.171172// First, set island tags on all operations from `ins` to `outs`173auto island = cv::gimpl::unrollExpr(ins.m_args, outs.m_args);174if (island.all_ops.empty())175{176util::throw_error(std::logic_error("Operation range is empty"));177}178for (auto &op_expr_node : island.all_ops)179{180auto &op_expr_node_p = op_expr_node.priv();181182GAPI_Assert(op_expr_node.shape() == GNode::NodeShape::CALL);183const GCall& call = op_expr_node.call();184const GCall::Priv& call_p = call.priv();185186if (!op_expr_node_p.m_island.empty())187{188util::throw_error(std::logic_error189( "Operation " + call_p.m_k.name190+ " is already assigned to island \""191+ op_expr_node_p.m_island + "\""));192}193else194{195op_expr_node_p.m_island = name;196GAPI_LOG_INFO(NULL,197"Assigned " << call_p.m_k.name << "_" << &call_p <<198" to island \"" << name << "\"");199}200}201202// Note - this function only sets islands to all operations in203// expression tree, it is just a first step.204// The second step is assigning intermediate data objects to Islands,205// see passes::initIslands for details.206}207208209