Publishing 2019 R1 content
[platform/upstream/dldt.git] / inference-engine / thirdparty / fluid / modules / gapi / src / compiler / gmodel.hpp
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-2019 Intel Corporation
6
7
8 #ifndef OPENCV_GAPI_GMODEL_HPP
9 #define OPENCV_GAPI_GMODEL_HPP
10
11 #include <memory>           // shared_ptr
12 #include <unordered_map>
13 #include <functional>       // std::function
14
15 #include <ade/graph.hpp>
16 #include <ade/typed_graph.hpp>
17 #include <ade/passes/topological_sort.hpp>
18
19 // /!\ ATTENTION:
20 //
21 // No API includes like GMat, GNode, GCall here!
22 // This part of the system is API-unaware by its design.
23 //
24
25 #include "opencv2/gapi/garg.hpp"
26 #include "opencv2/gapi/gkernel.hpp"
27 #include "api/gapi_priv.hpp"   // GShape
28 #include "api/gproto_priv.hpp" // origin_of
29 #include "backends/common/gbackend.hpp"
30
31 #include "compiler/gobjref.hpp"
32 #include "compiler/gislandmodel.hpp"
33
34 namespace cv { namespace gimpl {
35
36 // TODO: Document all metadata types
37
38 struct NodeType
39 {
40     static const char *name() { return "NodeType"; }
41     enum { OP, DATA } t;
42 };
43
44 struct Input
45 {
46     static const char *name() { return "Input"; }
47     std::size_t port;
48 };
49
50 struct Output
51 {
52     static const char *name() { return "Output"; }
53     std::size_t port;
54 };
55
56 struct Op
57 {
58     static const char *name() { return "Op"; }
59     cv::GKernel         k;
60     std::vector<GArg>   args; // TODO: Introduce a new type for internal args?
61     std::vector<RcDesc> outs; // TODO: Introduce a new type for resource references
62
63     cv::gapi::GBackend  backend;
64 };
65
66 struct Data
67 {
68     static const char *name() { return "Data"; }
69
70     // FIXME: This is a _pure_ duplication of RcDesc now! (except storage)
71     GShape   shape; // FIXME: Probably to be replaced by GMetaArg?
72     int      rc;
73     GMetaArg meta;
74     HostCtor ctor;  // T-specific helper to deal with unknown types in our code
75     // FIXME: Why rc+shape+meta is not represented as RcDesc here?
76
77     enum class Storage
78     {
79         INTERNAL,   // data object is not listed in GComputation protocol
80         INPUT,      // data object is listed in GComputation protocol as Input
81         OUTPUT,     // data object is listed in GComputation protocol as Output
82         CONST,      // data object is constant
83     };
84     Storage storage;
85 };
86
87 struct ConstValue
88 {
89     static const char *name() { return "ConstValue"; }
90     GRunArg arg;
91 };
92
93 // This metadata is valid for both DATA and OP kinds of nodes
94 // FIXME: Rename to IslandTag
95 struct Island
96 {
97     static const char *name() { return "Island"; }
98     std::string island; // can be set by user, otherwise is set by fusion
99 };
100
101 struct Protocol
102 {
103     static const char *name() { return "Protocol"; }
104     // TODO: Replace the whole thing with a "Protocol" object
105     std::vector<RcDesc> inputs;
106     std::vector<RcDesc> outputs;
107
108     std::vector<ade::NodeHandle> in_nhs;
109     std::vector<ade::NodeHandle> out_nhs;
110 };
111
112 struct OutputMeta
113 {
114     static const char *name() { return "OutputMeta"; }
115     GMetaArgs outMeta;
116 };
117
118 struct Journal
119 {
120     static const char *name() { return "Journal"; }
121     std::vector<std::string> messages;
122 };
123
124 // The mapping between user-side GMat/GScalar/... objects
125 // and its  appropriate nodes. Can be stored in graph optionally
126 // (NOT used by any compiler or backends, introspection purposes
127 // only)
128 struct Layout
129 {
130     static const char *name() { return "Layout"; }
131     GOriginMap<ade::NodeHandle> object_nodes;
132 };
133
134 // Unique data object counter (per-type)
135 class DataObjectCounter
136 {
137 public:
138     static const char* name() { return "DataObjectCounter"; }
139     int GetNewId(GShape shape) { return m_next_data_id[shape]++; }
140 private:
141     std::unordered_map<cv::GShape, int> m_next_data_id;
142 };
143
144 // A projected graph of Islands (generated from graph of Operations)
145 struct IslandModel
146 {
147     static const char* name() { return "IslandModel"; }
148     std::shared_ptr<ade::Graph> model;
149 };
150
151 // List of backends selected for current graph execution
152 struct ActiveBackends
153 {
154     static const char *name() { return "ActiveBackends"; }
155     std::unordered_set<cv::gapi::GBackend> backends;
156 };
157
158 namespace GModel
159 {
160     using Graph = ade::TypedGraph
161         < NodeType
162         , Input
163         , Output
164         , Op
165         , Data
166         , ConstValue
167         , Island
168         , Protocol
169         , OutputMeta
170         , Journal
171         , ade::passes::TopologicalSortData
172         , DataObjectCounter
173         , Layout
174         , IslandModel
175         , ActiveBackends
176         >;
177
178     // FIXME: How to define it based on GModel???
179     using ConstGraph = ade::ConstTypedGraph
180         < NodeType
181         , Input
182         , Output
183         , Op
184         , Data
185         , ConstValue
186         , Island
187         , Protocol
188         , OutputMeta
189         , Journal
190         , ade::passes::TopologicalSortData
191         , DataObjectCounter
192         , Layout
193         , IslandModel
194         , ActiveBackends
195         >;
196
197     // User should initialize graph before using it
198     // GAPI_EXPORTS for tests
199     GAPI_EXPORTS void init (Graph& g);
200
201     ade::NodeHandle mkOpNode(Graph &g, const GKernel &k, const std::vector<GArg>& args, const std::string &island);
202
203     // FIXME: change it to take GMeta instead of GShape?
204     ade::NodeHandle mkDataNode(Graph &g, const GOrigin& origin);
205
206     // Adds a string message to a node. Any node can be subject of log, messages then
207     // appear in the dumped .dot file.x
208     void log(Graph &g, ade::NodeHandle op, std::string &&message, ade::NodeHandle updater = ade::NodeHandle());
209     void log(Graph &g, ade::EdgeHandle op, std::string &&message, ade::NodeHandle updater = ade::NodeHandle());
210
211     void linkIn   (Graph &g, ade::NodeHandle op,     ade::NodeHandle obj, std::size_t in_port);
212     void linkOut  (Graph &g, ade::NodeHandle op,     ade::NodeHandle obj, std::size_t out_port);
213
214     // FIXME: Align this GModel API properly, it is a mess now
215     namespace detail
216     {
217         // FIXME: GAPI_EXPORTS only because of tests!!!
218         GAPI_EXPORTS ade::NodeHandle dataNodeOf(const ConstGraph& g, const GOrigin &origin);
219     }
220     template<typename T> inline ade::NodeHandle dataNodeOf(const ConstGraph& g, T &&t)
221     {
222         return detail::dataNodeOf(g, cv::gimpl::proto::origin_of(GProtoArg{t}));
223     }
224
225     void linkIn   (Graph &g, ade::NodeHandle op,     ade::NodeHandle obj, std::size_t in_port);
226     void linkOut  (Graph &g, ade::NodeHandle op,     ade::NodeHandle obj, std::size_t out_port);
227
228     void redirectReaders(Graph &g, ade::NodeHandle from, ade::NodeHandle to);
229     void redirectWriter (Graph &g, ade::NodeHandle from, ade::NodeHandle to);
230
231     std::vector<ade::NodeHandle> orderedInputs (Graph &g, ade::NodeHandle nh);
232     std::vector<ade::NodeHandle> orderedOutputs(Graph &g, ade::NodeHandle nh);
233
234     // Returns input meta array for given op node
235     // Array is sparse, as metadata for non-gapi input objects is empty
236     // TODO:
237     // Cover with tests!!
238     GMetaArgs collectInputMeta(GModel::ConstGraph cg, ade::NodeHandle node);
239     GMetaArgs collectOutputMeta(GModel::ConstGraph cg, ade::NodeHandle node);
240
241     ade::EdgeHandle getInEdgeByPort(const GModel::ConstGraph& cg, const ade::NodeHandle& nh, std::size_t in_port);
242
243     // Returns true if the given backend participates in the execution
244     bool isActive(const GModel::Graph &cg, const cv::gapi::GBackend &backend);
245 } // namespace GModel
246
247
248 }} // namespace cv::gimpl
249
250 #endif // OPENCV_GAPI_GMODEL_HPP