Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Tetragramm
GitHub Repository: Tetragramm/opencv
Path: blob/master/modules/gapi/src/api/gcomputation.cpp
16339 views
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 Intel Corporation
6
7
8
#include "precomp.hpp"
9
#include <algorithm> // remove_if
10
#include <cctype> // isspace (non-locale version)
11
#include <ade/util/algorithm.hpp>
12
13
#include "logger.hpp" // GAPI_LOG
14
15
#include "opencv2/gapi/gcomputation.hpp"
16
#include "opencv2/gapi/gkernel.hpp"
17
18
#include "api/gcomputation_priv.hpp"
19
#include "api/gcall_priv.hpp"
20
#include "api/gnode_priv.hpp"
21
22
#include "compiler/gmodelbuilder.hpp"
23
#include "compiler/gcompiler.hpp"
24
25
// cv::GComputation private implementation /////////////////////////////////////
26
// <none>
27
28
// cv::GComputation public implementation //////////////////////////////////////
29
cv::GComputation::GComputation(const Generator& gen)
30
: m_priv(gen().m_priv)
31
{
32
}
33
34
cv::GComputation::GComputation(GMat in, GMat out)
35
: cv::GComputation(cv::GIn(in), cv::GOut(out))
36
{
37
}
38
39
40
cv::GComputation::GComputation(GMat in, GScalar out)
41
: cv::GComputation(cv::GIn(in), cv::GOut(out))
42
{
43
}
44
45
cv::GComputation::GComputation(GMat in1, GMat in2, GMat out)
46
: cv::GComputation(cv::GIn(in1, in2), cv::GOut(out))
47
{
48
}
49
50
cv::GComputation::GComputation(GMat in1, GMat in2, GScalar out)
51
: cv::GComputation(cv::GIn(in1, in2), cv::GOut(out))
52
{
53
}
54
55
cv::GComputation::GComputation(const std::vector<GMat> &ins,
56
const std::vector<GMat> &outs)
57
: m_priv(new Priv())
58
{
59
const auto wrap = [](cv::GMat m) { return GProtoArg(m); };
60
ade::util::transform(ins, std::back_inserter(m_priv->m_ins), wrap);
61
ade::util::transform(outs, std::back_inserter(m_priv->m_outs), wrap);
62
}
63
64
cv::GComputation::GComputation(cv::GProtoInputArgs &&ins,
65
cv::GProtoOutputArgs &&outs)
66
: m_priv(new Priv())
67
{
68
m_priv->m_ins = std::move(ins.m_args);
69
m_priv->m_outs = std::move(outs.m_args);
70
}
71
72
cv::GCompiled cv::GComputation::compile(GMetaArgs &&metas, GCompileArgs &&args)
73
{
74
// FIXME: Cache gcompiled per parameters here?
75
cv::gimpl::GCompiler comp(*this, std::move(metas), std::move(args));
76
return comp.compile();
77
}
78
79
void cv::GComputation::apply(GRunArgs &&ins, GRunArgsP &&outs, GCompileArgs &&args)
80
{
81
const auto in_metas = descr_of(ins);
82
// FIXME Graph should be recompiled when GCompileArgs have changed
83
if (m_priv->m_lastMetas != in_metas)
84
{
85
// FIXME: Had to construct temporary object as compile() takes && (r-value)
86
m_priv->m_lastCompiled = compile(GMetaArgs(in_metas), std::move(args));
87
m_priv->m_lastMetas = in_metas; // Update only here, if compile() was ok
88
}
89
m_priv->m_lastCompiled(std::move(ins), std::move(outs));
90
}
91
92
void cv::GComputation::apply(const std::vector<cv::gapi::own::Mat> &ins,
93
const std::vector<cv::gapi::own::Mat> &outs,
94
GCompileArgs &&args)
95
{
96
GRunArgs call_ins;
97
GRunArgsP call_outs;
98
99
auto tmp = outs;
100
for (const cv::gapi::own::Mat &m : ins) { call_ins.emplace_back(m); }
101
for ( cv::gapi::own::Mat &m : tmp) { call_outs.emplace_back(&m); }
102
103
apply(std::move(call_ins), std::move(call_outs), std::move(args));
104
}
105
106
#if !defined(GAPI_STANDALONE)
107
void cv::GComputation::apply(cv::Mat in, cv::Mat &out, GCompileArgs &&args)
108
{
109
apply(cv::gin(in), cv::gout(out), std::move(args));
110
// FIXME: The following doesn't work!
111
// Operation result is not replicated into user's object
112
// apply({GRunArg(in)}, {GRunArg(out)});
113
}
114
115
void cv::GComputation::apply(cv::Mat in, cv::Scalar &out, GCompileArgs &&args)
116
{
117
apply(cv::gin(in), cv::gout(out), std::move(args));
118
}
119
120
void cv::GComputation::apply(cv::Mat in1, cv::Mat in2, cv::Mat &out, GCompileArgs &&args)
121
{
122
apply(cv::gin(in1, in2), cv::gout(out), std::move(args));
123
}
124
125
void cv::GComputation::apply(cv::Mat in1, cv::Mat in2, cv::Scalar &out, GCompileArgs &&args)
126
{
127
apply(cv::gin(in1, in2), cv::gout(out), std::move(args));
128
}
129
130
void cv::GComputation::apply(const std::vector<cv::Mat> &ins,
131
const std::vector<cv::Mat> &outs,
132
GCompileArgs &&args)
133
{
134
GRunArgs call_ins;
135
GRunArgsP call_outs;
136
137
// Make a temporary copy of vector outs - cv::Mats are copies anyway
138
auto tmp = outs;
139
for (const cv::Mat &m : ins) { call_ins.emplace_back(m); }
140
for ( cv::Mat &m : tmp) { call_outs.emplace_back(&m); }
141
142
apply(std::move(call_ins), std::move(call_outs), std::move(args));
143
}
144
#endif // !defined(GAPI_STANDALONE)
145
146
cv::GComputation::Priv& cv::GComputation::priv()
147
{
148
return *m_priv;
149
}
150
151
const cv::GComputation::Priv& cv::GComputation::priv() const
152
{
153
return *m_priv;
154
}
155
156
// Islands /////////////////////////////////////////////////////////////////////
157
158
void cv::gapi::island(const std::string &name,
159
GProtoInputArgs &&ins,
160
GProtoOutputArgs &&outs)
161
{
162
{
163
// Island must have a printable name.
164
// Forbid names which contain only spaces.
165
GAPI_Assert(!name.empty());
166
const auto first_printable_it = std::find_if_not(name.begin(), name.end(), isspace);
167
const bool likely_printable = first_printable_it != name.end();
168
GAPI_Assert(likely_printable);
169
}
170
// Even if the name contains spaces, keep it unmodified as user will
171
// then use this string to assign affinity, etc.
172
173
// First, set island tags on all operations from `ins` to `outs`
174
auto island = cv::gimpl::unrollExpr(ins.m_args, outs.m_args);
175
if (island.all_ops.empty())
176
{
177
util::throw_error(std::logic_error("Operation range is empty"));
178
}
179
for (auto &op_expr_node : island.all_ops)
180
{
181
auto &op_expr_node_p = op_expr_node.priv();
182
183
GAPI_Assert(op_expr_node.shape() == GNode::NodeShape::CALL);
184
const GCall& call = op_expr_node.call();
185
const GCall::Priv& call_p = call.priv();
186
187
if (!op_expr_node_p.m_island.empty())
188
{
189
util::throw_error(std::logic_error
190
( "Operation " + call_p.m_k.name
191
+ " is already assigned to island \""
192
+ op_expr_node_p.m_island + "\""));
193
}
194
else
195
{
196
op_expr_node_p.m_island = name;
197
GAPI_LOG_INFO(NULL,
198
"Assigned " << call_p.m_k.name << "_" << &call_p <<
199
" to island \"" << name << "\"");
200
}
201
}
202
203
// Note - this function only sets islands to all operations in
204
// expression tree, it is just a first step.
205
// The second step is assigning intermediate data objects to Islands,
206
// see passes::initIslands for details.
207
}
208
209