Merge pull request #18196 from mpashchenkov:mp/garray-initialization
authorMaxim Pashchenkov <maxim.pashchenkov@intel.com>
Fri, 18 Sep 2020 13:06:23 +0000 (16:06 +0300)
committerGitHub <noreply@github.com>
Fri, 18 Sep 2020 13:06:23 +0000 (13:06 +0000)
[G-API]: Add GArray initialization support

* Added GArray initialization (CONST_VALUE, GScalar analog) and test for this

* Whitespaces

* And one more space

* Trailing whitespace

* Test name changed. Build with magic commands.

* GArray works with rvalue initialization

* Code cleanup

* Ternary operator in the initialization list.

modules/gapi/include/opencv2/gapi/garray.hpp
modules/gapi/src/api/garray.cpp
modules/gapi/src/api/gorigin.cpp
modules/gapi/src/api/gproto.cpp
modules/gapi/src/compiler/gobjref.hpp
modules/gapi/src/executor/gexecutor.cpp
modules/gapi/test/gapi_array_tests.cpp

index 99f6661..d87ec8c 100644 (file)
@@ -80,6 +80,7 @@ namespace detail
 
     protected:
         GArrayU();                                // Default constructor
+        GArrayU(const detail::VectorRef& vref);   // Constant value constructor
         template<class> friend class cv::GArray;  //  (available to GArray<T> only)
 
         void setConstructFcn(ConstructVec &&cv);  // Store T-aware constructor
@@ -328,6 +329,14 @@ namespace detail
 template<typename T> class GArray
 {
 public:
+    // Host type (or Flat type) - the type this GArray is actually
+    // specified to.
+    using HT = typename detail::flatten_g<typename std::decay<T>::type>::type;
+
+    explicit GArray(const std::vector<HT>& v) // Constant value constructor
+        : m_ref(detail::GArrayU(detail::VectorRef(v))) { putDetails(); }
+    explicit GArray(std::vector<HT>&& v)      // Move-constructor
+        : m_ref(detail::GArrayU(detail::VectorRef(std::move(v)))) { putDetails(); }
     GArray() { putDetails(); }             // Empty constructor
     explicit GArray(detail::GArrayU &&ref) // GArrayU-based constructor
         : m_ref(ref) { putDetails(); }     //   (used by GCall, not for users)
@@ -335,10 +344,6 @@ public:
     detail::GArrayU strip() const { return m_ref; }
 
 private:
-    // Host type (or Flat type) - the type this GArray is actually
-    // specified to.
-    using HT = typename detail::flatten_g<typename std::decay<T>::type>::type;
-
     static void VCTor(detail::VectorRef& vref) {
         vref.reset<HT>();
         vref.storeKind<HT>();
index e99ce6a..7d3dca3 100644 (file)
@@ -20,6 +20,11 @@ cv::detail::GArrayU::GArrayU(const GNode &n, std::size_t out)
 {
 }
 
+cv::detail::GArrayU::GArrayU(const detail::VectorRef& vref)
+    : m_priv(new GOrigin(GShape::GARRAY, cv::gimpl::ConstVal(vref)))
+{
+}
+
 cv::GOrigin& cv::detail::GArrayU::priv()
 {
     return *m_priv;
index d78e906..e7b4389 100644 (file)
@@ -21,7 +21,10 @@ cv::GOrigin::GOrigin(GShape s,
 }
 
 cv::GOrigin::GOrigin(GShape s, cv::gimpl::ConstVal v)
-    : shape(s), node(cv::GNode::Const()), value(v), port(INVALID_PORT), kind(cv::detail::OpaqueKind::CV_UNKNOWN)
+    : shape(s), node(cv::GNode::Const()), value(v), port(INVALID_PORT),
+      kind(util::holds_alternative<detail::VectorRef>(v)
+               ? util::get<detail::VectorRef>(v).getKind()
+               : cv::detail::OpaqueKind::CV_UNKNOWN)
 {
 }
 
index 1bac18a..ef5162a 100644 (file)
@@ -79,6 +79,7 @@ cv::GRunArg cv::value_of(const cv::GOrigin &origin)
     switch (origin.shape)
     {
     case GShape::GSCALAR: return GRunArg(util::get<cv::Scalar>(origin.value));
+    case GShape::GARRAY:  return GRunArg(util::get<cv::detail::VectorRef>(origin.value));
     default: util::throw_error(std::logic_error("Unsupported shape for constant"));
     }
 }
index acbb64b..dd0939c 100644 (file)
@@ -29,6 +29,7 @@ namespace gimpl
     using ConstVal = util::variant
     < util::monostate
     , cv::Scalar
+    , cv::detail::VectorRef
     >;
 
     struct RcDesc
index 50c8f0a..eb5ac27 100644 (file)
@@ -114,6 +114,12 @@ void cv::gimpl::GExecutor::initResource(const ade::NodeHandle &orig_nh)
         break;
 
     case GShape::GARRAY:
+        if (d.storage == Data::Storage::CONST_VAL)
+        {
+            auto rc = RcDesc{d.rc, d.shape, d.ctor};
+            magazine::bindInArg(m_res, rc, m_gm.metadata(orig_nh).get<ConstValue>().arg);
+        }
+        break;
     case GShape::GOPAQUE:
         // Constructed on Reset, do nothing here
         break;
index b6f4a6e..74a531c 100644 (file)
@@ -28,6 +28,10 @@ G_TYPED_KERNEL(CountCorners,   <GScalar(GPointArray)>,  "test.array.in")
 {
     static GScalarDesc outMeta(const GArrayDesc &) { return empty_scalar_desc(); }
 };
+G_TYPED_KERNEL(PointIncrement, <GPointArray(GMat, GPointArray)>, "test.point_increment")
+{
+    static GArrayDesc outMeta(const GMatDesc&, const GArrayDesc&) { return empty_array_desc(); }
+};
 } // namespace ThisTest
 
 namespace
@@ -57,6 +61,15 @@ GAPI_OCV_KERNEL(OCVCountCorners, ThisTest::CountCorners)
     }
 };
 
+GAPI_OCV_KERNEL(OCVPointIncrement, ThisTest::PointIncrement)
+{
+    static void run(const cv::Mat&, const std::vector<cv::Point>& in, std::vector<cv::Point>& out)
+    {
+        for (const auto& el : in)
+            out.emplace_back(el + Point(1,1));
+    }
+};
+
 cv::Mat cross(int w, int h)
 {
     cv::Mat mat = cv::Mat::eye(h, w, CV_8UC1)*255;
@@ -164,6 +177,45 @@ TEST(GArray, TestIntermediateOutput)
     EXPECT_EQ(10,  out_count[0]);
 }
 
+TEST(GArray, GArrayConstValInitialization)
+{
+    std::vector<cv::Point> initial_vec {Point(0,0), Point(1,1), Point(2,2)};
+    std::vector<cv::Point> ref_vec     {Point(1,1), Point(2,2), Point(3,3)};
+    std::vector<cv::Point> out_vec;
+    cv::Mat in_mat;
+
+    cv::GComputationT<ThisTest::GPointArray(cv::GMat)> c([&](cv::GMat in)
+    {
+        // Initialization
+        ThisTest::GPointArray test_garray(initial_vec);
+        return ThisTest::PointIncrement::on(in, test_garray);
+    });
+    auto cc = c.compile(cv::descr_of(in_mat),
+                        cv::compile_args(cv::gapi::kernels<OCVPointIncrement>()));
+    cc(in_mat, out_vec);
+
+    EXPECT_EQ(ref_vec, out_vec);
+}
+
+TEST(GArray, GArrayRValInitialization)
+{
+    std::vector<cv::Point> ref_vec {Point(1,1), Point(2,2), Point(3,3)};
+    std::vector<cv::Point> out_vec;
+    cv::Mat in_mat;
+
+    cv::GComputationT<ThisTest::GPointArray(cv::GMat)> c([&](cv::GMat in)
+    {
+        // Rvalue initialization
+        ThisTest::GPointArray test_garray({Point(0,0), Point(1,1), Point(2,2)});
+        return ThisTest::PointIncrement::on(in, test_garray);
+    });
+    auto cc = c.compile(cv::descr_of(in_mat),
+                        cv::compile_args(cv::gapi::kernels<OCVPointIncrement>()));
+    cc(in_mat, out_vec);
+
+    EXPECT_EQ(ref_vec, out_vec);
+}
+
 TEST(GArray_VectorRef, TestMov)
 {
     // Warning: this test is testing some not-very-public APIs