gapi_int_island_tests.cpp 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654
  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. #include "../test_precomp.hpp"
  7. #include "compiler/gmodel.hpp"
  8. #include "compiler/gcompiled_priv.hpp"
  9. #include "compiler/gmodel_priv.hpp"
  10. namespace opencv_test
  11. {
  12. ////////////////////////////////////////////////////////////////////////////////
  13. // Tests on a plain graph
  14. //
  15. // (in) -> Blur1 -> (tmp0) -> Blur2 -> (tmp1) -> Blur3 -> (tmp2) -> Blur4 -> (out)
  16. //
  17. namespace
  18. {
  19. struct PlainIslandsFixture
  20. {
  21. cv::GMat in;
  22. cv::GMat tmp[3];
  23. cv::GMat out;
  24. PlainIslandsFixture()
  25. {
  26. tmp[0] = cv::gapi::boxFilter(in, -1, cv::Size(3,3));
  27. tmp[1] = cv::gapi::boxFilter(tmp[0], -1, cv::Size(3,3));
  28. tmp[2] = cv::gapi::boxFilter(tmp[1], -1, cv::Size(3,3));
  29. out = cv::gapi::boxFilter(tmp[2], -1, cv::Size(3,3));
  30. }
  31. };
  32. struct Islands: public ::testing::Test, public PlainIslandsFixture {};
  33. using GIntArray = GArray<int>;
  34. G_TYPED_KERNEL(CreateMatWithDiag, <GMat(GIntArray)>, "test.array.create_mat_with_diag")
  35. {
  36. static GMatDesc outMeta(const GArrayDesc&) { return cv::GMatDesc{CV_32S, 1,{3, 3}}; }
  37. };
  38. GAPI_OCV_KERNEL(CreateMatWithDiagImpl, CreateMatWithDiag)
  39. {
  40. static void run(const std::vector<int> &in, cv::Mat& out)
  41. {
  42. auto size = static_cast<int>(in.size());
  43. out = Mat::zeros(size, size, CV_32SC1);
  44. for(int i = 0; i < out.rows; i++)
  45. {
  46. auto* row = out.ptr<int>(i);
  47. row[i] = in[i];
  48. }
  49. }
  50. };
  51. G_TYPED_KERNEL(Mat2Array, <GIntArray(GMat)>, "test.array.mat2array")
  52. {
  53. static GArrayDesc outMeta(const GMatDesc&) { return empty_array_desc(); }
  54. };
  55. GAPI_OCV_KERNEL(Mat2ArrayImpl, Mat2Array)
  56. {
  57. static void run(const cv::Mat& in, std::vector<int> &out)
  58. {
  59. GAPI_Assert(in.depth() == CV_32S && in.isContinuous());
  60. out.reserve(in.cols * in.rows);
  61. out.assign((int*)in.datastart, (int*)in.dataend);
  62. }
  63. };
  64. }
  65. TEST_F(Islands, SmokeTest)
  66. {
  67. // (in) -> Blur1 -> (tmp0) -> Blur2 -> (tmp1) -> Blur3 -> (tmp2) -> Blur4 -> (out)
  68. // : "test" :
  69. // :<------------------------->:
  70. cv::gapi::island("test", cv::GIn(tmp[0]), cv::GOut(tmp[2]));
  71. auto cc = cv::GComputation(in, out).compile(cv::GMatDesc{CV_8U,1,{640,480}});
  72. const auto &gm = cc.priv().model();
  73. const auto tmp0_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[0]);
  74. const auto tmp1_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[1]);
  75. const auto tmp2_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[2]);
  76. // tmp1 and tmp3 is not a part of any island
  77. EXPECT_FALSE(gm.metadata(tmp0_nh).contains<cv::gimpl::Island>());
  78. EXPECT_FALSE(gm.metadata(tmp2_nh).contains<cv::gimpl::Island>());
  79. // tmp2 is part of "test" island
  80. EXPECT_TRUE(gm.metadata(tmp1_nh).contains<cv::gimpl::Island>());
  81. EXPECT_EQ("test", gm.metadata(tmp1_nh).get<cv::gimpl::Island>().island);
  82. }
  83. TEST_F(Islands, TwoIslands)
  84. {
  85. // (in) -> Blur1 -> (tmp0) -> Blur2 -> (tmp1) -> Blur3 -> (tmp2) -> Blur4 -> (out)
  86. // : "test1" : : "test2" :
  87. // :<---------------------------->: :<--------------------------------->
  88. EXPECT_NO_THROW(cv::gapi::island("test1", cv::GIn(in), cv::GOut(tmp[1])));
  89. EXPECT_NO_THROW(cv::gapi::island("test2", cv::GIn(tmp[1]), cv::GOut(out)));
  90. auto cc = cv::GComputation(in, out).compile(cv::GMatDesc{CV_8U,1,{640,480}});
  91. const auto &gm = cc.priv().model();
  92. const auto in_nh = cv::gimpl::GModel::dataNodeOf(gm, in);
  93. const auto tmp0_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[0]);
  94. const auto tmp1_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[1]);
  95. const auto tmp2_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[2]);
  96. const auto out_nh = cv::gimpl::GModel::dataNodeOf(gm, out);
  97. // Only tmp0 and tmp2 should be listed in islands.
  98. EXPECT_TRUE (gm.metadata(tmp0_nh).contains<cv::gimpl::Island>());
  99. EXPECT_TRUE (gm.metadata(tmp2_nh).contains<cv::gimpl::Island>());
  100. EXPECT_FALSE(gm.metadata(in_nh) .contains<cv::gimpl::Island>());
  101. EXPECT_FALSE(gm.metadata(tmp1_nh).contains<cv::gimpl::Island>());
  102. EXPECT_FALSE(gm.metadata(out_nh) .contains<cv::gimpl::Island>());
  103. EXPECT_EQ("test1", gm.metadata(tmp0_nh).get<cv::gimpl::Island>().island);
  104. EXPECT_EQ("test2", gm.metadata(tmp2_nh).get<cv::gimpl::Island>().island);
  105. }
  106. // FIXME: Disabled since currently merge procedure merges two into one
  107. // successfully
  108. TEST_F(Islands, DISABLED_Two_Islands_With_Same_Name_Should_Fail)
  109. {
  110. // (in) -> Blur1 -> (tmp0) -> Blur2 -> (tmp1) -> Blur3 -> (tmp2) -> Blur4 -> (out)
  111. // : "test1" : : "test1" :
  112. // :<---------------------------->: :<--------------------------------->
  113. EXPECT_NO_THROW(cv::gapi::island("test1", cv::GIn(in), cv::GOut(tmp[1])));
  114. EXPECT_NO_THROW(cv::gapi::island("test1", cv::GIn(tmp[1]), cv::GOut(out)));
  115. EXPECT_ANY_THROW(cv::GComputation(in, out).compile(cv::GMatDesc{CV_8U,1,{640,480}}));
  116. }
  117. // (in) -> Blur1 -> (tmp0) -> Blur2 -> (tmp1) -> Blur3 -> (tmp2) -> Blur4 -> (out)
  118. // : "test1": : :
  119. // :<----------------:----------->: :
  120. // : :
  121. // : "test2" :
  122. // :<------------------------->:
  123. TEST_F(Islands, OverlappingIslands1)
  124. {
  125. EXPECT_NO_THROW (cv::gapi::island("test1", cv::GIn(in), cv::GOut(tmp[1])));
  126. EXPECT_ANY_THROW(cv::gapi::island("test2", cv::GIn(tmp[0]), cv::GOut(tmp[2])));
  127. }
  128. TEST_F(Islands, OverlappingIslands2)
  129. {
  130. EXPECT_NO_THROW (cv::gapi::island("test2", cv::GIn(tmp[0]), cv::GOut(tmp[2])));
  131. EXPECT_ANY_THROW(cv::gapi::island("test1", cv::GIn(in), cv::GOut(tmp[1])));
  132. }
  133. ////////////////////////////////////////////////////////////////////////////////
  134. // Tests on a complex graph
  135. //
  136. // (in0) -> Not -> (tmp0) --> Add ---------> (tmp2) --> AddC -------> (out0)
  137. // ^ ^
  138. // (in1) -> Blur -> (tmp1) ----'--> Sum ----> (scl0) ----'
  139. // :
  140. // `------------> Median -> (tmp3) --> Blur -------> (out1)
  141. //
  142. namespace
  143. {
  144. struct ComplexIslandsFixture
  145. {
  146. cv::GMat in[2];
  147. cv::GMat tmp[4];
  148. cv::GScalar scl;
  149. cv::GMat out[2];
  150. ComplexIslandsFixture()
  151. {
  152. tmp[0] = cv::gapi::bitwise_not(in[0]);
  153. tmp[1] = cv::gapi::boxFilter(in[1], -1, cv::Size(3,3));
  154. tmp[2] = tmp[0] + tmp[1]; // FIXME: handle tmp[2] = tmp[0]+tmp[2] typo
  155. scl = cv::gapi::sum(tmp[1]);
  156. tmp[3] = cv::gapi::medianBlur(tmp[1], 3);
  157. out[0] = tmp[2] + scl;
  158. out[1] = cv::gapi::boxFilter(tmp[3], -1, cv::Size(3,3));
  159. }
  160. };
  161. struct ComplexIslands: public ::testing::Test, public ComplexIslandsFixture {};
  162. } // namespace
  163. TEST_F(ComplexIslands, SmokeTest)
  164. {
  165. // isl0 #internal1
  166. // ........................... ........
  167. // (in0) -> Not -> (tmp0) --> Add ---------> (tmp2) --> AddC -------> (out0)
  168. // :............ ........^...: :.^....:
  169. // ... : :
  170. // (in1) -> Blur -> (tmp1) ----'--> Sum ----> (scl0) ----'
  171. // : isl1
  172. // : ..............................
  173. // `------------> Median -> (tmp3) --> Blur -------> (out1)
  174. // :............................:
  175. cv::gapi::island("isl0", cv::GIn(in[0], tmp[1]), cv::GOut(tmp[2]));
  176. cv::gapi::island("isl1", cv::GIn(tmp[1]), cv::GOut(out[1]));
  177. auto cc = cv::GComputation(cv::GIn(in[0], in[1]), cv::GOut(out[0], out[1]))
  178. .compile(cv::GMatDesc{CV_8U,1,{640,480}},
  179. cv::GMatDesc{CV_8U,1,{640,480}});
  180. const auto &gm = cc.priv().model();
  181. const auto in0_nh = cv::gimpl::GModel::dataNodeOf(gm, in[0]);
  182. const auto in1_nh = cv::gimpl::GModel::dataNodeOf(gm, in[1]);
  183. const auto tmp0_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[0]);
  184. const auto tmp1_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[1]);
  185. const auto tmp2_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[2]);
  186. const auto tmp3_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[3]);
  187. const auto scl_nh = cv::gimpl::GModel::dataNodeOf(gm, scl);
  188. const auto out0_nh = cv::gimpl::GModel::dataNodeOf(gm, out[0]);
  189. const auto out1_nh = cv::gimpl::GModel::dataNodeOf(gm, out[1]);
  190. // tmp0, tmp3 are in islands, others are not
  191. EXPECT_TRUE(gm.metadata(tmp0_nh) .contains<cv::gimpl::Island>()); // isl0
  192. EXPECT_TRUE(gm.metadata(tmp3_nh) .contains<cv::gimpl::Island>()); // isl1
  193. EXPECT_FALSE(gm.metadata(in0_nh) .contains<cv::gimpl::Island>()); // (input is never fused)
  194. EXPECT_FALSE(gm.metadata(in1_nh) .contains<cv::gimpl::Island>()); // (input is never fused)
  195. EXPECT_TRUE (gm.metadata(tmp1_nh).contains<cv::gimpl::Island>()); // <internal island>
  196. EXPECT_FALSE(gm.metadata(tmp2_nh).contains<cv::gimpl::Island>()); // #not fused as cycle-causing#
  197. EXPECT_FALSE(gm.metadata(scl_nh) .contains<cv::gimpl::Island>()); // #not fused as cycle-causing#
  198. EXPECT_FALSE(gm.metadata(out0_nh).contains<cv::gimpl::Island>()); // (output is never fused)
  199. EXPECT_FALSE(gm.metadata(out1_nh).contains<cv::gimpl::Island>()); // (output is never fused)
  200. EXPECT_EQ("isl0", gm.metadata(tmp0_nh).get<cv::gimpl::Island>().island);
  201. EXPECT_EQ("isl1", gm.metadata(tmp3_nh).get<cv::gimpl::Island>().island);
  202. EXPECT_NE("isl0", gm.metadata(tmp1_nh).get<cv::gimpl::Island>().island);
  203. EXPECT_NE("isl1", gm.metadata(tmp1_nh).get<cv::gimpl::Island>().island);
  204. // FIXME: Add a test with same graph for Fusion and check GIslandModel
  205. }
  206. TEST_F(ComplexIslands, DistinictIslandsWithSameName)
  207. {
  208. // isl0
  209. // ...........................
  210. // (in0) -> Not -> (tmp0) --> Add ---------> (tmp2) --> AddC -------> (out0)
  211. // :............ ........^...: ^
  212. // ... : :
  213. // (in1) -> Blur -> (tmp1) ----'--> Sum ----> (scl0) ----'
  214. // : isl0
  215. // : ..............................
  216. // `------------> Median -> (tmp3) --> Blur -------> (out1)
  217. // :............................:
  218. cv::gapi::island("isl0", cv::GIn(in[0], tmp[1]), cv::GOut(tmp[2]));
  219. cv::gapi::island("isl0", cv::GIn(tmp[1]), cv::GOut(out[1]));
  220. auto cc = cv::GComputation(cv::GIn(in[0], in[1]), cv::GOut(out[0], out[1]));
  221. EXPECT_ANY_THROW(cc.compile(cv::GMatDesc{CV_8U,1,{640,480}},
  222. cv::GMatDesc{CV_8U,1,{640,480}}));
  223. }
  224. TEST_F(ComplexIslands, FullGraph)
  225. {
  226. cv::gapi::island("isl0", cv::GIn(in[0], in[1]), cv::GOut(out[0], out[1]));
  227. auto cc = cv::GComputation(cv::GIn(in[0], in[1]), cv::GOut(out[0], out[1]))
  228. .compile(cv::GMatDesc{CV_8U,1,{640,480}},
  229. cv::GMatDesc{CV_8U,1,{640,480}});
  230. const auto &gm = cc.priv().model();
  231. std::vector<ade::NodeHandle> handles_inside = {
  232. cv::gimpl::GModel::dataNodeOf(gm, tmp[0]),
  233. cv::gimpl::GModel::dataNodeOf(gm, tmp[1]),
  234. cv::gimpl::GModel::dataNodeOf(gm, tmp[2]),
  235. cv::gimpl::GModel::dataNodeOf(gm, tmp[3]),
  236. cv::gimpl::GModel::dataNodeOf(gm, scl),
  237. };
  238. std::vector<ade::NodeHandle> handles_outside = {
  239. cv::gimpl::GModel::dataNodeOf(gm, in[0]),
  240. cv::gimpl::GModel::dataNodeOf(gm, in[1]),
  241. cv::gimpl::GModel::dataNodeOf(gm, out[0]),
  242. cv::gimpl::GModel::dataNodeOf(gm, out[1]),
  243. };
  244. for (auto nh_inside : handles_inside)
  245. {
  246. EXPECT_EQ("isl0", gm.metadata(nh_inside).get<cv::gimpl::Island>().island);
  247. }
  248. for (auto nh_outside : handles_outside)
  249. {
  250. EXPECT_FALSE(gm.metadata(nh_outside).contains<cv::gimpl::Island>());
  251. }
  252. }
  253. TEST_F(ComplexIslands, ViaScalar)
  254. {
  255. //
  256. // .........................................#internal0.
  257. // (in0) -> Not -> (tmp0) --> Add ---------> (tmp2) --> AddC -------> (out0)
  258. // :....................^.........................^...:
  259. // : :
  260. // .....................:.........(isl0). :
  261. // (in1) -> Blur -> (tmp1) ----'--> Sum ----> (scl0) ----'
  262. // :..........:.........................:
  263. // :
  264. // : ..................#internal1.
  265. // `------------> Median -> (tmp3) --> Blur -------> (out1)
  266. // :...........................:
  267. cv::gapi::island("isl0", cv::GIn(in[1]), cv::GOut(scl));
  268. auto cc = cv::GComputation(cv::GIn(in[0], in[1]), cv::GOut(out[0], out[1]))
  269. .compile(cv::GMatDesc{CV_8U,1,{640,480}},
  270. cv::GMatDesc{CV_8U,1,{640,480}});
  271. const auto &gm = cc.priv().model();
  272. const auto tmp0_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[0]);
  273. const auto tmp1_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[1]);
  274. const auto tmp2_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[2]);
  275. const auto tmp3_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[3]);
  276. EXPECT_NE("isl0", gm.metadata(tmp0_nh).get<cv::gimpl::Island>().island); // <internal>
  277. EXPECT_EQ("isl0", gm.metadata(tmp1_nh).get<cv::gimpl::Island>().island); // isl0
  278. EXPECT_NE("isl0", gm.metadata(tmp2_nh).get<cv::gimpl::Island>().island); // <internal>
  279. EXPECT_NE("isl0", gm.metadata(tmp3_nh).get<cv::gimpl::Island>().island); // <internal>
  280. std::vector<ade::NodeHandle> handles_outside = {
  281. cv::gimpl::GModel::dataNodeOf(gm, in[0]),
  282. cv::gimpl::GModel::dataNodeOf(gm, in[1]),
  283. cv::gimpl::GModel::dataNodeOf(gm, scl),
  284. cv::gimpl::GModel::dataNodeOf(gm, out[0]),
  285. cv::gimpl::GModel::dataNodeOf(gm, out[1]),
  286. };
  287. for (auto nh_outside : handles_outside)
  288. {
  289. EXPECT_FALSE(gm.metadata(nh_outside).contains<cv::gimpl::Island>());
  290. }
  291. }
  292. TEST_F(ComplexIslands, BorderDataIsland)
  293. {
  294. // .................................(isl0)..
  295. // : :
  296. // (in0) -> Not -> (tmp0) --> Add ---------> (tmp2) --> AddC -------> (out0)
  297. // : ^ : ^
  298. // : : : :
  299. // (in1) -> Blur -> (tmp1) ----'--> Sum ----> (scl0) ----'
  300. // :...........:...........................:
  301. // : : :
  302. // : : :.........................................(isl1)..
  303. // : `------------> Median -> (tmp3) --> Blur -------> (out1)
  304. // : :
  305. // :......................................................:
  306. cv::gapi::island("isl0", cv::GIn(in[0], in[1]), cv::GOut(tmp[2], scl));
  307. cv::gapi::island("isl1", cv::GIn(tmp[1]), cv::GOut(out[1]));
  308. auto cc = cv::GComputation(cv::GIn(in[0], in[1]), cv::GOut(out[0], out[1]))
  309. .compile(cv::GMatDesc{CV_8U,1,{640,480}},
  310. cv::GMatDesc{CV_8U,1,{640,480}});
  311. const auto &gm = cc.priv().model();
  312. const auto in0_nh = cv::gimpl::GModel::dataNodeOf(gm, in[0]);
  313. const auto in1_nh = cv::gimpl::GModel::dataNodeOf(gm, in[1]);
  314. const auto tmp0_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[0]);
  315. const auto tmp1_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[1]);
  316. const auto tmp2_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[2]);
  317. const auto tmp3_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[3]);
  318. const auto scl_nh = cv::gimpl::GModel::dataNodeOf(gm, scl);
  319. const auto out0_nh = cv::gimpl::GModel::dataNodeOf(gm, out[0]);
  320. const auto out1_nh = cv::gimpl::GModel::dataNodeOf(gm, out[1]);
  321. // Check handles inside isl0
  322. EXPECT_EQ("isl0", gm.metadata(tmp0_nh).get<cv::gimpl::Island>().island);
  323. EXPECT_EQ("isl0", gm.metadata(tmp1_nh).get<cv::gimpl::Island>().island);
  324. // ^^^ Important - tmp1 is assigned to isl0, not isl1
  325. // Check handles inside isl1
  326. EXPECT_EQ("isl1", gm.metadata(tmp3_nh).get<cv::gimpl::Island>().island);
  327. // Check outside handles
  328. EXPECT_FALSE(gm.metadata(in0_nh) .contains<cv::gimpl::Island>());
  329. EXPECT_FALSE(gm.metadata(in1_nh) .contains<cv::gimpl::Island>());
  330. EXPECT_FALSE(gm.metadata(tmp2_nh).contains<cv::gimpl::Island>());
  331. EXPECT_FALSE(gm.metadata(scl_nh) .contains<cv::gimpl::Island>());
  332. EXPECT_FALSE(gm.metadata(out0_nh).contains<cv::gimpl::Island>());
  333. EXPECT_FALSE(gm.metadata(out1_nh).contains<cv::gimpl::Island>());
  334. }
  335. TEST_F(ComplexIslands, IncompleteSpec)
  336. {
  337. // isl0
  338. // ...........................
  339. // (in0) -> Not -> (tmp0) --> Add ---------> (tmp2) --> AddC -------> (out0)
  340. // :...........xxx.......^...: ^
  341. // : :
  342. // (in1) -> Blur -> (tmp1) ----'--> Sum ----> (scl0) ----'
  343. // :
  344. // :
  345. // `------------> Median -> (tmp3) --> Blur -------> (out1)
  346. //
  347. // tmp1 is missing in the below spec
  348. EXPECT_ANY_THROW(cv::gapi::island("isl0", cv::GIn(in[0]), cv::GOut(tmp[2])));
  349. // empty range
  350. EXPECT_ANY_THROW(cv::gapi::island("isl1", cv::GIn(tmp[2]), cv::GOut(tmp[2])));
  351. }
  352. TEST_F(ComplexIslands, InputOperationFromDifferentIslands)
  353. {
  354. // isl1
  355. // ........................... ........
  356. // (in0)--> Not -> (tmp0) --> Add :--------> (tmp2)-->: AddC : -------> (out0)
  357. // :......................^..: : ^ :
  358. // isl0 : : : :
  359. // .......................:....................... : :
  360. // (in1) :-> Blur -> (tmp1) ----'--> Sum ----> (scl0) ----- :
  361. // :....................................................:
  362. // isl0 :
  363. // `------------> Median -> (tmp3) --> Blur -------> (out1)
  364. //
  365. cv::gapi::island("isl0", cv::GIn(in[1], tmp[2]), cv::GOut(out[0]));
  366. cv::gapi::island("isl1", cv::GIn(in[0], tmp[1]), cv::GOut(tmp[2]));
  367. auto cc = cv::GComputation(cv::GIn(in[0], in[1]), cv::GOut(out[0], out[1]))
  368. .compile(cv::GMatDesc{CV_8U,1,{640,480}},
  369. cv::GMatDesc{CV_8U,1,{640,480}});
  370. const auto &gm = cc.priv().model();
  371. const auto tmp0_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[0]);
  372. const auto tmp1_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[1]);
  373. const auto tmp2_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[2]);
  374. EXPECT_EQ("isl1", gm.metadata(tmp0_nh).get<cv::gimpl::Island>().island);
  375. EXPECT_EQ("isl0", gm.metadata(tmp1_nh).get<cv::gimpl::Island>().island);
  376. EXPECT_FALSE(gm.metadata(tmp2_nh).contains<cv::gimpl::Island>());
  377. }
  378. TEST_F(ComplexIslands, NoWayBetweenNodes)
  379. {
  380. // (in0) -> Not -> (tmp0) --> Add ---------> (tmp2) --> AddC -------> (out0)
  381. // ^ ^
  382. // (in1) -> Blur -> (tmp1) ----'--> Sum ----> (scl0) ----'
  383. // :
  384. // `------------> Median -> (tmp3) --> Blur -------> (out1)
  385. EXPECT_ANY_THROW(cv::gapi::island("isl0", cv::GIn(in[1]), cv::GOut(tmp[0])));
  386. }
  387. TEST_F(ComplexIslands, IslandsContainUnusedPart)
  388. {
  389. // Unused part of the graph
  390. // 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
  391. // x x
  392. // x(in0) -> Not -> (tmp0) --> Add ---------> (tmp2)---> AddC ---------> (out0) x
  393. // x ^ ^ x
  394. // x x x x x x x x x x x x x x x | x x | x
  395. // | x | x
  396. // ...... | x | x
  397. // (in1) -> :Blur:----------> (tmp1) x-----> Sum ------> (scl0) x
  398. // ...... : x x x x x x x x x x x x x x x x x x x x x x x x
  399. // isl0
  400. // :
  401. // `------------> Median -> (tmp3) --> Blur -------> (out1)
  402. cv::gapi::island("isl0", cv::GIn(in[1]), cv::GOut(scl));
  403. auto cc = cv::GComputation(cv::GIn(in[1]), cv::GOut(out[1]))
  404. .compile(cv::GMatDesc{CV_8U,1,{640,480}});
  405. const auto &gm = cc.priv().model();
  406. const auto tmp1_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[1]);
  407. //The output 0 is not specified in the graph
  408. //means that there will not be a node scl, so that tmp1 will not assign to the island
  409. // FIXME Check that blur assigned to island using the function producerOf
  410. // After merge islands fusion
  411. EXPECT_FALSE(gm.metadata(tmp1_nh) .contains<cv::gimpl::Island>());
  412. }
  413. TEST_F(ComplexIslands, FullGraphInTwoIslands)
  414. {
  415. // isl0
  416. // ..................................................
  417. // (in0) -> :Not -> (tmp0) --> Add ---------> (tmp2) --> AddC: -------> (out0)
  418. // ...................^.... ^ :
  419. // ............... | : : :
  420. // (in1) -> :Blur-> (tmp1):----'-->:Sum ----> (scl0) ----' :
  421. // ........ | : ...........................
  422. // isl1 : | :............................................
  423. // : `------------> Median -> (tmp3) --> Blur ------->:(out1)
  424. // ....................................................
  425. cv::gapi::island("isl0", cv::GIn(in[0], tmp[1]), cv::GOut(out[0]));
  426. cv::gapi::island("isl1", cv::GIn(in[1]), cv::GOut(out[1]));
  427. auto cc = cv::GComputation(cv::GIn(in[0], in[1]), cv::GOut(out[0], out[1]))
  428. .compile(cv::GMatDesc{CV_8U,1,{640,480}},
  429. cv::GMatDesc{CV_8U,1,{640,480}});
  430. const auto &gm = cc.priv().model();
  431. const auto in0_nh = cv::gimpl::GModel::dataNodeOf(gm, in[0]);
  432. const auto in1_nh = cv::gimpl::GModel::dataNodeOf(gm, in[1]);
  433. const auto tmp0_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[0]);
  434. const auto tmp1_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[1]);
  435. const auto tmp2_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[2]);
  436. const auto tmp3_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[3]);
  437. const auto scl_nh = cv::gimpl::GModel::dataNodeOf(gm, scl);
  438. const auto out0_nh = cv::gimpl::GModel::dataNodeOf(gm, out[0]);
  439. const auto out1_nh = cv::gimpl::GModel::dataNodeOf(gm, out[1]);
  440. // Check handles inside isl0
  441. EXPECT_EQ("isl0", gm.metadata(tmp0_nh).get<cv::gimpl::Island>().island);
  442. EXPECT_EQ("isl0", gm.metadata(tmp2_nh).get<cv::gimpl::Island>().island);
  443. EXPECT_EQ("isl0", gm.metadata(scl_nh).get<cv::gimpl::Island>().island);
  444. // Check handles inside isl1
  445. EXPECT_EQ("isl1", gm.metadata(tmp1_nh).get<cv::gimpl::Island>().island);
  446. EXPECT_EQ("isl1", gm.metadata(tmp3_nh).get<cv::gimpl::Island>().island);
  447. // Check outside handles
  448. EXPECT_FALSE(gm.metadata(in0_nh) .contains<cv::gimpl::Island>());
  449. EXPECT_FALSE(gm.metadata(in1_nh) .contains<cv::gimpl::Island>());
  450. EXPECT_FALSE(gm.metadata(out0_nh).contains<cv::gimpl::Island>());
  451. EXPECT_FALSE(gm.metadata(out1_nh).contains<cv::gimpl::Island>());
  452. }
  453. TEST_F(ComplexIslands, OnlyOperationsAssignedToIslands)
  454. {
  455. cv::gapi::island("isl0", cv::GIn(in[1]), cv::GOut(tmp[1]));
  456. cv::gapi::island("isl1", cv::GIn(tmp[1]), cv::GOut(scl));
  457. cv::gapi::island("isl2", cv::GIn(scl, tmp[2]), cv::GOut(out[0]));
  458. cv::gapi::island("isl3", cv::GIn(in[0]), cv::GOut(tmp[0]));
  459. cv::gapi::island("isl4", cv::GIn(tmp[0], tmp[1]), cv::GOut(tmp[2]));
  460. cv::gapi::island("isl5", cv::GIn(tmp[1]), cv::GOut(tmp[3]));
  461. cv::gapi::island("isl6", cv::GIn(tmp[3]), cv::GOut(out[1]));
  462. auto cc = cv::GComputation(cv::GIn(in[0], in[1]), cv::GOut(out[0], out[1]))
  463. .compile(cv::GMatDesc{CV_8U,1,{640,480}},
  464. cv::GMatDesc{CV_8U,1,{640,480}});
  465. const auto &gm = cc.priv().model();
  466. //FIXME: Check that operation handles are really assigned to isl0..isl6
  467. const auto in0_nh = cv::gimpl::GModel::dataNodeOf(gm, in[0]);
  468. const auto in1_nh = cv::gimpl::GModel::dataNodeOf(gm, in[1]);
  469. const auto tmp0_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[0]);
  470. const auto tmp1_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[1]);
  471. const auto tmp2_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[2]);
  472. const auto tmp3_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[3]);
  473. const auto scl_nh = cv::gimpl::GModel::dataNodeOf(gm, scl);
  474. const auto out0_nh = cv::gimpl::GModel::dataNodeOf(gm, out[0]);
  475. const auto out1_nh = cv::gimpl::GModel::dataNodeOf(gm, out[1]);
  476. EXPECT_FALSE(gm.metadata(in0_nh) .contains<cv::gimpl::Island>());
  477. EXPECT_FALSE(gm.metadata(in1_nh) .contains<cv::gimpl::Island>());
  478. EXPECT_FALSE(gm.metadata(tmp0_nh) .contains<cv::gimpl::Island>());
  479. EXPECT_FALSE(gm.metadata(tmp1_nh) .contains<cv::gimpl::Island>());
  480. EXPECT_FALSE(gm.metadata(tmp2_nh) .contains<cv::gimpl::Island>());
  481. EXPECT_FALSE(gm.metadata(tmp3_nh) .contains<cv::gimpl::Island>());
  482. EXPECT_FALSE(gm.metadata(scl_nh) .contains<cv::gimpl::Island>());
  483. EXPECT_FALSE(gm.metadata(out0_nh).contains<cv::gimpl::Island>());
  484. EXPECT_FALSE(gm.metadata(out1_nh).contains<cv::gimpl::Island>());
  485. }
  486. namespace
  487. {
  488. struct IslandStructureWithGArray
  489. {
  490. GIntArray in, out;
  491. GMat tmp;
  492. IslandStructureWithGArray()
  493. {
  494. tmp = CreateMatWithDiag::on(in);
  495. out = Mat2Array::on(tmp);
  496. }
  497. };
  498. struct IslandsWithGArray: public ::testing::Test, public IslandStructureWithGArray {};
  499. } // namespace
  500. TEST_F(IslandsWithGArray, IslandWithGArrayAsInput)
  501. {
  502. cv::gapi::island("isl0", cv::GIn(in), cv::GOut(tmp));
  503. const auto pkg = cv::gapi::kernels<CreateMatWithDiagImpl, Mat2ArrayImpl>();
  504. auto cc = cv::GComputation(cv::GIn(in), GOut(out)).compile(cv::empty_array_desc(), cv::compile_args(pkg));
  505. const auto &gm = cc.priv().model();
  506. const auto in_nh = cv::gimpl::GModel::dataNodeOf(gm, in.strip());
  507. const auto out_nh = cv::gimpl::GModel::dataNodeOf(gm, out.strip());
  508. const auto tmp_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp);
  509. GAPI_Assert(tmp_nh->inNodes().size() == 1);
  510. const auto create_diag_mat_nh = tmp_nh->inNodes().front();
  511. EXPECT_EQ("isl0", gm.metadata(create_diag_mat_nh).get<cv::gimpl::Island>().island);
  512. EXPECT_FALSE(gm.metadata(in_nh) .contains<cv::gimpl::Island>());
  513. EXPECT_FALSE(gm.metadata(out_nh) .contains<cv::gimpl::Island>());
  514. EXPECT_FALSE(gm.metadata(tmp_nh) .contains<cv::gimpl::Island>());
  515. }
  516. TEST_F(IslandsWithGArray, IslandWithGArrayAsOutput)
  517. {
  518. cv::gapi::island("isl0", cv::GIn(tmp), cv::GOut(out));
  519. const auto pkg = cv::gapi::kernels<CreateMatWithDiagImpl, Mat2ArrayImpl>();
  520. auto cc = cv::GComputation(cv::GIn(in), GOut(out)).compile(cv::empty_array_desc(), cv::compile_args(pkg));
  521. const auto &gm = cc.priv().model();
  522. const auto in_nh = cv::gimpl::GModel::dataNodeOf(gm, in.strip());
  523. const auto out_nh = cv::gimpl::GModel::dataNodeOf(gm, out.strip());
  524. const auto tmp_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp);
  525. GAPI_Assert(tmp_nh->inNodes().size() == 1);
  526. const auto mat2array_nh = out_nh->inNodes().front();
  527. EXPECT_EQ("isl0", gm.metadata(mat2array_nh).get<cv::gimpl::Island>().island);
  528. EXPECT_FALSE(gm.metadata(in_nh) .contains<cv::gimpl::Island>());
  529. EXPECT_FALSE(gm.metadata(out_nh) .contains<cv::gimpl::Island>());
  530. EXPECT_FALSE(gm.metadata(tmp_nh) .contains<cv::gimpl::Island>());
  531. }
  532. ////////////////////////////////////////////////////////////////////////////////
  533. // Wrong input tests on island name
  534. //
  535. namespace
  536. {
  537. struct CheckName : public TestWithParam<std::tuple<bool, const char*> >,
  538. public PlainIslandsFixture
  539. {
  540. void assignIsland(const std::string &s)
  541. {
  542. cv::gapi::island(s, cv::GIn(tmp[0]), cv::GOut(tmp[2]));
  543. };
  544. };
  545. TEST_P(CheckName, Test)
  546. {
  547. bool correct = false;
  548. const char *name = "";
  549. std::tie(correct, name) = GetParam();
  550. if (correct) EXPECT_NO_THROW(assignIsland(name));
  551. else EXPECT_ANY_THROW(assignIsland(name));
  552. }
  553. } // namespace
  554. INSTANTIATE_TEST_CASE_P(IslandName, CheckName,
  555. Values(std::make_tuple(true, "name"),
  556. std::make_tuple(true, " name "),
  557. std::make_tuple(true, " n a m e "),
  558. std::make_tuple(true, " 123 $$ %%"),
  559. std::make_tuple(true, ".: -"),
  560. std::make_tuple(false, ""),
  561. std::make_tuple(false, " "),
  562. std::make_tuple(false, " \t "),
  563. std::make_tuple(false, " \t \t ")));
  564. // FIXME: add <internal> test on unrollExpr() use for islands
  565. } // opencv_test