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.
5 // Copyright (C) 2018 Intel Corporation
9 #include <memory> // unique_ptr
11 #include <opencv2/gapi/gkernel.hpp>
12 #include <opencv2/gapi/own/convert.hpp>
14 #include "api/gbackend_priv.hpp"
15 #include "backends/common/gbackend.hpp"
16 #include "compiler/gobjref.hpp"
17 #include "compiler/gislandmodel.hpp"
19 // GBackend private implementation /////////////////////////////////////////////
20 void cv::gapi::GBackend::Priv::unpackKernel(ade::Graph & /*graph */ ,
21 const ade::NodeHandle & /*op_node*/ ,
22 const GKernelImpl & /*impl */ )
24 // Default implementation is still there as Priv
25 // is instantiated by some tests.
26 // Priv is even instantiated as a mock object in a number of tests
27 // as a backend and this method is called for mock objects (doing nothing).
28 // FIXME: add a warning message here
29 // FIXME: Do something with this! Ideally this function should be "=0";
32 std::unique_ptr<cv::gimpl::GIslandExecutable>
33 cv::gapi::GBackend::Priv::compile(const ade::Graph&,
35 const std::vector<ade::NodeHandle> &) const
37 // ...and this method is here for the same reason!
42 void cv::gapi::GBackend::Priv::addBackendPasses(ade::ExecutionEngineSetupContext &)
44 // Do nothing by default, plugins may override this to
45 // add custom (backend-specific) graph transformations
48 cv::gapi::GKernelPackage cv::gapi::GBackend::Priv::auxiliaryKernels() const
53 // GBackend public implementation //////////////////////////////////////////////
54 cv::gapi::GBackend::GBackend()
58 cv::gapi::GBackend::GBackend(std::shared_ptr<cv::gapi::GBackend::Priv> &&p)
59 : m_priv(std::move(p))
63 cv::gapi::GBackend::Priv& cv::gapi::GBackend::priv()
68 const cv::gapi::GBackend::Priv& cv::gapi::GBackend::priv() const
73 std::size_t cv::gapi::GBackend::hash() const
75 return std::hash<const cv::gapi::GBackend::Priv*>{}(m_priv.get());
78 bool cv::gapi::GBackend::operator== (const cv::gapi::GBackend &rhs) const
80 return m_priv == rhs.m_priv;
83 // Abstract Host-side data manipulation ////////////////////////////////////////
84 // Reused between CPU backend and more generic GExecutor
89 // FIXME implement the below functions with visit()?
91 void bindInArg(Mag& mag, const RcDesc &rc, const GRunArg &arg, bool is_umat)
99 case GRunArg::index_of<cv::gapi::own::Mat>() :
102 #if !defined(GAPI_STANDALONE)
103 auto& mag_umat = mag.template slot<cv::UMat>()[rc.id];
104 mag_umat = to_ocv(util::get<cv::gapi::own::Mat>(arg)).getUMat(ACCESS_READ);
106 util::throw_error(std::logic_error("UMat is not supported in standalone build"));
107 #endif // !defined(GAPI_STANDALONE)
111 auto& mag_mat = mag.template slot<cv::gapi::own::Mat>()[rc.id];
112 mag_mat = util::get<cv::gapi::own::Mat>(arg);
115 #if !defined(GAPI_STANDALONE)
116 case GRunArg::index_of<cv::Mat>() :
119 auto& mag_umat = mag.template slot<cv::UMat>()[rc.id];
120 mag_umat = (util::get<cv::UMat>(arg));
124 auto& mag_mat = mag.template slot<cv::gapi::own::Mat>()[rc.id];
125 mag_mat = to_own(util::get<cv::Mat>(arg));
128 #endif // !defined(GAPI_STANDALONE)
129 default: util::throw_error(std::logic_error("content type of the runtime argument does not match to resource description ?"));
135 case GShape::GSCALAR:
137 auto& mag_scalar = mag.template slot<cv::gapi::own::Scalar>()[rc.id];
140 case GRunArg::index_of<cv::gapi::own::Scalar>() : mag_scalar = util::get<cv::gapi::own::Scalar>(arg); break;
141 #if !defined(GAPI_STANDALONE)
142 case GRunArg::index_of<cv::Scalar>() : mag_scalar = to_own(util::get<cv::Scalar>(arg)); break;
143 #endif // !defined(GAPI_STANDALONE)
144 default: util::throw_error(std::logic_error("content type of the runtime argument does not match to resource description ?"));
150 mag.template slot<cv::detail::VectorRef>()[rc.id] = util::get<cv::detail::VectorRef>(arg);
154 util::throw_error(std::logic_error("Unsupported GShape type"));
158 void bindOutArg(Mag& mag, const RcDesc &rc, const GRunArgP &arg, bool is_umat)
166 case GRunArgP::index_of<cv::gapi::own::Mat*>() :
169 #if !defined(GAPI_STANDALONE)
170 auto& mag_umat = mag.template slot<cv::UMat>()[rc.id];
171 mag_umat = to_ocv(*(util::get<cv::gapi::own::Mat*>(arg))).getUMat(ACCESS_RW);
173 util::throw_error(std::logic_error("UMat is not supported in standalone build"));
174 #endif // !defined(GAPI_STANDALONE)
178 auto& mag_mat = mag.template slot<cv::gapi::own::Mat>()[rc.id];
179 mag_mat = *util::get<cv::gapi::own::Mat*>(arg);
182 #if !defined(GAPI_STANDALONE)
183 case GRunArgP::index_of<cv::Mat*>() :
186 auto& mag_umat = mag.template slot<cv::UMat>()[rc.id];
187 mag_umat = (*util::get<cv::UMat*>(arg));
191 auto& mag_mat = mag.template slot<cv::gapi::own::Mat>()[rc.id];
192 mag_mat = to_own(*util::get<cv::Mat*>(arg));
195 #endif // !defined(GAPI_STANDALONE)
196 default: util::throw_error(std::logic_error("content type of the runtime argument does not match to resource description ?"));
201 case GShape::GSCALAR:
203 auto& mag_scalar = mag.template slot<cv::gapi::own::Scalar>()[rc.id];
206 case GRunArgP::index_of<cv::gapi::own::Scalar*>() : mag_scalar = *util::get<cv::gapi::own::Scalar*>(arg); break;
207 #if !defined(GAPI_STANDALONE)
208 case GRunArgP::index_of<cv::Scalar*>() : mag_scalar = to_own(*util::get<cv::Scalar*>(arg)); break;
209 #endif // !defined(GAPI_STANDALONE)
210 default: util::throw_error(std::logic_error("content type of the runtime argument does not match to resource description ?"));
215 mag.template slot<cv::detail::VectorRef>()[rc.id] = util::get<cv::detail::VectorRef>(arg);
219 util::throw_error(std::logic_error("Unsupported GShape type"));
224 void resetInternalData(Mag& mag, const Data &d)
226 if (d.storage != Data::Storage::INTERNAL)
232 util::get<cv::detail::ConstructVec>(d.ctor)
233 (mag.template slot<cv::detail::VectorRef>()[d.rc]);
236 case GShape::GSCALAR:
237 mag.template slot<cv::gapi::own::Scalar>()[d.rc] = cv::gapi::own::Scalar();
241 // Do nothign here - FIXME unify with initInternalData?
245 util::throw_error(std::logic_error("Unsupported GShape type"));
250 cv::GRunArg getArg(const Mag& mag, const RcDesc &ref)
252 // Wrap associated CPU object (either host or an internal one)
255 case GShape::GMAT: return GRunArg(mag.template slot<cv::gapi::own::Mat>().at(ref.id));
256 case GShape::GSCALAR: return GRunArg(mag.template slot<cv::gapi::own::Scalar>().at(ref.id));
257 // Note: .at() is intentional for GArray as object MUST be already there
258 // (and constructed by either bindIn/Out or resetInternal)
259 case GShape::GARRAY: return GRunArg(mag.template slot<cv::detail::VectorRef>().at(ref.id));
261 util::throw_error(std::logic_error("Unsupported GShape type"));
266 cv::GRunArgP getObjPtr(Mag& mag, const RcDesc &rc, bool is_umat)
273 #if !defined(GAPI_STANDALONE)
274 return GRunArgP(&mag.template slot<cv::UMat>()[rc.id]);
276 util::throw_error(std::logic_error("UMat is not supported in standalone build"));
277 #endif // !defined(GAPI_STANDALONE)
280 return GRunArgP(&mag.template slot<cv::gapi::own::Mat>()[rc.id]);
281 case GShape::GSCALAR: return GRunArgP(&mag.template slot<cv::gapi::own::Scalar>()[rc.id]);
282 // Note: .at() is intentional for GArray as object MUST be already there
283 // (and constructer by either bindIn/Out or resetInternal)
285 // FIXME(DM): For some absolutely unknown to me reason, move
286 // semantics is involved here without const_cast to const (and
287 // value from map is moved into return value GRunArgP, leaving
288 // map with broken value I've spent few late Friday hours
289 // debugging this!!!1
290 return GRunArgP(const_cast<const Mag&>(mag)
291 .template slot<cv::detail::VectorRef>().at(rc.id));
293 util::throw_error(std::logic_error("Unsupported GShape type"));
298 void writeBack(const Mag& mag, const RcDesc &rc, GRunArgP &g_arg, bool is_umat)
303 // Do nothing - should we really do anything here?
308 //simply check that memory was not reallocated, i.e.
309 //both instances of Mat pointing to the same memory
310 uchar* out_arg_data = nullptr;
311 switch (g_arg.index())
313 case GRunArgP::index_of<cv::gapi::own::Mat*>() : out_arg_data = util::get<cv::gapi::own::Mat*>(g_arg)->data; break;
314 #if !defined(GAPI_STANDALONE)
315 case GRunArgP::index_of<cv::Mat*>() : out_arg_data = util::get<cv::Mat*>(g_arg)->data; break;
316 case GRunArgP::index_of<cv::UMat*>() : out_arg_data = (util::get<cv::UMat*>(g_arg))->getMat(ACCESS_RW).data; break;
317 #endif // !defined(GAPI_STANDALONE)
318 default: util::throw_error(std::logic_error("content type of the runtime argument does not match to resource description ?"));
322 #if !defined(GAPI_STANDALONE)
323 auto& in_mag = mag.template slot<cv::UMat>().at(rc.id);
324 GAPI_Assert((out_arg_data == (in_mag.getMat(ACCESS_RW).data)) && " data for output parameters was reallocated ?");
326 util::throw_error(std::logic_error("UMat is not supported in standalone build"));
327 #endif // !defined(GAPI_STANDALONE)
331 auto& in_mag = mag.template slot<cv::gapi::own::Mat>().at(rc.id);
332 GAPI_Assert((out_arg_data == in_mag.data) && " data for output parameters was reallocated ?");
337 case GShape::GSCALAR:
339 switch (g_arg.index())
341 case GRunArgP::index_of<cv::gapi::own::Scalar*>() : *util::get<cv::gapi::own::Scalar*>(g_arg) = mag.template slot<cv::gapi::own::Scalar>().at(rc.id); break;
342 #if !defined(GAPI_STANDALONE)
343 case GRunArgP::index_of<cv::Scalar*>() : *util::get<cv::Scalar*>(g_arg) = cv::gapi::own::to_ocv(mag.template slot<cv::gapi::own::Scalar>().at(rc.id)); break;
344 #endif // !defined(GAPI_STANDALONE)
345 default: util::throw_error(std::logic_error("content type of the runtime argument does not match to resource description ?"));
351 util::throw_error(std::logic_error("Unsupported GShape type"));
356 } // namespace magazine
358 void createMat(const cv::GMatDesc desc, cv::gapi::own::Mat& mat)
360 const auto type = desc.planar ? desc.depth : CV_MAKETYPE(desc.depth, desc.chan);
361 const auto size = desc.planar ? cv::gapi::own::Size{desc.size.width, desc.size.height*desc.chan}
363 mat.create(size, type);
366 #if !defined(GAPI_STANDALONE)
367 void createMat(const cv::GMatDesc desc, cv::Mat& mat)
369 const auto type = desc.planar ? desc.depth : CV_MAKETYPE(desc.depth, desc.chan);
370 const auto size = desc.planar ? cv::Size{desc.size.width, desc.size.height*desc.chan}
371 : cv::gapi::own::to_ocv(desc.size);
372 mat.create(size, type);