graph_manager.hpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
  1. /**
  2. * @file tests/multithreading/lifegame/graph_manager.cpp
  3. * @author The ARTIS Development Team
  4. * See the AUTHORS or Authors.txt file
  5. */
  6. /*
  7. * ARTIS - the multimodeling and simulation environment
  8. * This file is a part of the ARTIS environment
  9. *
  10. * Copyright (C) 2013-2019 ULCO http://www.univ-littoral.fr
  11. *
  12. * This program is free software: you can redistribute it and/or modify
  13. * it under the terms of the GNU General Public License as published by
  14. * the Free Software Foundation, either version 3 of the License, or
  15. * (at your option) any later version.
  16. *
  17. * This program is distributed in the hope that it will be useful,
  18. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  20. * GNU General Public License for more details.
  21. *
  22. * You should have received a copy of the GNU General Public License
  23. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  24. */
  25. #ifndef TESTS_MULTITHREADING_LIFEGAME_GRAPH_MANAGER_HPP
  26. #define TESTS_MULTITHREADING_LIFEGAME_GRAPH_MANAGER_HPP
  27. #include <tests/multithreading/lifegame/models.hpp>
  28. #include <artis-star/kernel/pdevs/multithreading/Coordinator.hpp>
  29. #include <artis-star/kernel/pdevs/GraphManager.hpp>
  30. #include <artis-star/kernel/pdevs/Simulator.hpp>
  31. namespace artis {
  32. namespace tests {
  33. namespace multithreading {
  34. namespace lifegame {
  35. struct GridGraphManagerParameters
  36. {
  37. unsigned int begin_column;
  38. unsigned int end_column;
  39. unsigned int begin_line;
  40. unsigned int end_line;
  41. unsigned int min_column;
  42. unsigned int max_column;
  43. unsigned int min_line;
  44. unsigned int max_line;
  45. };
  46. class FlatGraphManager
  47. : public artis::pdevs::GraphManager<common::DoubleTime,
  48. CellParameters,
  49. GridGraphManagerParameters>
  50. {
  51. public:
  52. enum submodels
  53. {
  54. CELL
  55. };
  56. FlatGraphManager(common::Coordinator<common::DoubleTime> *coordinator,
  57. const CellParameters &parameters,
  58. const GridGraphManagerParameters &graph_parameters)
  59. :
  60. artis::pdevs::GraphManager<common::DoubleTime, CellParameters, GridGraphManagerParameters>(
  61. coordinator, parameters, graph_parameters)
  62. {
  63. unsigned int column_number =
  64. graph_parameters.end_column - graph_parameters.begin_column + 1;
  65. unsigned int line_number =
  66. graph_parameters.end_line - graph_parameters.begin_line + 1;
  67. for (unsigned int i = graph_parameters.begin_column;
  68. i <= graph_parameters.end_column; ++i) {
  69. for (unsigned int j = graph_parameters.begin_line;
  70. j <= graph_parameters.end_line; ++j) {
  71. std::ostringstream ss;
  72. ss << "C_" << i << "_" << j;
  73. auto cell = new Simulator(ss.str(), parameters);
  74. _cells.push_back(cell);
  75. add_children(CELL, cell);
  76. }
  77. }
  78. for (int i = 0; i < (int) column_number; ++i) {
  79. for (int j = 0; j < (int) line_number; ++j) {
  80. int index = i * (int) line_number + j;
  81. // north
  82. if (j - 1 >= 0) {
  83. out({_cells[index], Cell::OUT})
  84. >> in({_cells[i * line_number + j - 1],
  85. Cell::IN});
  86. }
  87. // south
  88. if (j + 1 < (int) line_number) {
  89. out({_cells[index], Cell::OUT})
  90. >> in({_cells[i * line_number + j + 1],
  91. Cell::IN});
  92. }
  93. // west
  94. if (i - 1 >= 0) {
  95. out({_cells[index], Cell::OUT})
  96. >> in({_cells[(i - 1) * line_number
  97. + j], Cell::IN});
  98. }
  99. // east
  100. if (i + 1 < (int) column_number) {
  101. out({_cells[index], Cell::OUT})
  102. >> in({_cells[(i + 1) * line_number
  103. + j], Cell::IN});
  104. }
  105. // north west
  106. if (j - 1 >= 0 and i - 1 >= 0) {
  107. out({_cells[index], Cell::OUT})
  108. >> in({_cells[(i - 1) * line_number + j
  109. - 1], Cell::IN});
  110. }
  111. // south west
  112. if (j + 1 < (int) line_number and i - 1 >= 0) {
  113. out({_cells[index], Cell::OUT})
  114. >> in({_cells[(i - 1) * line_number + j
  115. + 1], Cell::IN});
  116. }
  117. // north east
  118. if (j - 1 >= 0 and i + 1 < (int) column_number) {
  119. out({_cells[index], Cell::OUT})
  120. >> in({_cells[(i + 1) * line_number + j
  121. - 1], Cell::IN});
  122. }
  123. // south east
  124. if (j + 1 < (int) line_number and i + 1 < (int) column_number) {
  125. out({_cells[index], Cell::OUT})
  126. >> in({_cells[(i + 1) * line_number + j
  127. + 1], Cell::IN});
  128. }
  129. }
  130. }
  131. }
  132. ~FlatGraphManager() override
  133. {
  134. std::for_each(_cells.begin(), _cells.end(),
  135. std::default_delete<Simulator>());
  136. }
  137. private:
  138. typedef pdevs::Simulator<common::DoubleTime, Cell, CellParameters> Simulator;
  139. typedef std::vector<Simulator *> Simulators;
  140. Simulators _cells;
  141. };
  142. class ParallelBuiltFlatGraphManager : public FlatGraphManager
  143. {
  144. public:
  145. ParallelBuiltFlatGraphManager(
  146. common::Coordinator<common::DoubleTime> *coordinator,
  147. const CellParameters &parameters,
  148. const GridGraphManagerParameters &graph_parameters)
  149. :
  150. FlatGraphManager(coordinator, parameters, graph_parameters)
  151. {
  152. // inputs
  153. unsigned int k = 0;
  154. // top / bottom
  155. {
  156. int j_top = (int) graph_parameters.begin_line - 1;
  157. int j_bottom = (int) graph_parameters.end_line + 1;
  158. for (int i = (int) graph_parameters.begin_column - 1;
  159. i <= (int) graph_parameters.end_column + 1; ++i) {
  160. std::ostringstream ss_out;
  161. ++k;
  162. if (i >= (int) graph_parameters.min_column
  163. and i <= (int) graph_parameters.max_column
  164. and j_top >= (int) graph_parameters.min_line) {
  165. ss_out << "in_" << i << "_" << j_top;
  166. coordinator->add_in_port({k, ss_out.str()});
  167. }
  168. ++k;
  169. if (i >= (int) graph_parameters.min_column
  170. and i <= (int) graph_parameters.max_column
  171. and j_bottom <= (int) graph_parameters.max_line) {
  172. ss_out << "in_" << i << "_" << j_bottom;
  173. coordinator->add_in_port({k, ss_out.str()});
  174. }
  175. }
  176. }
  177. // left / right
  178. {
  179. int i_left = (int) graph_parameters.begin_column - 1;
  180. int i_right = (int) graph_parameters.end_column + 1;
  181. for (int j = (int) graph_parameters.begin_line;
  182. j <= (int) graph_parameters.end_line; ++j) {
  183. std::ostringstream ss_out;
  184. ++k;
  185. if (j >= (int) graph_parameters.min_line
  186. and j <= (int) graph_parameters.max_line
  187. and i_left >= (int) graph_parameters.min_column) {
  188. ss_out << "out_" << i_left << "_" << j;
  189. coordinator->add_in_port({k, ss_out.str()});
  190. }
  191. ++k;
  192. if (j >= (int) graph_parameters.min_line
  193. and j <= (int) graph_parameters.max_line
  194. and i_right >= (int) graph_parameters.max_column) {
  195. ss_out << "out_" << i_right << "_" << j;
  196. coordinator->add_in_port({k, ss_out.str()});
  197. }
  198. }
  199. }
  200. // outputs
  201. k = 0;
  202. // top / bottom
  203. {
  204. int j_top = (int) graph_parameters.begin_line;
  205. int j_bottom = (int) graph_parameters.end_line;
  206. for (int i = (int) graph_parameters.begin_column;
  207. i <= (int) graph_parameters.end_column; ++i) {
  208. std::ostringstream ss_out;
  209. ++k;
  210. ss_out << "out_" << i << "_" << j_top;
  211. coordinator->add_out_port({k, ss_out.str()});
  212. ++k;
  213. ss_out << "out_" << i << "_" << j_bottom;
  214. coordinator->add_out_port({k, ss_out.str()});
  215. }
  216. }
  217. // left / right
  218. {
  219. int i_left = (int) graph_parameters.begin_column;
  220. int i_right = (int) graph_parameters.end_column;
  221. for (int j = (int) graph_parameters.begin_line + 1;
  222. j <= (int) graph_parameters.end_line - 1; ++j) {
  223. std::ostringstream ss_out;
  224. ++k;
  225. ss_out << "out_" << i_left << "_" << j;
  226. coordinator->add_out_port({k, ss_out.str()});
  227. ++k;
  228. ss_out << "out_" << i_right << "_" << j;
  229. coordinator->add_out_port({k, ss_out.str()});
  230. }
  231. }
  232. // for (Edges::const_iterator it = parameters._output_edges.begin();
  233. // it != parameters._output_edges.end(); ++it) {
  234. // std::ostringstream ss_out;
  235. //
  236. // ss_out << "out_" << it->first;
  237. // if (not coordinator->exist_out_port(ss_out.str())) {
  238. // coordinator->add_out_port(ss_out.str());
  239. // }
  240. // if (not ParallelBuiltFlatGraphManager::exist_link(
  241. // ParallelBuiltFlatGraphManager::_simulators[it->first],
  242. // "out", coordinator, ss_out.str())) {
  243. // ParallelBuiltFlatGraphManager::add_link(
  244. // ParallelBuiltFlatGraphManager::_simulators[it->first],
  245. // "out", coordinator, ss_out.str());
  246. // }
  247. // }
  248. }
  249. void init()
  250. {}
  251. void start(common::DoubleTime::type /* t */)
  252. {}
  253. void transition(
  254. const common::Models<common::DoubleTime> & /* receivers */,
  255. common::DoubleTime::type /* t */)
  256. {}
  257. ~ParallelBuiltFlatGraphManager() override = default;
  258. };
  259. class ParallelHierarchicalGraphManager :
  260. public artis::pdevs::GraphManager<common::DoubleTime,
  261. CellParameters,
  262. GridGraphManagerParameters>
  263. {
  264. public:
  265. enum submodels
  266. {
  267. S1_1 = 0, S1_2, S2_1, S2_2
  268. };
  269. ParallelHierarchicalGraphManager(
  270. common::Coordinator<common::DoubleTime> *coordinator,
  271. const CellParameters &parameters,
  272. const GridGraphManagerParameters &graph_parameters)
  273. :
  274. artis::pdevs::GraphManager<common::DoubleTime, CellParameters,
  275. GridGraphManagerParameters>(
  276. coordinator, parameters, graph_parameters)
  277. {
  278. // build coordinators (graphs)
  279. for (unsigned int i = 0; i < 2; ++i) {
  280. for (unsigned int j = 0; j < 2; ++j) {
  281. ParallelCoordinator *sub_coordinator = nullptr;
  282. std::ostringstream ss;
  283. ss << "S_" << (i + 1) << "_" << (j + 1);
  284. sub_coordinator = new ParallelCoordinator(ss.str(),
  285. parameters,
  286. {i * 5 + 1, (i + 1) * 5, j * 5 + 1, (j + 1) * 5,
  287. 1, 10, 1, 10});
  288. _coordinators.push_back(sub_coordinator);
  289. add_child(i, sub_coordinator);
  290. }
  291. }
  292. // builds internal connections (edges)
  293. // for (Connections::const_iterator it = parent_connections.begin();
  294. // it != parent_connections.end(); ++it) {
  295. // const Connection& connection = *it;
  296. // std::ostringstream ss_out;
  297. // std::ostringstream ss_in;
  298. //
  299. // ss_out << "out_" << connection.first.second;
  300. // ss_in << "in_" << connection.first.second;
  301. //
  302. // if (not exist_link(
  303. // _coordinators[connection.first.first - 1],
  304. // ss_out.str(),
  305. // _coordinators[connection.second.first - 1],
  306. // ss_in.str())) {
  307. // add_link(
  308. // _coordinators[connection.first.first - 1],
  309. // ss_out.str(),
  310. // _coordinators[connection.second.first - 1],
  311. // ss_in.str());
  312. // }
  313. // }
  314. }
  315. ~ParallelHierarchicalGraphManager() override
  316. {
  317. for (typename Coordinators::const_iterator it = _coordinators.begin();
  318. it != _coordinators.end(); ++it) {
  319. delete *it;
  320. }
  321. }
  322. void init()
  323. {
  324. std::for_each(_coordinators.begin(), _coordinators.end(),
  325. [this](ParallelCoordinator *coordinator) {
  326. coordinator->set_sender(
  327. (dynamic_cast< artis::pdevs::multithreading::Coordinator<
  328. artis::common::DoubleTime,
  329. ParallelHierarchicalGraphManager,
  330. CellParameters,
  331. GridGraphManagerParameters> *>(this->coordinator()))->get_sender());
  332. });
  333. }
  334. void start(common::DoubleTime::type t)
  335. {
  336. std::for_each(_coordinators.begin(), _coordinators.end(),
  337. [t](ParallelCoordinator *coordinator) {
  338. coordinator->get_sender().send(
  339. artis::pdevs::multithreading::start_message<
  340. artis::common::DoubleTime>(t));
  341. });
  342. }
  343. void transition(const common::Models<common::DoubleTime> &receivers,
  344. artis::common::DoubleTime::type t)
  345. {
  346. std::for_each(receivers.begin(), receivers.end(),
  347. [this, t](const common::Model<common::DoubleTime> *model) {
  348. if (not model->is_atomic()) {
  349. typename Coordinators::const_iterator itc =
  350. std::find(_coordinators.begin(),
  351. _coordinators.end(), model);
  352. (*itc)->get_sender().send(
  353. artis::pdevs::multithreading::transition_message<
  354. artis::common::DoubleTime>(t));
  355. }
  356. });
  357. }
  358. private:
  359. typedef artis::pdevs::multithreading::Coordinator<
  360. common::DoubleTime,
  361. ParallelBuiltFlatGraphManager,
  362. CellParameters,
  363. GridGraphManagerParameters
  364. > ParallelCoordinator;
  365. typedef std::vector<ParallelCoordinator *> Coordinators;
  366. Coordinators _coordinators;
  367. };
  368. }
  369. }
  370. }
  371. } // namespace artis tests multithreading lifegame
  372. #endif