Merge pull request #22451 from dmatveev:dm/abstract_execs

G-API: Introduce abstract base classes for GExecutor and GStreamingExecutor
pull/22495/head
Alexander Smorkalov 3 years ago committed by GitHub
commit c9060b053d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      modules/gapi/CMakeLists.txt
  2. 3
      modules/gapi/src/compiler/gcompiled.cpp
  3. 6
      modules/gapi/src/compiler/gcompiled_priv.hpp
  4. 4
      modules/gapi/src/compiler/gstreaming.cpp
  5. 8
      modules/gapi/src/compiler/gstreaming_priv.hpp
  6. 25
      modules/gapi/src/executor/gabstractexecutor.cpp
  7. 80
      modules/gapi/src/executor/gabstractexecutor.hpp
  8. 23
      modules/gapi/src/executor/gabstractstreamingexecutor.cpp
  9. 49
      modules/gapi/src/executor/gabstractstreamingexecutor.hpp
  10. 11
      modules/gapi/src/executor/gexecutor.cpp
  11. 54
      modules/gapi/src/executor/gexecutor.hpp
  12. 10
      modules/gapi/src/executor/gstreamingexecutor.cpp
  13. 29
      modules/gapi/src/executor/gstreamingexecutor.hpp

@ -113,6 +113,8 @@ set(gapi_srcs
src/compiler/passes/intrin.cpp src/compiler/passes/intrin.cpp
# Executor # Executor
src/executor/gabstractexecutor.cpp
src/executor/gabstractstreamingexecutor.cpp
src/executor/gexecutor.cpp src/executor/gexecutor.cpp
src/executor/gtbbexecutor.cpp src/executor/gtbbexecutor.cpp
src/executor/gstreamingexecutor.cpp src/executor/gstreamingexecutor.cpp

@ -14,11 +14,12 @@
#include "compiler/gcompiled_priv.hpp" #include "compiler/gcompiled_priv.hpp"
#include "backends/common/gbackend.hpp" #include "backends/common/gbackend.hpp"
#include "executor/gexecutor.hpp"
// GCompiled private implementation //////////////////////////////////////////// // GCompiled private implementation ////////////////////////////////////////////
void cv::GCompiled::Priv::setup(const GMetaArgs &_metaArgs, void cv::GCompiled::Priv::setup(const GMetaArgs &_metaArgs,
const GMetaArgs &_outMetas, const GMetaArgs &_outMetas,
std::unique_ptr<cv::gimpl::GExecutor> &&_pE) std::unique_ptr<cv::gimpl::GAbstractExecutor> &&_pE)
{ {
m_metas = _metaArgs; m_metas = _metaArgs;
m_outMetas = _outMetas; m_outMetas = _outMetas;

@ -12,7 +12,7 @@
#include "opencv2/gapi/util/optional.hpp" #include "opencv2/gapi/util/optional.hpp"
#include "compiler/gmodel.hpp" #include "compiler/gmodel.hpp"
#include "executor/gexecutor.hpp" #include "executor/gabstractexecutor.hpp"
// NB: BTW, GCompiled is the only "public API" class which // NB: BTW, GCompiled is the only "public API" class which
// private part (implementation) is hosted in the "compiler/" module. // private part (implementation) is hosted in the "compiler/" module.
@ -36,14 +36,14 @@ class GAPI_EXPORTS GCompiled::Priv
// If we want to go autonomous, we might to do something with this. // If we want to go autonomous, we might to do something with this.
GMetaArgs m_metas; // passed by user GMetaArgs m_metas; // passed by user
GMetaArgs m_outMetas; // inferred by compiler GMetaArgs m_outMetas; // inferred by compiler
std::unique_ptr<cv::gimpl::GExecutor> m_exec; std::unique_ptr<cv::gimpl::GAbstractExecutor> m_exec;
void checkArgs(const cv::gimpl::GRuntimeArgs &args) const; void checkArgs(const cv::gimpl::GRuntimeArgs &args) const;
public: public:
void setup(const GMetaArgs &metaArgs, void setup(const GMetaArgs &metaArgs,
const GMetaArgs &outMetas, const GMetaArgs &outMetas,
std::unique_ptr<cv::gimpl::GExecutor> &&pE); std::unique_ptr<cv::gimpl::GAbstractExecutor> &&pE);
bool isEmpty() const; bool isEmpty() const;
bool canReshape() const; bool canReshape() const;

@ -19,14 +19,14 @@
// GStreamingCompiled private implementation /////////////////////////////////// // GStreamingCompiled private implementation ///////////////////////////////////
void cv::GStreamingCompiled::Priv::setup(const GMetaArgs &_metaArgs, void cv::GStreamingCompiled::Priv::setup(const GMetaArgs &_metaArgs,
const GMetaArgs &_outMetas, const GMetaArgs &_outMetas,
std::unique_ptr<cv::gimpl::GStreamingExecutor> &&_pE) std::unique_ptr<cv::gimpl::GAbstractStreamingExecutor> &&_pE)
{ {
m_metas = _metaArgs; m_metas = _metaArgs;
m_outMetas = _outMetas; m_outMetas = _outMetas;
m_exec = std::move(_pE); m_exec = std::move(_pE);
} }
void cv::GStreamingCompiled::Priv::setup(std::unique_ptr<cv::gimpl::GStreamingExecutor> &&_pE) void cv::GStreamingCompiled::Priv::setup(std::unique_ptr<cv::gimpl::GAbstractStreamingExecutor> &&_pE)
{ {
m_exec = std::move(_pE); m_exec = std::move(_pE);
} }

@ -9,7 +9,7 @@
#define OPENCV_GAPI_GSTREAMING_COMPILED_PRIV_HPP #define OPENCV_GAPI_GSTREAMING_COMPILED_PRIV_HPP
#include <memory> // unique_ptr #include <memory> // unique_ptr
#include "executor/gstreamingexecutor.hpp" #include "executor/gabstractstreamingexecutor.hpp"
namespace cv { namespace cv {
@ -26,7 +26,7 @@ class GAPI_EXPORTS GStreamingCompiled::Priv
{ {
GMetaArgs m_metas; // passed by user GMetaArgs m_metas; // passed by user
GMetaArgs m_outMetas; // inferred by compiler GMetaArgs m_outMetas; // inferred by compiler
std::unique_ptr<cv::gimpl::GStreamingExecutor> m_exec; std::unique_ptr<cv::gimpl::GAbstractStreamingExecutor> m_exec;
// NB: Used by python wrapper to clarify input/output types // NB: Used by python wrapper to clarify input/output types
GTypesInfo m_out_info; GTypesInfo m_out_info;
@ -35,8 +35,8 @@ class GAPI_EXPORTS GStreamingCompiled::Priv
public: public:
void setup(const GMetaArgs &metaArgs, void setup(const GMetaArgs &metaArgs,
const GMetaArgs &outMetas, const GMetaArgs &outMetas,
std::unique_ptr<cv::gimpl::GStreamingExecutor> &&pE); std::unique_ptr<cv::gimpl::GAbstractStreamingExecutor> &&pE);
void setup(std::unique_ptr<cv::gimpl::GStreamingExecutor> &&pE); void setup(std::unique_ptr<cv::gimpl::GAbstractStreamingExecutor> &&pE);
bool isEmpty() const; bool isEmpty() const;
const GMetaArgs& metas() const; const GMetaArgs& metas() const;

@ -0,0 +1,25 @@
// 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) 2022 Intel Corporation
#include "precomp.hpp"
#include <opencv2/gapi/opencv_includes.hpp>
#include "executor/gabstractexecutor.hpp"
cv::gimpl::GAbstractExecutor::GAbstractExecutor(std::unique_ptr<ade::Graph> &&g_model)
: m_orig_graph(std::move(g_model))
, m_island_graph(GModel::Graph(*m_orig_graph).metadata()
.get<IslandModel>().model)
, m_gm(*m_orig_graph)
, m_gim(*m_island_graph)
{
}
const cv::gimpl::GModel::Graph& cv::gimpl::GAbstractExecutor::model() const
{
return m_gm;
}

@ -0,0 +1,80 @@
// 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) 2022 Intel Corporation
#ifndef OPENCV_GAPI_GABSTRACT_EXECUTOR_HPP
#define OPENCV_GAPI_GABSTRACT_EXECUTOR_HPP
#include <memory> // unique_ptr, shared_ptr
#include <utility> // tuple, required by magazine
#include <unordered_map> // required by magazine
#include <ade/graph.hpp>
#include "backends/common/gbackend.hpp"
namespace cv {
namespace gimpl {
// Graph-level executor interface.
//
// This class specifies API for a "super-executor" which orchestrates
// the overall Island graph execution.
//
// Every Island (subgraph) execution is delegated to a particular
// backend and is done opaquely to the GExecutor.
//
// Inputs to a GExecutor instance are:
// - GIslandModel - a high-level graph model which may be seen as a
// "procedure" to execute.
// - GModel - a low-level graph of operations (from which a GIslandModel
// is projected)
// - GComputation runtime arguments - vectors of input/output objects
//
// Every GExecutor is responsible for
// a. Maintaining non-island (intermediate) data objects within graph
// b. Providing GIslandExecutables with input/output data according to
// their protocols
// c. Triggering execution of GIslandExecutables when task/data dependencies
// are met.
//
// By default G-API stores all data on host, and cross-Island
// exchange happens via host buffers (and CV data objects).
//
// Today's exchange data objects are:
// - cv::Mat, cv::RMat - for image buffers
// - cv::Scalar - for single values (with up to four components inside)
// - cv::detail::VectorRef - an untyped wrapper over std::vector<T>
// - cv::detail::OpaqueRef - an untyped wrapper over T
// - cv::MediaFrame - for image textures and surfaces (e.g. in planar format)
class GAbstractExecutor
{
protected:
std::unique_ptr<ade::Graph> m_orig_graph;
std::shared_ptr<ade::Graph> m_island_graph;
cv::gimpl::GModel::Graph m_gm; // FIXME: make const?
cv::gimpl::GIslandModel::Graph m_gim; // FIXME: make const?
public:
explicit GAbstractExecutor(std::unique_ptr<ade::Graph> &&g_model);
virtual ~GAbstractExecutor() = default;
virtual void run(cv::gimpl::GRuntimeArgs &&args) = 0;
virtual bool canReshape() const = 0;
virtual void reshape(const GMetaArgs& inMetas, const GCompileArgs& args) = 0;
virtual void prepareForNewStream() = 0;
const GModel::Graph& model() const; // FIXME: make it ConstGraph?
};
} // namespace gimpl
} // namespace cv
#endif // OPENCV_GAPI_GABSTRACT_EXECUTOR_HPP

@ -0,0 +1,23 @@
// 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) 2022 Intel Corporation
#include "precomp.hpp"
#include <opencv2/gapi/opencv_includes.hpp>
#include "executor/gabstractstreamingexecutor.hpp"
cv::gimpl::GAbstractStreamingExecutor::GAbstractStreamingExecutor(std::unique_ptr<ade::Graph> &&g_model,
const GCompileArgs &comp_args)
: m_orig_graph(std::move(g_model))
, m_island_graph(GModel::Graph(*m_orig_graph).metadata()
.get<IslandModel>().model)
, m_comp_args(comp_args)
, m_gim(*m_island_graph)
, m_desync(GModel::Graph(*m_orig_graph).metadata()
.contains<Desynchronized>())
{
}

@ -0,0 +1,49 @@
// 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) 2022 Intel Corporation
#ifndef OPENCV_GAPI_GABSTRACT_STREAMING_EXECUTOR_HPP
#define OPENCV_GAPI_GABSTRACT_STREAMING_EXECUTOR_HPP
#include <memory> // unique_ptr, shared_ptr
#include <ade/graph.hpp>
#include "backends/common/gbackend.hpp"
namespace cv {
namespace gimpl {
class GAbstractStreamingExecutor
{
protected:
std::unique_ptr<ade::Graph> m_orig_graph;
std::shared_ptr<ade::Graph> m_island_graph;
cv::GCompileArgs m_comp_args;
cv::gimpl::GIslandModel::Graph m_gim; // FIXME: make const?
const bool m_desync;
public:
explicit GAbstractStreamingExecutor(std::unique_ptr<ade::Graph> &&g_model,
const cv::GCompileArgs &comp_args);
virtual ~GAbstractStreamingExecutor() = default;
virtual void setSource(GRunArgs &&args) = 0;
virtual void start() = 0;
virtual bool pull(cv::GRunArgsP &&outs) = 0;
virtual bool pull(cv::GOptRunArgsP &&outs) = 0;
using PyPullResult = std::tuple<bool, cv::util::variant<cv::GRunArgs, cv::GOptRunArgs>>;
virtual PyPullResult pull() = 0;
virtual bool try_pull(cv::GRunArgsP &&outs) = 0;
virtual void stop() = 0;
virtual bool running() const = 0;
};
} // namespace gimpl
} // namespace cv
#endif // OPENCV_GAPI_GABSTRACT_STREAMING_EXECUTOR_HPP

@ -16,11 +16,7 @@
#include "compiler/passes/passes.hpp" #include "compiler/passes/passes.hpp"
cv::gimpl::GExecutor::GExecutor(std::unique_ptr<ade::Graph> &&g_model) cv::gimpl::GExecutor::GExecutor(std::unique_ptr<ade::Graph> &&g_model)
: m_orig_graph(std::move(g_model)) : GAbstractExecutor(std::move(g_model))
, m_island_graph(GModel::Graph(*m_orig_graph).metadata()
.get<IslandModel>().model)
, m_gm(*m_orig_graph)
, m_gim(*m_island_graph)
{ {
// NB: Right now GIslandModel is acyclic, so for a naive execution, // NB: Right now GIslandModel is acyclic, so for a naive execution,
// simple unrolling to a list of triggers is enough // simple unrolling to a list of triggers is enough
@ -424,11 +420,6 @@ void cv::gimpl::GExecutor::run(cv::gimpl::GRuntimeArgs &&args)
} }
} }
const cv::gimpl::GModel::Graph& cv::gimpl::GExecutor::model() const
{
return m_gm;
}
bool cv::gimpl::GExecutor::canReshape() const bool cv::gimpl::GExecutor::canReshape() const
{ {
// FIXME: Introduce proper reshaping support on GExecutor level // FIXME: Introduce proper reshaping support on GExecutor level

@ -8,58 +8,18 @@
#ifndef OPENCV_GAPI_GEXECUTOR_HPP #ifndef OPENCV_GAPI_GEXECUTOR_HPP
#define OPENCV_GAPI_GEXECUTOR_HPP #define OPENCV_GAPI_GEXECUTOR_HPP
#include <memory> // unique_ptr, shared_ptr
#include <utility> // tuple, required by magazine #include <utility> // tuple, required by magazine
#include <unordered_map> // required by magazine #include <unordered_map> // required by magazine
#include <ade/graph.hpp> #include "executor/gabstractexecutor.hpp"
#include "backends/common/gbackend.hpp"
namespace cv { namespace cv {
namespace gimpl { namespace gimpl {
// Graph-level executor interface. class GExecutor final: public GAbstractExecutor
//
// This class specifies API for a "super-executor" which orchestrates
// the overall Island graph execution.
//
// Every Island (subgraph) execution is delegated to a particular
// backend and is done opaquely to the GExecutor.
//
// Inputs to a GExecutor instance are:
// - GIslandModel - a high-level graph model which may be seen as a
// "procedure" to execute.
// - GModel - a low-level graph of operations (from which a GIslandModel
// is projected)
// - GComputation runtime arguments - vectors of input/output objects
//
// Every GExecutor is responsible for
// a. Maintaining non-island (intermediate) data objects within graph
// b. Providing GIslandExecutables with input/output data according to
// their protocols
// c. Triggering execution of GIslandExecutables when task/data dependencies
// are met.
//
// By default G-API stores all data on host, and cross-Island
// exchange happens via host buffers (and CV data objects).
//
// Today's exchange data objects are:
// - cv::Mat - for image buffers
// - cv::Scalar - for single values (with up to four components inside)
// - cv::detail::VectorRef - an untyped wrapper over std::vector<T>
//
class GExecutor
{ {
protected: protected:
Mag m_res; Mag m_res;
std::unique_ptr<ade::Graph> m_orig_graph;
std::shared_ptr<ade::Graph> m_island_graph;
cv::gimpl::GModel::Graph m_gm; // FIXME: make const?
cv::gimpl::GIslandModel::Graph m_gim; // FIXME: make const?
// FIXME: Naive executor details are here for now // FIXME: Naive executor details are here for now
// but then it should be moved to another place // but then it should be moved to another place
@ -85,14 +45,12 @@ protected:
public: public:
explicit GExecutor(std::unique_ptr<ade::Graph> &&g_model); explicit GExecutor(std::unique_ptr<ade::Graph> &&g_model);
void run(cv::gimpl::GRuntimeArgs &&args); void run(cv::gimpl::GRuntimeArgs &&args) override;
bool canReshape() const;
void reshape(const GMetaArgs& inMetas, const GCompileArgs& args);
void prepareForNewStream(); bool canReshape() const override;
void reshape(const GMetaArgs& inMetas, const GCompileArgs& args) override;
const GModel::Graph& model() const; // FIXME: make it ConstGraph? void prepareForNewStream() override;
}; };
} // namespace gimpl } // namespace gimpl

@ -1288,13 +1288,7 @@ public:
// proper graph reshape and islands recompilation // proper graph reshape and islands recompilation
cv::gimpl::GStreamingExecutor::GStreamingExecutor(std::unique_ptr<ade::Graph> &&g_model, cv::gimpl::GStreamingExecutor::GStreamingExecutor(std::unique_ptr<ade::Graph> &&g_model,
const GCompileArgs &comp_args) const GCompileArgs &comp_args)
: m_orig_graph(std::move(g_model)) : GAbstractStreamingExecutor(std::move(g_model), comp_args)
, m_island_graph(GModel::Graph(*m_orig_graph).metadata()
.get<IslandModel>().model)
, m_comp_args(comp_args)
, m_gim(*m_island_graph)
, m_desync(GModel::Graph(*m_orig_graph).metadata()
.contains<Desynchronized>())
{ {
GModel::Graph gm(*m_orig_graph); GModel::Graph gm(*m_orig_graph);
// NB: Right now GIslandModel is acyclic, and all the below code assumes that. // NB: Right now GIslandModel is acyclic, and all the below code assumes that.
@ -1862,7 +1856,7 @@ bool cv::gimpl::GStreamingExecutor::pull(cv::GOptRunArgsP &&outs)
GAPI_Assert(false && "Unreachable code"); GAPI_Assert(false && "Unreachable code");
} }
std::tuple<bool, cv::util::variant<cv::GRunArgs, cv::GOptRunArgs>> cv::gimpl::GStreamingExecutor::pull() cv::gimpl::GAbstractStreamingExecutor::PyPullResult cv::gimpl::GStreamingExecutor::pull()
{ {
using RunArgs = cv::util::variant<cv::GRunArgs, cv::GOptRunArgs>; using RunArgs = cv::util::variant<cv::GRunArgs, cv::GOptRunArgs>;
bool is_over = false; bool is_over = false;

@ -12,7 +12,6 @@
// on concurrent_bounded_queue // on concurrent_bounded_queue
#endif #endif
#include <memory> // unique_ptr, shared_ptr
#include <thread> // thread #include <thread> // thread
#include <vector> #include <vector>
#include <unordered_map> #include <unordered_map>
@ -26,9 +25,7 @@ template<typename T> using QueueClass = cv::gapi::own::concurrent_bounded_queue<
#endif // TBB #endif // TBB
#include "executor/last_value.hpp" #include "executor/last_value.hpp"
#include <ade/graph.hpp> #include "executor/gabstractstreamingexecutor.hpp"
#include "backends/common/gbackend.hpp"
namespace cv { namespace cv {
namespace gimpl { namespace gimpl {
@ -104,7 +101,7 @@ public:
// FIXME: Currently all GExecutor comments apply also // FIXME: Currently all GExecutor comments apply also
// to this one. Please document it separately in the future. // to this one. Please document it separately in the future.
class GStreamingExecutor final class GStreamingExecutor final: public GAbstractStreamingExecutor
{ {
protected: protected:
// GStreamingExecutor is a state machine described as follows // GStreamingExecutor is a state machine described as follows
@ -131,15 +128,9 @@ protected:
RUNNING, RUNNING,
} state = State::STOPPED; } state = State::STOPPED;
std::unique_ptr<ade::Graph> m_orig_graph;
std::shared_ptr<ade::Graph> m_island_graph;
cv::GCompileArgs m_comp_args;
cv::GMetaArgs m_last_metas; cv::GMetaArgs m_last_metas;
util::optional<bool> m_reshapable; util::optional<bool> m_reshapable;
cv::gimpl::GIslandModel::Graph m_gim; // FIXME: make const?
const bool m_desync;
// FIXME: Naive executor details are here for now // FIXME: Naive executor details are here for now
// but then it should be moved to another place // but then it should be moved to another place
struct OpDesc struct OpDesc
@ -202,14 +193,14 @@ public:
explicit GStreamingExecutor(std::unique_ptr<ade::Graph> &&g_model, explicit GStreamingExecutor(std::unique_ptr<ade::Graph> &&g_model,
const cv::GCompileArgs &comp_args); const cv::GCompileArgs &comp_args);
~GStreamingExecutor(); ~GStreamingExecutor();
void setSource(GRunArgs &&args); void setSource(GRunArgs &&args) override;
void start(); void start() override;
bool pull(cv::GRunArgsP &&outs); bool pull(cv::GRunArgsP &&outs) override;
bool pull(cv::GOptRunArgsP &&outs); bool pull(cv::GOptRunArgsP &&outs) override;
std::tuple<bool, cv::util::variant<cv::GRunArgs, cv::GOptRunArgs>> pull(); PyPullResult pull() override;
bool try_pull(cv::GRunArgsP &&outs); bool try_pull(cv::GRunArgsP &&outs) override;
void stop(); void stop() override;
bool running() const; bool running() const override;
}; };
} // namespace gimpl } // namespace gimpl

Loading…
Cancel
Save