gapi_transactions_test.cpp 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369
  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 - 2020 Intel Corporation
  6. #include "../test_precomp.hpp"
  7. #include <ade/graph.hpp>
  8. #include <ade/typed_graph.hpp>
  9. #include "compiler/transactions.hpp"
  10. namespace opencv_test
  11. {
  12. namespace
  13. {
  14. bool contains(const ade::Graph& graph, const ade::NodeHandle& node)
  15. {
  16. auto nodes = graph.nodes();
  17. return nodes.end() != std::find(nodes.begin(), nodes.end(), node);
  18. }
  19. bool connected(const ade::NodeHandle& src_node, const ade::NodeHandle& dst_node)
  20. {
  21. auto nodes = src_node->outNodes();
  22. return nodes.end() != std::find(nodes.begin(), nodes.end(), dst_node);
  23. }
  24. struct SimpleGraph
  25. {
  26. // ehs[0] ehs[1] ehs[2] ehs[3]
  27. // nhs[0] -- > nhs[1] --> nhs[2] --> nhs[3] --> nhs[4]
  28. enum { node_nums = 5 };
  29. ade::Graph graph;
  30. ade::NodeHandle fused_nh; // For check that fusion node is connected to the
  31. // inputs of the prod and the outputs of the cons
  32. std::array<ade::NodeHandle, node_nums> nhs;
  33. std::array<ade::EdgeHandle, node_nums - 1> ehs;
  34. using Change = ChangeT<>;
  35. Change::List changes;
  36. SimpleGraph()
  37. {
  38. nhs[0] = graph.createNode();
  39. for (int i = 1; i < node_nums; ++i)
  40. {
  41. nhs[i ] = graph.createNode();
  42. ehs[i - 1] = graph.link(nhs[i - 1], nhs[i]);
  43. }
  44. }
  45. void fuse()
  46. {
  47. // nhs[0] --> fused_nh --> nhs[4]
  48. fused_nh = graph.createNode();
  49. changes.enqueue<Change::NodeCreated>(fused_nh);
  50. changes.enqueue<Change::NewLink> (graph, nhs[0], fused_nh);
  51. changes.enqueue<Change::DropLink>(graph, nhs[1], ehs[0]);
  52. changes.enqueue<Change::NewLink> (graph, fused_nh, nhs[4]);
  53. changes.enqueue<Change::DropLink>(graph, nhs[3], ehs[3]);
  54. changes.enqueue<Change::DropLink>(graph, nhs[1], ehs[1]);
  55. changes.enqueue<Change::DropLink>(graph, nhs[2], ehs[2]);
  56. changes.enqueue<Change::DropNode>(nhs[1]);
  57. changes.enqueue<Change::DropNode>(nhs[2]);
  58. changes.enqueue<Change::DropNode>(nhs[3]);
  59. }
  60. void commit() { changes.commit(graph); }
  61. void rollback() { changes.rollback(graph); }
  62. };
  63. struct Transactions: public ::testing::Test, public SimpleGraph {};
  64. } // anonymous namespace
  65. TEST_F(Transactions, NodeCreated_Create)
  66. {
  67. auto new_nh = graph.createNode();
  68. Change::NodeCreated node_created(new_nh);
  69. EXPECT_EQ(6u, static_cast<std::size_t>(graph.nodes().size()));
  70. EXPECT_TRUE(contains(graph, new_nh));
  71. }
  72. TEST_F(Transactions, NodeCreated_RollBack)
  73. {
  74. auto new_nh = graph.createNode();
  75. Change::NodeCreated node_created(new_nh);
  76. node_created.rollback(graph);
  77. EXPECT_EQ(5u, static_cast<std::size_t>(graph.nodes().size()));
  78. EXPECT_FALSE(contains(graph, new_nh));
  79. }
  80. TEST_F(Transactions, NodeCreated_Commit)
  81. {
  82. auto new_nh = graph.createNode();
  83. Change::NodeCreated node_created(new_nh);
  84. node_created.commit(graph);
  85. EXPECT_EQ(6u, static_cast<std::size_t>(graph.nodes().size()));
  86. EXPECT_TRUE(contains(graph, new_nh));
  87. }
  88. TEST_F(Transactions, DropLink_Create)
  89. {
  90. Change::DropLink drop_link(graph, nhs[0], ehs[0]);
  91. EXPECT_FALSE(connected(nhs[0], nhs[1]));
  92. }
  93. TEST_F(Transactions, DropLink_RollBack)
  94. {
  95. Change::DropLink drop_link(graph, nhs[0], ehs[0]);
  96. drop_link.rollback(graph);
  97. EXPECT_TRUE(connected(nhs[0], nhs[1]));
  98. }
  99. TEST_F(Transactions, DropLink_Commit)
  100. {
  101. Change::DropLink drop_link(graph, nhs[0], ehs[0]);
  102. drop_link.commit(graph);
  103. EXPECT_FALSE(connected(nhs[0], nhs[1]));
  104. }
  105. TEST_F(Transactions, NewLink_Create)
  106. {
  107. auto new_nh = graph.createNode();
  108. Change::NewLink new_link(graph, new_nh, nhs[0]);
  109. EXPECT_TRUE(connected(new_nh, nhs[0]));
  110. }
  111. TEST_F(Transactions, NewLink_RollBack)
  112. {
  113. auto new_nh = graph.createNode();
  114. Change::NewLink new_link(graph, new_nh, nhs[0]);
  115. new_link.rollback(graph);
  116. EXPECT_FALSE(connected(new_nh, nhs[0]));
  117. }
  118. TEST_F(Transactions, NewLink_Commit)
  119. {
  120. auto new_nh = graph.createNode();
  121. Change::NewLink new_link(graph, new_nh, nhs[0]);
  122. new_link.commit(graph);
  123. EXPECT_TRUE(connected(new_nh, nhs[0]));
  124. }
  125. TEST_F(Transactions, DropNode_Create)
  126. {
  127. auto new_nh = graph.createNode();
  128. Change::DropNode drop_node(new_nh);
  129. EXPECT_EQ(6u, static_cast<std::size_t>(graph.nodes().size()));
  130. EXPECT_TRUE(contains(graph, new_nh));
  131. }
  132. TEST_F(Transactions, DropNode_RollBack)
  133. {
  134. auto new_nh = graph.createNode();
  135. Change::DropNode drop_node(new_nh);
  136. drop_node.rollback(graph);
  137. EXPECT_EQ(6u, static_cast<std::size_t>(graph.nodes().size()));
  138. EXPECT_TRUE(contains(graph, new_nh));
  139. }
  140. TEST_F(Transactions, DropNode_Commit)
  141. {
  142. auto new_nh = graph.createNode();
  143. Change::DropNode drop_node(new_nh);
  144. drop_node.commit(graph);
  145. EXPECT_EQ(5u, static_cast<std::size_t>(graph.nodes().size()));
  146. EXPECT_FALSE(contains(graph, new_nh));
  147. }
  148. TEST_F(Transactions, Fusion_Commit)
  149. {
  150. fuse();
  151. commit();
  152. EXPECT_EQ(3u, static_cast<std::size_t>(graph.nodes().size()));
  153. EXPECT_TRUE(connected(nhs[0] , fused_nh));
  154. EXPECT_TRUE(connected(fused_nh, nhs[4]));
  155. }
  156. TEST_F(Transactions, Fusion_RollBack)
  157. {
  158. fuse();
  159. rollback();
  160. EXPECT_EQ(static_cast<std::size_t>(node_nums),
  161. static_cast<std::size_t>(graph.nodes().size()));
  162. EXPECT_FALSE(contains(graph, fused_nh));
  163. for (int i = 0; i < static_cast<int>(node_nums) - 1; ++i)
  164. {
  165. EXPECT_TRUE(connected(nhs[i], nhs[i + 1]));
  166. }
  167. }
  168. namespace
  169. {
  170. struct MetaInt {
  171. static const char *name() { return "int_meta"; }
  172. int x;
  173. };
  174. struct MetaStr {
  175. static const char *name() { return "string_meta"; }
  176. std::string s;
  177. };
  178. }
  179. TEST(PreservedMeta, TestMetaCopy_Full)
  180. {
  181. ade::Graph g;
  182. ade::TypedGraph<MetaInt, MetaStr> tg(g);
  183. auto src_nh = tg.createNode();
  184. tg.metadata(src_nh).set(MetaInt{42});
  185. tg.metadata(src_nh).set(MetaStr{"hi"});
  186. auto dst_nh = tg.createNode();
  187. EXPECT_FALSE(tg.metadata(dst_nh).contains<MetaInt>());
  188. EXPECT_FALSE(tg.metadata(dst_nh).contains<MetaStr>());
  189. // Here we specify all the meta types we know about the src node
  190. // Assume Preserved copies its all for us
  191. Preserved<ade::NodeHandle, MetaInt, MetaStr>(g, src_nh).copyTo(g, dst_nh);
  192. ASSERT_TRUE(tg.metadata(dst_nh).contains<MetaInt>());
  193. ASSERT_TRUE(tg.metadata(dst_nh).contains<MetaStr>());
  194. EXPECT_EQ(42, tg.metadata(dst_nh).get<MetaInt>().x);
  195. EXPECT_EQ("hi", tg.metadata(dst_nh).get<MetaStr>().s);
  196. }
  197. TEST(PreservedMeta, TestMetaCopy_Partial_Dst)
  198. {
  199. ade::Graph g;
  200. ade::TypedGraph<MetaInt, MetaStr> tg(g);
  201. auto tmp_nh1 = tg.createNode();
  202. auto tmp_nh2 = tg.createNode();
  203. auto src_eh = tg.link(tmp_nh1, tmp_nh2);
  204. tg.metadata(src_eh).set(MetaInt{42});
  205. tg.metadata(src_eh).set(MetaStr{"hi"});
  206. auto tmp_nh3 = tg.createNode();
  207. auto tmp_nh4 = tg.createNode();
  208. auto dst_eh = tg.link(tmp_nh3, tmp_nh4);
  209. EXPECT_FALSE(tg.metadata(dst_eh).contains<MetaInt>());
  210. EXPECT_FALSE(tg.metadata(dst_eh).contains<MetaStr>());
  211. // Here we specify just a single meta type for the src node
  212. // Assume Preserved copies only this type and nothing else
  213. Preserved<ade::EdgeHandle, MetaStr>(g, src_eh).copyTo(g, dst_eh);
  214. ASSERT_FALSE(tg.metadata(dst_eh).contains<MetaInt>());
  215. ASSERT_TRUE (tg.metadata(dst_eh).contains<MetaStr>());
  216. EXPECT_EQ("hi", tg.metadata(dst_eh).get<MetaStr>().s);
  217. }
  218. TEST(PreservedMeta, TestMetaCopy_Partial_Src)
  219. {
  220. ade::Graph g;
  221. ade::TypedGraph<MetaInt, MetaStr> tg(g);
  222. auto src_nh = tg.createNode();
  223. tg.metadata(src_nh).set(MetaInt{42});
  224. auto dst_nh = tg.createNode();
  225. EXPECT_FALSE(tg.metadata(dst_nh).contains<MetaInt>());
  226. EXPECT_FALSE(tg.metadata(dst_nh).contains<MetaStr>());
  227. // Here we specify all the meta types we know about the src node
  228. // but the src node has just one of them.
  229. // A valid situation, only MetaInt to be copied.
  230. Preserved<ade::NodeHandle, MetaInt, MetaStr>(g, src_nh).copyTo(g, dst_nh);
  231. ASSERT_TRUE (tg.metadata(dst_nh).contains<MetaInt>());
  232. ASSERT_FALSE(tg.metadata(dst_nh).contains<MetaStr>());
  233. EXPECT_EQ(42, tg.metadata(dst_nh).get<MetaInt>().x);
  234. }
  235. TEST(PreservedMeta, TestMetaCopy_Nothing)
  236. {
  237. ade::Graph g;
  238. ade::TypedGraph<MetaInt, MetaStr> tg(g);
  239. auto src_nh = tg.createNode();
  240. auto dst_nh = tg.createNode();
  241. EXPECT_FALSE(tg.metadata(src_nh).contains<MetaInt>());
  242. EXPECT_FALSE(tg.metadata(src_nh).contains<MetaStr>());
  243. EXPECT_FALSE(tg.metadata(dst_nh).contains<MetaInt>());
  244. EXPECT_FALSE(tg.metadata(dst_nh).contains<MetaStr>());
  245. // Here we specify all the meta types we know about the src node
  246. // but the src node has none of those. See how it works now
  247. Preserved<ade::NodeHandle, MetaInt, MetaStr>(g, src_nh).copyTo(g, dst_nh);
  248. ASSERT_FALSE(tg.metadata(dst_nh).contains<MetaInt>());
  249. ASSERT_FALSE(tg.metadata(dst_nh).contains<MetaStr>());
  250. }
  251. TEST(PreservedMeta, DropEdge)
  252. {
  253. ade::Graph g;
  254. ade::TypedGraph<MetaInt, MetaStr> tg(g);
  255. auto nh1 = tg.createNode();
  256. auto nh2 = tg.createNode();
  257. auto eh = tg.link(nh1, nh2);
  258. tg.metadata(eh).set(MetaInt{42});
  259. tg.metadata(eh).set(MetaStr{"hi"});
  260. // Drop an edge using the transaction API
  261. using Change = ChangeT<MetaInt, MetaStr>;
  262. Change::List changes;
  263. changes.enqueue<Change::DropLink>(g, nh1, eh);
  264. EXPECT_EQ(0u, nh1->outNodes().size());
  265. EXPECT_EQ(nullptr, eh);
  266. // Now restore the edge and check if it's meta was restored
  267. changes.rollback(g);
  268. ASSERT_EQ(1u, nh1->outNodes().size());
  269. eh = *nh1->outEdges().begin();
  270. ASSERT_TRUE(tg.metadata(eh).contains<MetaInt>());
  271. ASSERT_TRUE(tg.metadata(eh).contains<MetaStr>());
  272. EXPECT_EQ(42, tg.metadata(eh).get<MetaInt>().x);
  273. EXPECT_EQ("hi", tg.metadata(eh).get<MetaStr>().s);
  274. }
  275. } // opencv_test