From 830d8d6b75be0cf55fedeef5fcc20d28ef0d9aa8 Mon Sep 17 00:00:00 2001 From: Maxim Pashchenkov Date: Fri, 18 Sep 2020 16:06:23 +0300 Subject: [PATCH] Merge pull request #18196 from mpashchenkov:mp/garray-initialization [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 | 13 ++++--- modules/gapi/src/api/garray.cpp | 5 +++ modules/gapi/src/api/gorigin.cpp | 5 ++- modules/gapi/src/api/gproto.cpp | 1 + modules/gapi/src/compiler/gobjref.hpp | 1 + modules/gapi/src/executor/gexecutor.cpp | 6 ++++ modules/gapi/test/gapi_array_tests.cpp | 52 ++++++++++++++++++++++++++++ 7 files changed, 78 insertions(+), 5 deletions(-) diff --git a/modules/gapi/include/opencv2/gapi/garray.hpp b/modules/gapi/include/opencv2/gapi/garray.hpp index 99f6661..d87ec8c 100644 --- a/modules/gapi/include/opencv2/gapi/garray.hpp +++ b/modules/gapi/include/opencv2/gapi/garray.hpp @@ -80,6 +80,7 @@ namespace detail protected: GArrayU(); // Default constructor + GArrayU(const detail::VectorRef& vref); // Constant value constructor template friend class cv::GArray; // (available to GArray only) void setConstructFcn(ConstructVec &&cv); // Store T-aware constructor @@ -328,6 +329,14 @@ namespace detail template class GArray { public: + // Host type (or Flat type) - the type this GArray is actually + // specified to. + using HT = typename detail::flatten_g::type>::type; + + explicit GArray(const std::vector& v) // Constant value constructor + : m_ref(detail::GArrayU(detail::VectorRef(v))) { putDetails(); } + explicit GArray(std::vector&& 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::type>::type; - static void VCTor(detail::VectorRef& vref) { vref.reset(); vref.storeKind(); diff --git a/modules/gapi/src/api/garray.cpp b/modules/gapi/src/api/garray.cpp index e99ce6a..7d3dca3 100644 --- a/modules/gapi/src/api/garray.cpp +++ b/modules/gapi/src/api/garray.cpp @@ -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; diff --git a/modules/gapi/src/api/gorigin.cpp b/modules/gapi/src/api/gorigin.cpp index d78e906..e7b4389 100644 --- a/modules/gapi/src/api/gorigin.cpp +++ b/modules/gapi/src/api/gorigin.cpp @@ -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(v) + ? util::get(v).getKind() + : cv::detail::OpaqueKind::CV_UNKNOWN) { } diff --git a/modules/gapi/src/api/gproto.cpp b/modules/gapi/src/api/gproto.cpp index 1bac18a..ef5162a 100644 --- a/modules/gapi/src/api/gproto.cpp +++ b/modules/gapi/src/api/gproto.cpp @@ -79,6 +79,7 @@ cv::GRunArg cv::value_of(const cv::GOrigin &origin) switch (origin.shape) { case GShape::GSCALAR: return GRunArg(util::get(origin.value)); + case GShape::GARRAY: return GRunArg(util::get(origin.value)); default: util::throw_error(std::logic_error("Unsupported shape for constant")); } } diff --git a/modules/gapi/src/compiler/gobjref.hpp b/modules/gapi/src/compiler/gobjref.hpp index acbb64b..dd0939c 100644 --- a/modules/gapi/src/compiler/gobjref.hpp +++ b/modules/gapi/src/compiler/gobjref.hpp @@ -29,6 +29,7 @@ namespace gimpl using ConstVal = util::variant < util::monostate , cv::Scalar + , cv::detail::VectorRef >; struct RcDesc diff --git a/modules/gapi/src/executor/gexecutor.cpp b/modules/gapi/src/executor/gexecutor.cpp index 50c8f0a..eb5ac27 100644 --- a/modules/gapi/src/executor/gexecutor.cpp +++ b/modules/gapi/src/executor/gexecutor.cpp @@ -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().arg); + } + break; case GShape::GOPAQUE: // Constructed on Reset, do nothing here break; diff --git a/modules/gapi/test/gapi_array_tests.cpp b/modules/gapi/test/gapi_array_tests.cpp index b6f4a6e..74a531c 100644 --- a/modules/gapi/test/gapi_array_tests.cpp +++ b/modules/gapi/test/gapi_array_tests.cpp @@ -28,6 +28,10 @@ G_TYPED_KERNEL(CountCorners, , "test.array.in") { static GScalarDesc outMeta(const GArrayDesc &) { return empty_scalar_desc(); } }; +G_TYPED_KERNEL(PointIncrement, , "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& in, std::vector& 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 initial_vec {Point(0,0), Point(1,1), Point(2,2)}; + std::vector ref_vec {Point(1,1), Point(2,2), Point(3,3)}; + std::vector out_vec; + cv::Mat in_mat; + + cv::GComputationT 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())); + cc(in_mat, out_vec); + + EXPECT_EQ(ref_vec, out_vec); +} + +TEST(GArray, GArrayRValInitialization) +{ + std::vector ref_vec {Point(1,1), Point(2,2), Point(3,3)}; + std::vector out_vec; + cv::Mat in_mat; + + cv::GComputationT 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())); + 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 -- 2.7.4