github.com/kaydxh/golang@v0.0.131/pkg/gocv/cgo/third_path/opencv4/include/opencv2/gapi/garray.hpp (about) 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-2020 Intel Corporation 6 7 8 #ifndef OPENCV_GAPI_GARRAY_HPP 9 #define OPENCV_GAPI_GARRAY_HPP 10 11 #include <functional> 12 #include <ostream> 13 #include <vector> 14 #include <memory> 15 16 #include <opencv2/gapi/own/exports.hpp> 17 #include <opencv2/gapi/opencv_includes.hpp> 18 19 #include <opencv2/gapi/util/variant.hpp> 20 #include <opencv2/gapi/util/throw.hpp> 21 #include <opencv2/gapi/own/assert.hpp> 22 23 #include <opencv2/gapi/gmat.hpp> // flatten_g only! 24 #include <opencv2/gapi/gscalar.hpp> // flatten_g only! 25 26 namespace cv 27 { 28 // Forward declaration; GNode and GOrigin are an internal 29 // (user-inaccessible) classes. 30 class GNode; 31 struct GOrigin; 32 template<typename T> class GArray; 33 34 /** 35 * \addtogroup gapi_meta_args 36 * @{ 37 */ 38 struct GAPI_EXPORTS_W_SIMPLE GArrayDesc 39 { 40 // FIXME: Body 41 // FIXME: Also implement proper operator== then 42 bool operator== (const GArrayDesc&) const { return true; } 43 }; 44 template<typename U> GArrayDesc descr_of(const std::vector<U> &) { return {};} 45 GAPI_EXPORTS_W inline GArrayDesc empty_array_desc() {return {}; } 46 /** @} */ 47 48 std::ostream& operator<<(std::ostream& os, const cv::GArrayDesc &desc); 49 50 namespace detail 51 { 52 // ConstructVec is a callback which stores information about T and is used by 53 // G-API runtime to construct arrays in host memory (T remains opaque for G-API). 54 // ConstructVec is carried into G-API internals by GArrayU. 55 // Currently it is suitable for Host (CPU) plugins only, real offload may require 56 // more information for manual memory allocation on-device. 57 class VectorRef; 58 using ConstructVec = std::function<void(VectorRef&)>; 59 60 // This is the base struct for GArrayU type holder 61 struct TypeHintBase{virtual ~TypeHintBase() = default;}; 62 63 // This class holds type of initial GArray to be checked from GArrayU 64 template <typename T> 65 struct TypeHint final : public TypeHintBase{}; 66 67 // This class strips type information from GArray<T> and makes it usable 68 // in the G-API graph compiler (expression unrolling, graph generation, etc). 69 // Part of GProtoArg. 70 class GAPI_EXPORTS GArrayU 71 { 72 public: 73 GArrayU(const GNode &n, std::size_t out); // Operation result constructor 74 75 template <typename T> 76 bool holds() const; // Check if was created from GArray<T> 77 78 GOrigin& priv(); // Internal use only 79 const GOrigin& priv() const; // Internal use only 80 81 protected: 82 GArrayU(); // Default constructor 83 GArrayU(const detail::VectorRef& vref); // Constant value constructor 84 template<class> friend class cv::GArray; // (available to GArray<T> only) 85 86 void setConstructFcn(ConstructVec &&cv); // Store T-aware constructor 87 88 template <typename T> 89 void specifyType(); // Store type of initial GArray<T> 90 91 template <typename T> 92 void storeKind(); 93 94 void setKind(cv::detail::OpaqueKind); 95 96 std::shared_ptr<GOrigin> m_priv; 97 std::shared_ptr<TypeHintBase> m_hint; 98 }; 99 100 template <typename T> 101 bool GArrayU::holds() const{ 102 GAPI_Assert(m_hint != nullptr); 103 using U = typename std::decay<T>::type; 104 return dynamic_cast<TypeHint<U>*>(m_hint.get()) != nullptr; 105 }; 106 107 template <typename T> 108 void GArrayU::specifyType(){ 109 m_hint.reset(new TypeHint<typename std::decay<T>::type>); 110 }; 111 112 template <typename T> 113 void GArrayU::storeKind(){ 114 setKind(cv::detail::GOpaqueTraits<T>::kind); 115 }; 116 117 // This class represents a typed STL vector reference. 118 // Depending on origins, this reference may be either "just a" reference to 119 // an object created externally, OR actually own the underlying object 120 // (be value holder). 121 class BasicVectorRef 122 { 123 public: 124 // These fields are set by the derived class(es) 125 std::size_t m_elemSize = 0ul; 126 cv::GArrayDesc m_desc; 127 virtual ~BasicVectorRef() {} 128 129 virtual void mov(BasicVectorRef &ref) = 0; 130 virtual const void* ptr() const = 0; 131 virtual std::size_t size() const = 0; 132 }; 133 134 template<typename T> class VectorRefT final: public BasicVectorRef 135 { 136 using empty_t = util::monostate; 137 using ro_ext_t = const std::vector<T> *; 138 using rw_ext_t = std::vector<T> *; 139 using rw_own_t = std::vector<T> ; 140 util::variant<empty_t, ro_ext_t, rw_ext_t, rw_own_t> m_ref; 141 142 inline bool isEmpty() const { return util::holds_alternative<empty_t>(m_ref); } 143 inline bool isROExt() const { return util::holds_alternative<ro_ext_t>(m_ref); } 144 inline bool isRWExt() const { return util::holds_alternative<rw_ext_t>(m_ref); } 145 inline bool isRWOwn() const { return util::holds_alternative<rw_own_t>(m_ref); } 146 147 void init(const std::vector<T>* vec = nullptr) 148 { 149 m_elemSize = sizeof(T); 150 if (vec) m_desc = cv::descr_of(*vec); 151 } 152 153 public: 154 VectorRefT() { init(); } 155 virtual ~VectorRefT() {} 156 157 explicit VectorRefT(const std::vector<T>& vec) : m_ref(&vec) { init(&vec); } 158 explicit VectorRefT(std::vector<T>& vec) : m_ref(&vec) { init(&vec); } 159 explicit VectorRefT(std::vector<T>&& vec) : m_ref(std::move(vec)) { init(&vec); } 160 161 // Reset a VectorRefT. Called only for objects instantiated 162 // internally in G-API (e.g. temporary GArray<T>'s within a 163 // computation). Reset here means both initialization 164 // (creating an object) and reset (discarding its existing 165 // content before the next execution). Must never be called 166 // for external VectorRefTs. 167 void reset() 168 { 169 if (isEmpty()) 170 { 171 std::vector<T> empty_vector; 172 m_desc = cv::descr_of(empty_vector); 173 m_ref = std::move(empty_vector); 174 GAPI_Assert(isRWOwn()); 175 } 176 else if (isRWOwn()) 177 { 178 util::get<rw_own_t>(m_ref).clear(); 179 } 180 else GAPI_Assert(false); // shouldn't be called in *EXT modes 181 } 182 183 // Obtain a WRITE reference to underlying object 184 // Used by CPU kernel API wrappers when a kernel execution frame 185 // is created 186 std::vector<T>& wref() 187 { 188 GAPI_Assert(isRWExt() || isRWOwn()); 189 if (isRWExt()) return *util::get<rw_ext_t>(m_ref); 190 if (isRWOwn()) return util::get<rw_own_t>(m_ref); 191 util::throw_error(std::logic_error("Impossible happened")); 192 } 193 194 // Obtain a READ reference to underlying object 195 // Used by CPU kernel API wrappers when a kernel execution frame 196 // is created 197 const std::vector<T>& rref() const 198 { 199 // ANY vector can be accessed for reading, even if it declared for 200 // output. Example -- a GComputation from [in] to [out1,out2] 201 // where [out2] is a result of operation applied to [out1]: 202 // 203 // GComputation boundary 204 // . . . . . . . 205 // . . 206 // [in] ----> foo() ----> [out1] 207 // . . : 208 // . . . .:. . . 209 // . V . 210 // . bar() ---> [out2] 211 // . . . . . . . . . . . . 212 // 213 if (isROExt()) return *util::get<ro_ext_t>(m_ref); 214 if (isRWExt()) return *util::get<rw_ext_t>(m_ref); 215 if (isRWOwn()) return util::get<rw_own_t>(m_ref); 216 util::throw_error(std::logic_error("Impossible happened")); 217 } 218 219 virtual void mov(BasicVectorRef &v) override { 220 VectorRefT<T> *tv = dynamic_cast<VectorRefT<T>*>(&v); 221 GAPI_Assert(tv != nullptr); 222 wref() = std::move(tv->wref()); 223 } 224 225 virtual const void* ptr() const override { return &rref(); } 226 virtual std::size_t size() const override { return rref().size(); } 227 }; 228 229 // This class strips type information from VectorRefT<> and makes it usable 230 // in the G-API executables (carrying run-time data/information to kernels). 231 // Part of GRunArg. 232 // Its methods are typed proxies to VectorRefT<T>. 233 // VectorRef maintains "reference" semantics so two copies of VectoRef refer 234 // to the same underlying object. 235 // FIXME: Put a good explanation on why cv::OutputArray doesn't fit this role 236 class VectorRef 237 { 238 std::shared_ptr<BasicVectorRef> m_ref; 239 cv::detail::OpaqueKind m_kind; 240 241 template<typename T> inline void check() const 242 { 243 GAPI_DbgAssert(dynamic_cast<VectorRefT<T>*>(m_ref.get()) != nullptr); 244 GAPI_Assert(sizeof(T) == m_ref->m_elemSize); 245 } 246 247 public: 248 VectorRef() = default; 249 template<typename T> explicit VectorRef(const std::vector<T>& vec) 250 : m_ref(new VectorRefT<T>(vec)) 251 , m_kind(GOpaqueTraits<T>::kind) 252 {} 253 template<typename T> explicit VectorRef(std::vector<T>& vec) 254 : m_ref(new VectorRefT<T>(vec)) 255 , m_kind(GOpaqueTraits<T>::kind) 256 {} 257 template<typename T> explicit VectorRef(std::vector<T>&& vec) 258 : m_ref(new VectorRefT<T>(std::move(vec))) 259 , m_kind(GOpaqueTraits<T>::kind) 260 {} 261 262 cv::detail::OpaqueKind getKind() const 263 { 264 return m_kind; 265 } 266 267 template<typename T> void reset() 268 { 269 if (!m_ref) m_ref.reset(new VectorRefT<T>()); 270 check<T>(); 271 storeKind<T>(); 272 static_cast<VectorRefT<T>&>(*m_ref).reset(); 273 } 274 275 template <typename T> 276 void storeKind() 277 { 278 m_kind = cv::detail::GOpaqueTraits<T>::kind; 279 } 280 281 template<typename T> std::vector<T>& wref() 282 { 283 check<T>(); 284 return static_cast<VectorRefT<T>&>(*m_ref).wref(); 285 } 286 287 template<typename T> const std::vector<T>& rref() const 288 { 289 check<T>(); 290 return static_cast<VectorRefT<T>&>(*m_ref).rref(); 291 } 292 293 // Check if was created for/from std::vector<T> 294 template <typename T> bool holds() const 295 { 296 if (!m_ref) return false; 297 using U = typename std::decay<T>::type; 298 return dynamic_cast<VectorRefT<U>*>(m_ref.get()) != nullptr; 299 } 300 301 void mov(VectorRef &v) 302 { 303 m_ref->mov(*v.m_ref); 304 } 305 306 cv::GArrayDesc descr_of() const 307 { 308 return m_ref->m_desc; 309 } 310 311 std::size_t size() const 312 { 313 return m_ref->size(); 314 } 315 316 // May be used to uniquely identify this object internally 317 const void *ptr() const { return m_ref->ptr(); } 318 }; 319 320 // Helper (FIXME: work-around?) 321 // stripping G types to their host types 322 // like cv::GArray<GMat> would still map to std::vector<cv::Mat> 323 // but not to std::vector<cv::GMat> 324 #if defined(GAPI_STANDALONE) 325 # define FLATTEN_NS cv::gapi::own 326 #else 327 # define FLATTEN_NS cv 328 #endif 329 template<class T> struct flatten_g; 330 template<> struct flatten_g<cv::GMat> { using type = FLATTEN_NS::Mat; }; 331 template<> struct flatten_g<cv::GScalar> { using type = FLATTEN_NS::Scalar; }; 332 template<class T> struct flatten_g<GArray<T>> { using type = std::vector<T>; }; 333 template<class T> struct flatten_g { using type = T; }; 334 #undef FLATTEN_NS 335 // FIXME: the above mainly duplicates "ProtoToParam" thing from gtyped.hpp 336 // but I decided not to include gtyped here - probably worth moving that stuff 337 // to some common place? (DM) 338 } // namespace detail 339 340 /** \addtogroup gapi_data_objects 341 * @{ 342 */ 343 /** 344 * @brief `cv::GArray<T>` template class represents a list of objects 345 * of class `T` in the graph. 346 * 347 * `cv::GArray<T>` describes a functional relationship between 348 * operations consuming and producing arrays of objects of class 349 * `T`. The primary purpose of `cv::GArray<T>` is to represent a 350 * dynamic list of objects -- where the size of the list is not known 351 * at the graph construction or compile time. Examples include: corner 352 * and feature detectors (`cv::GArray<cv::Point>`), object detection 353 * and tracking results (`cv::GArray<cv::Rect>`). Programmers can use 354 * their own types with `cv::GArray<T>` in the custom operations. 355 * 356 * Similar to `cv::GScalar`, `cv::GArray<T>` may be value-initialized 357 * -- in this case a graph-constant value is associated with the object. 358 * 359 * `GArray<T>` is a virtual counterpart of `std::vector<T>`, which is 360 * usually used to represent the `GArray<T>` data in G-API during the 361 * execution. 362 * 363 * @sa `cv::GOpaque<T>` 364 */ 365 template<typename T> class GArray 366 { 367 public: 368 // Host type (or Flat type) - the type this GArray is actually 369 // specified to. 370 /// @private 371 using HT = typename detail::flatten_g<typename std::decay<T>::type>::type; 372 373 /** 374 * @brief Constructs a value-initialized `cv::GArray<T>` 375 * 376 * `cv::GArray<T>` objects may have their values 377 * be associated at graph construction time. It is useful when 378 * some operation has a `cv::GArray<T>` input which doesn't change during 379 * the program execution, and is set only once. In this case, 380 * there is no need to declare such `cv::GArray<T>` as a graph input. 381 * 382 * @note The value of `cv::GArray<T>` may be overwritten by assigning some 383 * other `cv::GArray<T>` to the object using `operator=` -- on the 384 * assigment, the old association or value is discarded. 385 * 386 * @param v a std::vector<T> to associate with this 387 * `cv::GArray<T>` object. Vector data is copied into the 388 * `cv::GArray<T>` (no reference to the passed data is held). 389 */ 390 explicit GArray(const std::vector<HT>& v) // Constant value constructor 391 : m_ref(detail::GArrayU(detail::VectorRef(v))) { putDetails(); } 392 393 /** 394 * @overload 395 * @brief Constructs a value-initialized `cv::GArray<T>` 396 * 397 * @param v a std::vector<T> to associate with this 398 * `cv::GArray<T>` object. Vector data is moved into the `cv::GArray<T>`. 399 */ 400 explicit GArray(std::vector<HT>&& v) // Move-constructor 401 : m_ref(detail::GArrayU(detail::VectorRef(std::move(v)))) { putDetails(); } 402 403 /** 404 * @brief Constructs an empty `cv::GArray<T>` 405 * 406 * Normally, empty G-API data objects denote a starting point of 407 * the graph. When an empty `cv::GArray<T>` is assigned to a result 408 * of some operation, it obtains a functional link to this 409 * operation (and is not empty anymore). 410 */ 411 GArray() { putDetails(); } // Empty constructor 412 413 /// @private 414 explicit GArray(detail::GArrayU &&ref) // GArrayU-based constructor 415 : m_ref(ref) { putDetails(); } // (used by GCall, not for users) 416 417 /// @private 418 detail::GArrayU strip() const { 419 return m_ref; 420 } 421 /// @private 422 static void VCtor(detail::VectorRef& vref) { 423 vref.reset<HT>(); 424 } 425 426 private: 427 void putDetails() { 428 m_ref.setConstructFcn(&VCtor); 429 m_ref.specifyType<HT>(); // FIXME: to unify those 2 to avoid excessive dynamic_cast 430 m_ref.storeKind<HT>(); // 431 } 432 433 detail::GArrayU m_ref; 434 }; 435 436 /** @} */ 437 438 } // namespace cv 439 440 #endif // OPENCV_GAPI_GARRAY_HPP