// This file is part of OpenCV project. // It is subject to the license terms in the LICENSE file found in the top-level directory // of this distribution and at http://opencv.org/license.html. // // Copyright (C) 2018 Intel Corporation #include "../test_precomp.hpp" #include "compiler/gmodel.hpp" #include "compiler/gcompiled_priv.hpp" #include "compiler/gmodel_priv.hpp" namespace opencv_test { //////////////////////////////////////////////////////////////////////////////// // Tests on a plain graph // // (in) -> Blur1 -> (tmp0) -> Blur2 -> (tmp1) -> Blur3 -> (tmp2) -> Blur4 -> (out) // namespace { struct PlainIslandsFixture { cv::GMat in; cv::GMat tmp[3]; cv::GMat out; PlainIslandsFixture() { tmp[0] = cv::gapi::boxFilter(in, -1, cv::Size(3,3)); tmp[1] = cv::gapi::boxFilter(tmp[0], -1, cv::Size(3,3)); tmp[2] = cv::gapi::boxFilter(tmp[1], -1, cv::Size(3,3)); out = cv::gapi::boxFilter(tmp[2], -1, cv::Size(3,3)); } }; struct Islands: public ::testing::Test, public PlainIslandsFixture {}; using GIntArray = GArray; G_TYPED_KERNEL(CreateMatWithDiag, , "test.array.create_mat_with_diag") { static GMatDesc outMeta(const GArrayDesc&) { return cv::GMatDesc{CV_32S, 1,{3, 3}}; } }; GAPI_OCV_KERNEL(CreateMatWithDiagImpl, CreateMatWithDiag) { static void run(const std::vector &in, cv::Mat& out) { auto size = static_cast(in.size()); out = Mat::zeros(size, size, CV_32SC1); for(int i = 0; i < out.rows; i++) { auto* row = out.ptr(i); row[i] = in[i]; } } }; G_TYPED_KERNEL(Mat2Array, , "test.array.mat2array") { static GArrayDesc outMeta(const GMatDesc&) { return empty_array_desc(); } }; GAPI_OCV_KERNEL(Mat2ArrayImpl, Mat2Array) { static void run(const cv::Mat& in, std::vector &out) { GAPI_Assert(in.depth() == CV_32S && in.isContinuous()); out.reserve(in.cols * in.rows); out.assign((int*)in.datastart, (int*)in.dataend); } }; } TEST_F(Islands, SmokeTest) { // (in) -> Blur1 -> (tmp0) -> Blur2 -> (tmp1) -> Blur3 -> (tmp2) -> Blur4 -> (out) // : "test" : // :<------------------------->: cv::gapi::island("test", cv::GIn(tmp[0]), cv::GOut(tmp[2])); auto cc = cv::GComputation(in, out).compile(cv::GMatDesc{CV_8U,1,{640,480}}); const auto &gm = cc.priv().model(); const auto tmp0_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[0]); const auto tmp1_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[1]); const auto tmp2_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[2]); // tmp1 and tmp3 is not a part of any island EXPECT_FALSE(gm.metadata(tmp0_nh).contains()); EXPECT_FALSE(gm.metadata(tmp2_nh).contains()); // tmp2 is part of "test" island EXPECT_TRUE(gm.metadata(tmp1_nh).contains()); EXPECT_EQ("test", gm.metadata(tmp1_nh).get().island); } TEST_F(Islands, TwoIslands) { // (in) -> Blur1 -> (tmp0) -> Blur2 -> (tmp1) -> Blur3 -> (tmp2) -> Blur4 -> (out) // : "test1" : : "test2" : // :<---------------------------->: :<---------------------------------> EXPECT_NO_THROW(cv::gapi::island("test1", cv::GIn(in), cv::GOut(tmp[1]))); EXPECT_NO_THROW(cv::gapi::island("test2", cv::GIn(tmp[1]), cv::GOut(out))); auto cc = cv::GComputation(in, out).compile(cv::GMatDesc{CV_8U,1,{640,480}}); const auto &gm = cc.priv().model(); const auto in_nh = cv::gimpl::GModel::dataNodeOf(gm, in); const auto tmp0_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[0]); const auto tmp1_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[1]); const auto tmp2_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[2]); const auto out_nh = cv::gimpl::GModel::dataNodeOf(gm, out); // Only tmp0 and tmp2 should be listed in islands. EXPECT_TRUE (gm.metadata(tmp0_nh).contains()); EXPECT_TRUE (gm.metadata(tmp2_nh).contains()); EXPECT_FALSE(gm.metadata(in_nh) .contains()); EXPECT_FALSE(gm.metadata(tmp1_nh).contains()); EXPECT_FALSE(gm.metadata(out_nh) .contains()); EXPECT_EQ("test1", gm.metadata(tmp0_nh).get().island); EXPECT_EQ("test2", gm.metadata(tmp2_nh).get().island); } // FIXME: Disabled since currently merge procedure merges two into one // successfully TEST_F(Islands, DISABLED_Two_Islands_With_Same_Name_Should_Fail) { // (in) -> Blur1 -> (tmp0) -> Blur2 -> (tmp1) -> Blur3 -> (tmp2) -> Blur4 -> (out) // : "test1" : : "test1" : // :<---------------------------->: :<---------------------------------> EXPECT_NO_THROW(cv::gapi::island("test1", cv::GIn(in), cv::GOut(tmp[1]))); EXPECT_NO_THROW(cv::gapi::island("test1", cv::GIn(tmp[1]), cv::GOut(out))); EXPECT_ANY_THROW(cv::GComputation(in, out).compile(cv::GMatDesc{CV_8U,1,{640,480}})); } // (in) -> Blur1 -> (tmp0) -> Blur2 -> (tmp1) -> Blur3 -> (tmp2) -> Blur4 -> (out) // : "test1": : : // :<----------------:----------->: : // : : // : "test2" : // :<------------------------->: TEST_F(Islands, OverlappingIslands1) { EXPECT_NO_THROW (cv::gapi::island("test1", cv::GIn(in), cv::GOut(tmp[1]))); EXPECT_ANY_THROW(cv::gapi::island("test2", cv::GIn(tmp[0]), cv::GOut(tmp[2]))); } TEST_F(Islands, OverlappingIslands2) { EXPECT_NO_THROW (cv::gapi::island("test2", cv::GIn(tmp[0]), cv::GOut(tmp[2]))); EXPECT_ANY_THROW(cv::gapi::island("test1", cv::GIn(in), cv::GOut(tmp[1]))); } //////////////////////////////////////////////////////////////////////////////// // Tests on a complex graph // // (in0) -> Not -> (tmp0) --> Add ---------> (tmp2) --> AddC -------> (out0) // ^ ^ // (in1) -> Blur -> (tmp1) ----'--> Sum ----> (scl0) ----' // : // `------------> Median -> (tmp3) --> Blur -------> (out1) // namespace { struct ComplexIslandsFixture { cv::GMat in[2]; cv::GMat tmp[4]; cv::GScalar scl; cv::GMat out[2]; ComplexIslandsFixture() { tmp[0] = cv::gapi::bitwise_not(in[0]); tmp[1] = cv::gapi::boxFilter(in[1], -1, cv::Size(3,3)); tmp[2] = tmp[0] + tmp[1]; // FIXME: handle tmp[2] = tmp[0]+tmp[2] typo scl = cv::gapi::sum(tmp[1]); tmp[3] = cv::gapi::medianBlur(tmp[1], 3); out[0] = tmp[2] + scl; out[1] = cv::gapi::boxFilter(tmp[3], -1, cv::Size(3,3)); } }; struct ComplexIslands: public ::testing::Test, public ComplexIslandsFixture {}; } // namespace TEST_F(ComplexIslands, SmokeTest) { // isl0 #internal1 // ........................... ........ // (in0) -> Not -> (tmp0) --> Add ---------> (tmp2) --> AddC -------> (out0) // :............ ........^...: :.^....: // ... : : // (in1) -> Blur -> (tmp1) ----'--> Sum ----> (scl0) ----' // : isl1 // : .............................. // `------------> Median -> (tmp3) --> Blur -------> (out1) // :............................: cv::gapi::island("isl0", cv::GIn(in[0], tmp[1]), cv::GOut(tmp[2])); cv::gapi::island("isl1", cv::GIn(tmp[1]), cv::GOut(out[1])); auto cc = cv::GComputation(cv::GIn(in[0], in[1]), cv::GOut(out[0], out[1])) .compile(cv::GMatDesc{CV_8U,1,{640,480}}, cv::GMatDesc{CV_8U,1,{640,480}}); const auto &gm = cc.priv().model(); const auto in0_nh = cv::gimpl::GModel::dataNodeOf(gm, in[0]); const auto in1_nh = cv::gimpl::GModel::dataNodeOf(gm, in[1]); const auto tmp0_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[0]); const auto tmp1_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[1]); const auto tmp2_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[2]); const auto tmp3_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[3]); const auto scl_nh = cv::gimpl::GModel::dataNodeOf(gm, scl); const auto out0_nh = cv::gimpl::GModel::dataNodeOf(gm, out[0]); const auto out1_nh = cv::gimpl::GModel::dataNodeOf(gm, out[1]); // tmp0, tmp3 are in islands, others are not EXPECT_TRUE(gm.metadata(tmp0_nh) .contains()); // isl0 EXPECT_TRUE(gm.metadata(tmp3_nh) .contains()); // isl1 EXPECT_FALSE(gm.metadata(in0_nh) .contains()); // (input is never fused) EXPECT_FALSE(gm.metadata(in1_nh) .contains()); // (input is never fused) EXPECT_TRUE (gm.metadata(tmp1_nh).contains()); // EXPECT_FALSE(gm.metadata(tmp2_nh).contains()); // #not fused as cycle-causing# EXPECT_FALSE(gm.metadata(scl_nh) .contains()); // #not fused as cycle-causing# EXPECT_FALSE(gm.metadata(out0_nh).contains()); // (output is never fused) EXPECT_FALSE(gm.metadata(out1_nh).contains()); // (output is never fused) EXPECT_EQ("isl0", gm.metadata(tmp0_nh).get().island); EXPECT_EQ("isl1", gm.metadata(tmp3_nh).get().island); EXPECT_NE("isl0", gm.metadata(tmp1_nh).get().island); EXPECT_NE("isl1", gm.metadata(tmp1_nh).get().island); // FIXME: Add a test with same graph for Fusion and check GIslandModel } TEST_F(ComplexIslands, DistinictIslandsWithSameName) { // isl0 // ........................... // (in0) -> Not -> (tmp0) --> Add ---------> (tmp2) --> AddC -------> (out0) // :............ ........^...: ^ // ... : : // (in1) -> Blur -> (tmp1) ----'--> Sum ----> (scl0) ----' // : isl0 // : .............................. // `------------> Median -> (tmp3) --> Blur -------> (out1) // :............................: cv::gapi::island("isl0", cv::GIn(in[0], tmp[1]), cv::GOut(tmp[2])); cv::gapi::island("isl0", cv::GIn(tmp[1]), cv::GOut(out[1])); auto cc = cv::GComputation(cv::GIn(in[0], in[1]), cv::GOut(out[0], out[1])); EXPECT_ANY_THROW(cc.compile(cv::GMatDesc{CV_8U,1,{640,480}}, cv::GMatDesc{CV_8U,1,{640,480}})); } TEST_F(ComplexIslands, FullGraph) { cv::gapi::island("isl0", cv::GIn(in[0], in[1]), cv::GOut(out[0], out[1])); auto cc = cv::GComputation(cv::GIn(in[0], in[1]), cv::GOut(out[0], out[1])) .compile(cv::GMatDesc{CV_8U,1,{640,480}}, cv::GMatDesc{CV_8U,1,{640,480}}); const auto &gm = cc.priv().model(); std::vector handles_inside = { cv::gimpl::GModel::dataNodeOf(gm, tmp[0]), cv::gimpl::GModel::dataNodeOf(gm, tmp[1]), cv::gimpl::GModel::dataNodeOf(gm, tmp[2]), cv::gimpl::GModel::dataNodeOf(gm, tmp[3]), cv::gimpl::GModel::dataNodeOf(gm, scl), }; std::vector handles_outside = { cv::gimpl::GModel::dataNodeOf(gm, in[0]), cv::gimpl::GModel::dataNodeOf(gm, in[1]), cv::gimpl::GModel::dataNodeOf(gm, out[0]), cv::gimpl::GModel::dataNodeOf(gm, out[1]), }; for (auto nh_inside : handles_inside) { EXPECT_EQ("isl0", gm.metadata(nh_inside).get().island); } for (auto nh_outside : handles_outside) { EXPECT_FALSE(gm.metadata(nh_outside).contains()); } } TEST_F(ComplexIslands, ViaScalar) { // // .........................................#internal0. // (in0) -> Not -> (tmp0) --> Add ---------> (tmp2) --> AddC -------> (out0) // :....................^.........................^...: // : : // .....................:.........(isl0). : // (in1) -> Blur -> (tmp1) ----'--> Sum ----> (scl0) ----' // :..........:.........................: // : // : ..................#internal1. // `------------> Median -> (tmp3) --> Blur -------> (out1) // :...........................: cv::gapi::island("isl0", cv::GIn(in[1]), cv::GOut(scl)); auto cc = cv::GComputation(cv::GIn(in[0], in[1]), cv::GOut(out[0], out[1])) .compile(cv::GMatDesc{CV_8U,1,{640,480}}, cv::GMatDesc{CV_8U,1,{640,480}}); const auto &gm = cc.priv().model(); const auto tmp0_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[0]); const auto tmp1_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[1]); const auto tmp2_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[2]); const auto tmp3_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[3]); EXPECT_NE("isl0", gm.metadata(tmp0_nh).get().island); // EXPECT_EQ("isl0", gm.metadata(tmp1_nh).get().island); // isl0 EXPECT_NE("isl0", gm.metadata(tmp2_nh).get().island); // EXPECT_NE("isl0", gm.metadata(tmp3_nh).get().island); // std::vector handles_outside = { cv::gimpl::GModel::dataNodeOf(gm, in[0]), cv::gimpl::GModel::dataNodeOf(gm, in[1]), cv::gimpl::GModel::dataNodeOf(gm, scl), cv::gimpl::GModel::dataNodeOf(gm, out[0]), cv::gimpl::GModel::dataNodeOf(gm, out[1]), }; for (auto nh_outside : handles_outside) { EXPECT_FALSE(gm.metadata(nh_outside).contains()); } } TEST_F(ComplexIslands, BorderDataIsland) { // .................................(isl0).. // : : // (in0) -> Not -> (tmp0) --> Add ---------> (tmp2) --> AddC -------> (out0) // : ^ : ^ // : : : : // (in1) -> Blur -> (tmp1) ----'--> Sum ----> (scl0) ----' // :...........:...........................: // : : : // : : :.........................................(isl1).. // : `------------> Median -> (tmp3) --> Blur -------> (out1) // : : // :......................................................: cv::gapi::island("isl0", cv::GIn(in[0], in[1]), cv::GOut(tmp[2], scl)); cv::gapi::island("isl1", cv::GIn(tmp[1]), cv::GOut(out[1])); auto cc = cv::GComputation(cv::GIn(in[0], in[1]), cv::GOut(out[0], out[1])) .compile(cv::GMatDesc{CV_8U,1,{640,480}}, cv::GMatDesc{CV_8U,1,{640,480}}); const auto &gm = cc.priv().model(); const auto in0_nh = cv::gimpl::GModel::dataNodeOf(gm, in[0]); const auto in1_nh = cv::gimpl::GModel::dataNodeOf(gm, in[1]); const auto tmp0_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[0]); const auto tmp1_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[1]); const auto tmp2_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[2]); const auto tmp3_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[3]); const auto scl_nh = cv::gimpl::GModel::dataNodeOf(gm, scl); const auto out0_nh = cv::gimpl::GModel::dataNodeOf(gm, out[0]); const auto out1_nh = cv::gimpl::GModel::dataNodeOf(gm, out[1]); // Check handles inside isl0 EXPECT_EQ("isl0", gm.metadata(tmp0_nh).get().island); EXPECT_EQ("isl0", gm.metadata(tmp1_nh).get().island); // ^^^ Important - tmp1 is assigned to isl0, not isl1 // Check handles inside isl1 EXPECT_EQ("isl1", gm.metadata(tmp3_nh).get().island); // Check outside handles EXPECT_FALSE(gm.metadata(in0_nh) .contains()); EXPECT_FALSE(gm.metadata(in1_nh) .contains()); EXPECT_FALSE(gm.metadata(tmp2_nh).contains()); EXPECT_FALSE(gm.metadata(scl_nh) .contains()); EXPECT_FALSE(gm.metadata(out0_nh).contains()); EXPECT_FALSE(gm.metadata(out1_nh).contains()); } TEST_F(ComplexIslands, IncompleteSpec) { // isl0 // ........................... // (in0) -> Not -> (tmp0) --> Add ---------> (tmp2) --> AddC -------> (out0) // :...........xxx.......^...: ^ // : : // (in1) -> Blur -> (tmp1) ----'--> Sum ----> (scl0) ----' // : // : // `------------> Median -> (tmp3) --> Blur -------> (out1) // // tmp1 is missing in the below spec EXPECT_ANY_THROW(cv::gapi::island("isl0", cv::GIn(in[0]), cv::GOut(tmp[2]))); // empty range EXPECT_ANY_THROW(cv::gapi::island("isl1", cv::GIn(tmp[2]), cv::GOut(tmp[2]))); } TEST_F(ComplexIslands, InputOperationFromDifferentIslands) { // isl1 // ........................... ........ // (in0)--> Not -> (tmp0) --> Add :--------> (tmp2)-->: AddC : -------> (out0) // :......................^..: : ^ : // isl0 : : : : // .......................:....................... : : // (in1) :-> Blur -> (tmp1) ----'--> Sum ----> (scl0) ----- : // :....................................................: // isl0 : // `------------> Median -> (tmp3) --> Blur -------> (out1) // cv::gapi::island("isl0", cv::GIn(in[1], tmp[2]), cv::GOut(out[0])); cv::gapi::island("isl1", cv::GIn(in[0], tmp[1]), cv::GOut(tmp[2])); auto cc = cv::GComputation(cv::GIn(in[0], in[1]), cv::GOut(out[0], out[1])) .compile(cv::GMatDesc{CV_8U,1,{640,480}}, cv::GMatDesc{CV_8U,1,{640,480}}); const auto &gm = cc.priv().model(); const auto tmp0_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[0]); const auto tmp1_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[1]); const auto tmp2_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[2]); EXPECT_EQ("isl1", gm.metadata(tmp0_nh).get().island); EXPECT_EQ("isl0", gm.metadata(tmp1_nh).get().island); EXPECT_FALSE(gm.metadata(tmp2_nh).contains()); } TEST_F(ComplexIslands, NoWayBetweenNodes) { // (in0) -> Not -> (tmp0) --> Add ---------> (tmp2) --> AddC -------> (out0) // ^ ^ // (in1) -> Blur -> (tmp1) ----'--> Sum ----> (scl0) ----' // : // `------------> Median -> (tmp3) --> Blur -------> (out1) EXPECT_ANY_THROW(cv::gapi::island("isl0", cv::GIn(in[1]), cv::GOut(tmp[0]))); } TEST_F(ComplexIslands, IslandsContainUnusedPart) { // Unused part of the graph // x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x // x x // x(in0) -> Not -> (tmp0) --> Add ---------> (tmp2)---> AddC ---------> (out0) x // x ^ ^ x // x x x x x x x x x x x x x x x | x x | x // | x | x // ...... | x | x // (in1) -> :Blur:----------> (tmp1) x-----> Sum ------> (scl0) x // ...... : x x x x x x x x x x x x x x x x x x x x x x x x // isl0 // : // `------------> Median -> (tmp3) --> Blur -------> (out1) cv::gapi::island("isl0", cv::GIn(in[1]), cv::GOut(scl)); auto cc = cv::GComputation(cv::GIn(in[1]), cv::GOut(out[1])) .compile(cv::GMatDesc{CV_8U,1,{640,480}}); const auto &gm = cc.priv().model(); const auto tmp1_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[1]); //The output 0 is not specified in the graph //means that there will not be a node scl, so that tmp1 will not assign to the island // FIXME Check that blur assigned to island using the function producerOf // After merge islands fusion EXPECT_FALSE(gm.metadata(tmp1_nh) .contains()); } TEST_F(ComplexIslands, FullGraphInTwoIslands) { // isl0 // .................................................. // (in0) -> :Not -> (tmp0) --> Add ---------> (tmp2) --> AddC: -------> (out0) // ...................^.... ^ : // ............... | : : : // (in1) -> :Blur-> (tmp1):----'-->:Sum ----> (scl0) ----' : // ........ | : ........................... // isl1 : | :............................................ // : `------------> Median -> (tmp3) --> Blur ------->:(out1) // .................................................... cv::gapi::island("isl0", cv::GIn(in[0], tmp[1]), cv::GOut(out[0])); cv::gapi::island("isl1", cv::GIn(in[1]), cv::GOut(out[1])); auto cc = cv::GComputation(cv::GIn(in[0], in[1]), cv::GOut(out[0], out[1])) .compile(cv::GMatDesc{CV_8U,1,{640,480}}, cv::GMatDesc{CV_8U,1,{640,480}}); const auto &gm = cc.priv().model(); const auto in0_nh = cv::gimpl::GModel::dataNodeOf(gm, in[0]); const auto in1_nh = cv::gimpl::GModel::dataNodeOf(gm, in[1]); const auto tmp0_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[0]); const auto tmp1_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[1]); const auto tmp2_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[2]); const auto tmp3_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[3]); const auto scl_nh = cv::gimpl::GModel::dataNodeOf(gm, scl); const auto out0_nh = cv::gimpl::GModel::dataNodeOf(gm, out[0]); const auto out1_nh = cv::gimpl::GModel::dataNodeOf(gm, out[1]); // Check handles inside isl0 EXPECT_EQ("isl0", gm.metadata(tmp0_nh).get().island); EXPECT_EQ("isl0", gm.metadata(tmp2_nh).get().island); EXPECT_EQ("isl0", gm.metadata(scl_nh).get().island); // Check handles inside isl1 EXPECT_EQ("isl1", gm.metadata(tmp1_nh).get().island); EXPECT_EQ("isl1", gm.metadata(tmp3_nh).get().island); // Check outside handles EXPECT_FALSE(gm.metadata(in0_nh) .contains()); EXPECT_FALSE(gm.metadata(in1_nh) .contains()); EXPECT_FALSE(gm.metadata(out0_nh).contains()); EXPECT_FALSE(gm.metadata(out1_nh).contains()); } TEST_F(ComplexIslands, OnlyOperationsAssignedToIslands) { cv::gapi::island("isl0", cv::GIn(in[1]), cv::GOut(tmp[1])); cv::gapi::island("isl1", cv::GIn(tmp[1]), cv::GOut(scl)); cv::gapi::island("isl2", cv::GIn(scl, tmp[2]), cv::GOut(out[0])); cv::gapi::island("isl3", cv::GIn(in[0]), cv::GOut(tmp[0])); cv::gapi::island("isl4", cv::GIn(tmp[0], tmp[1]), cv::GOut(tmp[2])); cv::gapi::island("isl5", cv::GIn(tmp[1]), cv::GOut(tmp[3])); cv::gapi::island("isl6", cv::GIn(tmp[3]), cv::GOut(out[1])); auto cc = cv::GComputation(cv::GIn(in[0], in[1]), cv::GOut(out[0], out[1])) .compile(cv::GMatDesc{CV_8U,1,{640,480}}, cv::GMatDesc{CV_8U,1,{640,480}}); const auto &gm = cc.priv().model(); //FIXME: Check that operation handles are really assigned to isl0..isl6 const auto in0_nh = cv::gimpl::GModel::dataNodeOf(gm, in[0]); const auto in1_nh = cv::gimpl::GModel::dataNodeOf(gm, in[1]); const auto tmp0_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[0]); const auto tmp1_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[1]); const auto tmp2_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[2]); const auto tmp3_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[3]); const auto scl_nh = cv::gimpl::GModel::dataNodeOf(gm, scl); const auto out0_nh = cv::gimpl::GModel::dataNodeOf(gm, out[0]); const auto out1_nh = cv::gimpl::GModel::dataNodeOf(gm, out[1]); EXPECT_FALSE(gm.metadata(in0_nh) .contains()); EXPECT_FALSE(gm.metadata(in1_nh) .contains()); EXPECT_FALSE(gm.metadata(tmp0_nh) .contains()); EXPECT_FALSE(gm.metadata(tmp1_nh) .contains()); EXPECT_FALSE(gm.metadata(tmp2_nh) .contains()); EXPECT_FALSE(gm.metadata(tmp3_nh) .contains()); EXPECT_FALSE(gm.metadata(scl_nh) .contains()); EXPECT_FALSE(gm.metadata(out0_nh).contains()); EXPECT_FALSE(gm.metadata(out1_nh).contains()); } namespace { struct IslandStructureWithGArray { GIntArray in, out; GMat tmp; IslandStructureWithGArray() { tmp = CreateMatWithDiag::on(in); out = Mat2Array::on(tmp); } }; struct IslandsWithGArray: public ::testing::Test, public IslandStructureWithGArray {}; } // namespace TEST_F(IslandsWithGArray, IslandWithGArrayAsInput) { cv::gapi::island("isl0", cv::GIn(in), cv::GOut(tmp)); const auto pkg = cv::gapi::kernels(); auto cc = cv::GComputation(cv::GIn(in), GOut(out)).compile(cv::empty_array_desc(), cv::compile_args(pkg)); const auto &gm = cc.priv().model(); const auto in_nh = cv::gimpl::GModel::dataNodeOf(gm, in.strip()); const auto out_nh = cv::gimpl::GModel::dataNodeOf(gm, out.strip()); const auto tmp_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp); GAPI_Assert(tmp_nh->inNodes().size() == 1); const auto create_diag_mat_nh = tmp_nh->inNodes().front(); EXPECT_EQ("isl0", gm.metadata(create_diag_mat_nh).get().island); EXPECT_FALSE(gm.metadata(in_nh) .contains()); EXPECT_FALSE(gm.metadata(out_nh) .contains()); EXPECT_FALSE(gm.metadata(tmp_nh) .contains()); } TEST_F(IslandsWithGArray, IslandWithGArrayAsOutput) { cv::gapi::island("isl0", cv::GIn(tmp), cv::GOut(out)); const auto pkg = cv::gapi::kernels(); auto cc = cv::GComputation(cv::GIn(in), GOut(out)).compile(cv::empty_array_desc(), cv::compile_args(pkg)); const auto &gm = cc.priv().model(); const auto in_nh = cv::gimpl::GModel::dataNodeOf(gm, in.strip()); const auto out_nh = cv::gimpl::GModel::dataNodeOf(gm, out.strip()); const auto tmp_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp); GAPI_Assert(tmp_nh->inNodes().size() == 1); const auto mat2array_nh = out_nh->inNodes().front(); EXPECT_EQ("isl0", gm.metadata(mat2array_nh).get().island); EXPECT_FALSE(gm.metadata(in_nh) .contains()); EXPECT_FALSE(gm.metadata(out_nh) .contains()); EXPECT_FALSE(gm.metadata(tmp_nh) .contains()); } //////////////////////////////////////////////////////////////////////////////// // Wrong input tests on island name // namespace { struct CheckName : public TestWithParam >, public PlainIslandsFixture { void assignIsland(const std::string &s) { cv::gapi::island(s, cv::GIn(tmp[0]), cv::GOut(tmp[2])); }; }; TEST_P(CheckName, Test) { bool correct = false; const char *name = ""; std::tie(correct, name) = GetParam(); if (correct) EXPECT_NO_THROW(assignIsland(name)); else EXPECT_ANY_THROW(assignIsland(name)); } } // namespace INSTANTIATE_TEST_CASE_P(IslandName, CheckName, Values(std::make_tuple(true, "name"), std::make_tuple(true, " name "), std::make_tuple(true, " n a m e "), std::make_tuple(true, " 123 $$ %%"), std::make_tuple(true, ".: -"), std::make_tuple(false, ""), std::make_tuple(false, " "), std::make_tuple(false, " \t "), std::make_tuple(false, " \t \t "))); // FIXME: add test on unrollExpr() use for islands } // opencv_test