garray.hpp 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  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. #ifndef OPENCV_GAPI_GARRAY_HPP
  7. #define OPENCV_GAPI_GARRAY_HPP
  8. #include <functional>
  9. #include <ostream>
  10. #include <vector>
  11. #include <memory>
  12. #include <opencv2/gapi/own/exports.hpp>
  13. #include <opencv2/gapi/opencv_includes.hpp>
  14. #include <opencv2/gapi/util/variant.hpp>
  15. #include <opencv2/gapi/util/throw.hpp>
  16. #include "opencv2/gapi/own/assert.hpp"
  17. namespace cv
  18. {
  19. // Forward declaration; GNode and GOrigin are an internal
  20. // (user-inaccessible) classes.
  21. class GNode;
  22. struct GOrigin;
  23. template<typename T> class GArray;
  24. /**
  25. * \addtogroup gapi_meta_args
  26. * @{
  27. */
  28. struct GArrayDesc
  29. {
  30. // FIXME: Body
  31. // FIXME: Also implement proper operator== then
  32. bool operator== (const GArrayDesc&) const { return true; }
  33. };
  34. template<typename U> GArrayDesc descr_of(const std::vector<U> &) { return {};}
  35. static inline GArrayDesc empty_array_desc() {return {}; }
  36. /** @} */
  37. std::ostream& operator<<(std::ostream& os, const cv::GArrayDesc &desc);
  38. namespace detail
  39. {
  40. // ConstructVec is a callback which stores information about T and is used by
  41. // G-API runtime to construct arrays in host memory (T remains opaque for G-API).
  42. // ConstructVec is carried into G-API internals by GArrayU.
  43. // Currently it is suitable for Host (CPU) plugins only, real offload may require
  44. // more information for manual memory allocation on-device.
  45. class VectorRef;
  46. using ConstructVec = std::function<void(VectorRef&)>;
  47. // This class strips type information from GArray<T> and makes it usable
  48. // in the G-API graph compiler (expression unrolling, graph generation, etc).
  49. // Part of GProtoArg.
  50. class GAPI_EXPORTS GArrayU
  51. {
  52. public:
  53. GArrayU(const GNode &n, std::size_t out); // Operation result constructor
  54. GOrigin& priv(); // Internal use only
  55. const GOrigin& priv() const; // Internal use only
  56. protected:
  57. GArrayU(); // Default constructor
  58. template<class> friend class cv::GArray; // (avialable to GArray<T> only)
  59. void setConstructFcn(ConstructVec &&cv); // Store T-aware constructor
  60. std::shared_ptr<GOrigin> m_priv;
  61. };
  62. // This class represents a typed STL vector reference.
  63. // Depending on origins, this reference may be either "just a" reference to
  64. // an object created externally, OR actually own the underlying object
  65. // (be value holder).
  66. class BasicVectorRef
  67. {
  68. public:
  69. std::size_t m_elemSize = 0ul;
  70. cv::GArrayDesc m_desc;
  71. virtual ~BasicVectorRef() {}
  72. };
  73. template<typename T> class VectorRefT: public BasicVectorRef
  74. {
  75. using empty_t = util::monostate;
  76. using ro_ext_t = const std::vector<T> *;
  77. using rw_ext_t = std::vector<T> *;
  78. using rw_own_t = std::vector<T> ;
  79. util::variant<empty_t, ro_ext_t, rw_ext_t, rw_own_t> m_ref;
  80. inline bool isEmpty() const { return util::holds_alternative<empty_t>(m_ref); }
  81. inline bool isROExt() const { return util::holds_alternative<ro_ext_t>(m_ref); }
  82. inline bool isRWExt() const { return util::holds_alternative<rw_ext_t>(m_ref); }
  83. inline bool isRWOwn() const { return util::holds_alternative<rw_own_t>(m_ref); }
  84. void init(const std::vector<T>* vec = nullptr)
  85. {
  86. m_elemSize = sizeof(T);
  87. if (vec) m_desc = cv::descr_of(*vec);
  88. }
  89. public:
  90. VectorRefT() { init(); }
  91. virtual ~VectorRefT() {}
  92. explicit VectorRefT(const std::vector<T>& vec) : m_ref(&vec) { init(&vec); }
  93. explicit VectorRefT(std::vector<T>& vec) : m_ref(&vec) { init(&vec); }
  94. explicit VectorRefT(std::vector<T>&& vec) : m_ref(std::move(vec)) { init(&vec); }
  95. // Reset a VectorRefT. Called only for objects instantiated
  96. // internally in G-API (e.g. temporary GArray<T>'s within a
  97. // computation). Reset here means both initialization
  98. // (creating an object) and reset (discarding its existing
  99. // content before the next execution). Must never be called
  100. // for external VectorRefTs.
  101. void reset()
  102. {
  103. if (isEmpty())
  104. {
  105. std::vector<T> empty_vector;
  106. m_desc = cv::descr_of(empty_vector);
  107. m_ref = std::move(empty_vector);
  108. GAPI_Assert(isRWOwn());
  109. }
  110. else if (isRWOwn())
  111. {
  112. util::get<rw_own_t>(m_ref).clear();
  113. }
  114. else GAPI_Assert(false); // shouldn't be called in *EXT modes
  115. }
  116. // Obtain a WRITE reference to underlying object
  117. // Used by CPU kernel API wrappers when a kernel execution frame
  118. // is created
  119. std::vector<T>& wref()
  120. {
  121. GAPI_Assert(isRWExt() || isRWOwn());
  122. if (isRWExt()) return *util::get<rw_ext_t>(m_ref);
  123. if (isRWOwn()) return util::get<rw_own_t>(m_ref);
  124. util::throw_error(std::logic_error("Impossible happened"));
  125. }
  126. // Obtain a READ reference to underlying object
  127. // Used by CPU kernel API wrappers when a kernel execution frame
  128. // is created
  129. const std::vector<T>& rref() const
  130. {
  131. // ANY vector can be accessed for reading, even if it declared for
  132. // output. Example -- a GComputation from [in] to [out1,out2]
  133. // where [out2] is a result of operation applied to [out1]:
  134. //
  135. // GComputation boundary
  136. // . . . . . . .
  137. // . .
  138. // [in] ----> foo() ----> [out1]
  139. // . . :
  140. // . . . .:. . .
  141. // . V .
  142. // . bar() ---> [out2]
  143. // . . . . . . . . . . . .
  144. //
  145. if (isROExt()) return *util::get<ro_ext_t>(m_ref);
  146. if (isRWExt()) return *util::get<rw_ext_t>(m_ref);
  147. if (isRWOwn()) return util::get<rw_own_t>(m_ref);
  148. util::throw_error(std::logic_error("Impossible happened"));
  149. }
  150. };
  151. // This class strips type information from VectorRefT<> and makes it usable
  152. // in the G-API executables (carrying run-time data/information to kernels).
  153. // Part of GRunArg.
  154. // Its methods are typed proxies to VectorRefT<T>.
  155. // VectorRef maintains "reference" semantics so two copies of VectoRef refer
  156. // to the same underlying object.
  157. // FIXME: Put a good explanation on why cv::OutputArray doesn't fit this role
  158. class VectorRef
  159. {
  160. std::shared_ptr<BasicVectorRef> m_ref;
  161. template<typename T> inline void check() const
  162. {
  163. GAPI_DbgAssert(dynamic_cast<VectorRefT<T>*>(m_ref.get()) != nullptr);
  164. GAPI_Assert(sizeof(T) == m_ref->m_elemSize);
  165. }
  166. public:
  167. VectorRef() = default;
  168. template<typename T> explicit VectorRef(const std::vector<T>& vec) : m_ref(new VectorRefT<T>(vec)) {}
  169. template<typename T> explicit VectorRef(std::vector<T>& vec) : m_ref(new VectorRefT<T>(vec)) {}
  170. template<typename T> explicit VectorRef(std::vector<T>&& vec) : m_ref(new VectorRefT<T>(vec)) {}
  171. template<typename T> void reset()
  172. {
  173. if (!m_ref) m_ref.reset(new VectorRefT<T>());
  174. check<T>();
  175. static_cast<VectorRefT<T>&>(*m_ref).reset();
  176. }
  177. template<typename T> std::vector<T>& wref()
  178. {
  179. check<T>();
  180. return static_cast<VectorRefT<T>&>(*m_ref).wref();
  181. }
  182. template<typename T> const std::vector<T>& rref() const
  183. {
  184. check<T>();
  185. return static_cast<VectorRefT<T>&>(*m_ref).rref();
  186. }
  187. cv::GArrayDesc descr_of() const
  188. {
  189. return m_ref->m_desc;
  190. }
  191. };
  192. } // namespace detail
  193. /** \addtogroup gapi_data_objects
  194. * @{
  195. */
  196. template<typename T> class GArray
  197. {
  198. public:
  199. GArray() { putDetails(); } // Empty constructor
  200. explicit GArray(detail::GArrayU &&ref) // GArrayU-based constructor
  201. : m_ref(ref) { putDetails(); } // (used by GCall, not for users)
  202. detail::GArrayU strip() const { return m_ref; }
  203. private:
  204. static void VCTor(detail::VectorRef& vref) { vref.reset<T>(); }
  205. void putDetails() {m_ref.setConstructFcn(&VCTor); }
  206. detail::GArrayU m_ref;
  207. };
  208. /** @} */
  209. } // namespace cv
  210. #endif // OPENCV_GAPI_GARRAY_HPP