Blame view

3rdparty/opencv-4.5.4/modules/gapi/doc/10-hld-overview.md 7.33 KB
f4334277   Hu Chunming   提交3rdparty
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
  # High-level design overview {#gapi_hld}
  
  [TOC]
  
  # G-API High-level design overview
  
  G-API is a heterogeneous framework and provides an unified API to
  program image processing pipelines with a number of supported
  backends.
  
  The key design idea is to keep pipeline code itself platform-neutral
  while specifying which kernels to use and which devices to utilize
  using extra parameters at graph compile (configuration) time. This
  requirement has led to the following architecture:
  
  <!-- FIXME: Render from dot directly -->
  
  ![G-API framework architecture](pics/gapi_scheme.png)
  
  There are three layers in this architecture:
  * **API Layer** -- this is the top layer, which implements G-API
    public interface, its building blocks and semantics.
    When user constructs a pipeline with G-API, he interacts with this
    layer directly, and the entities the user operates on (like cv::GMat
    or cv::GComputation) are provided by this layer.
  * **Graph Compiler Layer** -- this is the intermediate layer which
    unrolls user computation into a graph and then applies a number of
    transformations to it (e.g. optimizations). This layer is built atop
    of [ADE Framework](@ref gapi_detail_ade).
  * **Backends Layer** -- this is the lowest level layer, which lists a
    number of _Backends_. In contrast with the above two layers,
    backends are highly coupled with low-level platform details, with
    every backend standing for every platform. A backend operates on a
    processed graph (coming from the graph compiler) and executes this
    graph optimally for a specific platform or device.
  
  # API layer {#gapi_api_layer}
  
  API layer is what user interacts with when defining and using a
  pipeline (a Computation in G-API terms). API layer defines a set of
  G-API _dynamic_ objects which can be used as inputs, outputs, and
  intermediate data objects within a graph:
  * cv::GMat
  * cv::GScalar
  * cv::GArray (template class)
  
  API layer specifies a list of Operations which are defined on these
  data objects -- so called kernels. See G-API [core](@ref gapi_core)
  and [imgproc](@ref gapi_imgproc) namespaces for details on which
  operations G-API provides by default.
  
  G-API is not limited to these operations only -- users can define
  their own kernels easily using a special macro G_TYPED_KERNEL().
  
  API layer is also responsible for marshalling and storing operation
  parameters on pipeline creation. In addition to the aforementioned
  G-API dynamic objects, operations may also accept arbitrary
  parameters (more on this [here](@ref gapi_detail_params)), so API
  layer captures its values and stores internally upon the moment of
  execution.
  
  Finally, cv::GComputation and cv::GCompiled are the remaining
  important components of API layer. The former wraps a series of G-API
  expressions into an object (graph), and the latter is a product of
  graph _compilation_ (see [this chapter](@ref gapi_detail_compiler) for
  details).
  
  # Graph compiler layer {#gapi_compiler}
  
  Every G-API computation is compiled before it executes. Compilation
  process is triggered in two ways:
  * _implicitly_, when cv::GComputation::apply() is used. In this case,
    graph compilation is then immediately followed by execution.
  * _explicitly_, when cv::GComputation::compile() is used. In this case,
    a cv::GCompiled object is returned which then can be invoked as a
    C++ functor.
  
  The first way is recommended for cases when input data format is not
  known in advance -- e.g. when it comes from an arbitrary input file.
  The second way is recommended for deployment (production) scenarios
  where input data characteristics are usually predefined.
  
  Graph compilation process is built atop of ADE Framework. Initially, a
  bipartite graph is generated from expressions captured by API layer.
  This graph contains nodes of two types: _Data_ and _Operations_. Graph
  always starts and ends with a Data node(s), with Operations nodes
  in-between. Every Operation node has inputs and outputs, both are Data
  nodes.
  
  After the initial graph is generated, it is actually processed by a
  number of graph transformations, called _passes_. ADE Framework acts
  as a compiler pass management engine, and passes are written
  specifically for G-API.
  
  There are different passes which check graph validity, refine details
  on operations and data, organize nodes into clusters ("Islands") based
  on affinity or user-specified regioning[TBD], and more. Backends also
  are able to inject backend-specific passes into the compilation
  process, see more on this in the [dedicated chapter](@ref gapi_detail_meta).
  
  Result of graph compilation is a compiled object, represented by class
  cv::GCompiled. A new cv::GCompiled object is always created regardless
  if there was an explicit or implicit compilation request (see
  above). Actual graph execution happens within cv::GCompiled and is
  determined by backends which participated in the graph compilation.
  
  @sa cv::GComputation::apply(), cv::GComputation::compile(), cv::GCompiled
  
  # Backends layer {#gapi_backends}
  
  The above diagram lists two backends, _OpenCV_ and _Fluid_. _OpenCV_
  is so-called "reference backend", which implements G-API operations
  using plain old OpenCV functions. This backend is useful for
  prototyping on a familiar development system. _Fluid_ is a plugin for
  cache-efficient execution on CPU -- it implements a different
  execution policy and operates with its own, special kernels. Fluid
  backend allows to achieve less memory footprint and better memory
  locality when running on CPU.
  
  There may be more backends available, e.g. Halide, OpenCL, etc. --
  G-API provides an uniform internal API to develop backends so any
  enthusiast or a company are free to scale G-API on a new platform or
  accelerator. In terms of OpenCV infrastructure, every new backend is a
  new distinct OpenCV module, which extends G-API when build as a part
  of OpenCV.
  
  # Graph execution {#gapi_compiled}
  
  The way graph executed is defined by backends selected for
  compilation. In fact, every backend builds its own execution script as
  the final stage of graph compilation process, when an executable
  (compiled) object is being generated. For example, in OpenCV backend,
  this script is just a topologically-sorted sequence of OpenCV
  functions to call; for Fluid backend, it is a similar thing -- a
  topologically sorted list of _Agents_ processing lines of input on
  every iteration.
  
  Graph execution is triggered in two ways:
  * via cv::GComputation::apply(), with graph compiled in-place exactly
    for the given input data;
  * via cv::GCompiled::operator()(), when the graph has been precompiled.
  
  Both methods are polimorphic and take a variadic number of arguments,
  with validity checks performed in runtime. If a number, shapes, and
  formats of passed data objects differ from expected, a run-time
  exception is thrown. G-API also provides _typed_ wrappers to move
  these checks to the compile time -- see `cv::GComputationT<>`.
  
  G-API graph execution is declared stateless -- it means that a
  compiled functor (cv::GCompiled) acts like a pure C++ function and
  provides the same result for the same set of input arguments.
  
  Both execution methods take \f$N+M\f$ parameters, where \f$N\f$ is a
  number of inputs, and \f$M\f$ is a number of outputs on which a
  cv::GComputation is defined. Note that while G-API types (cv::GMat,
  etc) are used in definition, the execution methods accept OpenCV's
  traditional data types (like cv::Mat) which hold actual data -- see
  table in [parameter marshalling](@ref gapi_detail_params).
  
  @sa @ref gapi_impl, @ref gapi_kernel_api