graph_manager.hpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598
  1. /**
  2. * @file tests/boost_graph/graph_manager.hpp
  3. * @author The PARADEVS Development Team
  4. * See the AUTHORS or Authors.txt file
  5. */
  6. /*
  7. * PARADEVS - the multimodeling and simulation environment
  8. * This file is a part of the PARADEVS environment
  9. *
  10. * Copyright (C) 2013-2015 ULCO http://www.univ-litoral.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_BOOST_GRAPH_GRAPH_MANAGER_HPP
  26. #define __TESTS_BOOST_GRAPH_GRAPH_MANAGER_HPP 1
  27. #include <paradevs/common/scheduler/HeapScheduler.hpp>
  28. #include <paradevs/kernel/pdevs/Coordinator.hpp>
  29. #include <paradevs/kernel/pdevs/GraphManager.hpp>
  30. #include <paradevs/kernel/pdevs/Simulator.hpp>
  31. #include <paradevs/kernel/pdevs/multithreading/Coordinator.hpp>
  32. #include <tests/boost_graph/models.hpp>
  33. #include <tests/boost_graph/graph_partitioning.hpp>
  34. namespace paradevs { namespace tests { namespace boost_graph {
  35. struct GraphParameters
  36. {
  37. OrientedGraph _graph;
  38. InputEdges _input_edges;
  39. OutputEdges _output_edges;
  40. GraphParameters(const OrientedGraph& graph,
  41. const InputEdges& input_edges,
  42. const OutputEdges& output_edges) :
  43. _graph(graph), _input_edges(input_edges), _output_edges(output_edges)
  44. { }
  45. };
  46. template < class Parameters >
  47. class FlatGraphManager :
  48. public paradevs::pdevs::GraphManager < common::DoubleTime,
  49. Parameters >
  50. {
  51. public:
  52. FlatGraphManager(common::Coordinator < common::DoubleTime >* coordinator,
  53. const Parameters& parameters) :
  54. paradevs::pdevs::GraphManager < common::DoubleTime, Parameters >(
  55. coordinator, parameters)
  56. { }
  57. virtual ~FlatGraphManager()
  58. {
  59. for (typename TopSimulators::const_iterator it =
  60. _top_simulators.begin(); it != _top_simulators.end();
  61. ++it) {
  62. delete it->second;
  63. }
  64. for (typename NormalSimulators::const_iterator it =
  65. _normal_simulators.begin(); it != _normal_simulators.end();
  66. ++it) {
  67. delete it->second;
  68. }
  69. }
  70. void build_flat_graph(const OrientedGraph& g, const InputEdges& inputs)
  71. {
  72. OrientedGraph::vertex_iterator vertexIt, vertexEnd;
  73. boost::tie(vertexIt, vertexEnd) = boost::vertices(g);
  74. for (; vertexIt != vertexEnd; ++vertexIt) {
  75. std::ostringstream ss;
  76. ss << "a" << g[*vertexIt]._index;
  77. switch (g[*vertexIt]._type) {
  78. case 0 /*TOP_PIXEL*/:
  79. _top_simulators[g[*vertexIt]._index] =
  80. new pdevs::Simulator <
  81. common::DoubleTime, TopPixel,
  82. TopPixelParameters >(ss.str(), TopPixelParameters());
  83. _top_simulators[g[*vertexIt]._index]->add_out_port("out");
  84. FlatGraphManager < Parameters >::add_child(
  85. _top_simulators[g[*vertexIt]._index]);
  86. break;
  87. case 1 /*NORMAL_PIXEL*/:
  88. unsigned int n = 0;
  89. OrientedGraph::vertex_iterator vertexIt2, vertexEnd2;
  90. boost::tie(vertexIt2, vertexEnd2) = boost::vertices(g);
  91. for (; vertexIt2 != vertexEnd2; ++vertexIt2) {
  92. OrientedGraph::adjacency_iterator neighbourIt, neighbourEnd;
  93. boost::tie(neighbourIt, neighbourEnd) =
  94. boost::adjacent_vertices(*vertexIt2, g);
  95. for (; neighbourIt != neighbourEnd; ++neighbourIt) {
  96. if (g[*neighbourIt]._index == g[*vertexIt]._index) {
  97. ++n;
  98. }
  99. }
  100. }
  101. for (InputEdges::const_iterator it = inputs.begin();
  102. it != inputs.end(); ++it) {
  103. if (g[*vertexIt]._index == it->second) {
  104. ++n;
  105. }
  106. }
  107. _normal_simulators[g[*vertexIt]._index] =
  108. new pdevs::Simulator <
  109. common::DoubleTime, NormalPixel,
  110. NormalPixelParameters >(
  111. ss.str(), NormalPixelParameters(n));
  112. _normal_simulators[g[*vertexIt]._index]->add_in_port("in");
  113. _normal_simulators[g[*vertexIt]._index]->add_out_port("out");
  114. FlatGraphManager < Parameters >::add_child(
  115. _normal_simulators[g[*vertexIt]._index]);
  116. break;
  117. };
  118. }
  119. boost::tie(vertexIt, vertexEnd) = boost::vertices(g);
  120. for (; vertexIt != vertexEnd; ++vertexIt)
  121. {
  122. OrientedGraph::adjacency_iterator neighbourIt, neighbourEnd;
  123. boost::tie(neighbourIt, neighbourEnd) =
  124. boost::adjacent_vertices(*vertexIt, g);
  125. for (; neighbourIt != neighbourEnd; ++neighbourIt) {
  126. paradevs::common::Model < common::DoubleTime >* a = 0;
  127. paradevs::common::Model < common::DoubleTime >* b = 0;
  128. if (g[*vertexIt]._type == 0 /*TOP_PIXEL*/) {
  129. a = _top_simulators[g[*vertexIt]._index];
  130. } else {
  131. a = _normal_simulators[g[*vertexIt]._index];
  132. }
  133. if (g[*neighbourIt]._type == 0 /*TOP_PIXEL*/) {
  134. b = _top_simulators[g[*neighbourIt]._index];
  135. } else {
  136. b = _normal_simulators[g[*neighbourIt]._index];
  137. }
  138. FlatGraphManager < Parameters >::add_link(a, "out",
  139. b, "in");
  140. }
  141. }
  142. }
  143. protected:
  144. typedef std::map < int, pdevs::Simulator <
  145. common::DoubleTime,
  146. TopPixel,
  147. TopPixelParameters >* > TopSimulators;
  148. typedef std::map < int, pdevs::Simulator <
  149. common::DoubleTime,
  150. NormalPixel,
  151. NormalPixelParameters >* > NormalSimulators;
  152. TopSimulators _top_simulators;
  153. NormalSimulators _normal_simulators;
  154. };
  155. class BuiltFlatGraphManager :
  156. public FlatGraphManager < GraphParameters >
  157. {
  158. public:
  159. BuiltFlatGraphManager(
  160. common::Coordinator < common::DoubleTime >* coordinator,
  161. const GraphParameters& parameters) :
  162. FlatGraphManager < GraphParameters >(
  163. coordinator, parameters)
  164. {
  165. BuiltFlatGraphManager::build_flat_graph(
  166. parameters._graph, parameters._input_edges);
  167. // input
  168. // std::cout << "Input edges:" << std::endl;
  169. for (Edges::const_iterator it = parameters._input_edges.begin();
  170. it != parameters._input_edges.end(); ++it) {
  171. std::ostringstream ss_in;
  172. ss_in << "in_" << it->first;
  173. if (not coordinator->exist_in_port(ss_in.str())) {
  174. coordinator->add_in_port(ss_in.str());
  175. }
  176. BuiltFlatGraphManager::add_link(
  177. coordinator, ss_in.str(),
  178. BuiltFlatGraphManager::_normal_simulators[it->second], "in");
  179. // std::cout << "link = " << coordinator->get_name()
  180. // << "::" << ss_in.str() << " -> "
  181. // << BuiltFlatGraphManager <
  182. // SchedulerHandle >::_normal_simulators[it->second]
  183. // ->get_name() << "::" << "in" << std::endl;
  184. }
  185. // output
  186. // std::cout << "Output edges:" << std::endl;
  187. for (Edges::const_iterator it = parameters._output_edges.begin();
  188. it != parameters._output_edges.end(); ++it) {
  189. std::ostringstream ss_out;
  190. ss_out << "out_" << it->first;
  191. if (not coordinator->exist_out_port(ss_out.str())) {
  192. coordinator->add_out_port(ss_out.str());
  193. }
  194. if (BuiltFlatGraphManager::_normal_simulators.find(it->first) !=
  195. BuiltFlatGraphManager::_normal_simulators.end()) {
  196. if (not BuiltFlatGraphManager::exist_link(
  197. BuiltFlatGraphManager::_normal_simulators[it->first],
  198. "out", coordinator, ss_out.str())) {
  199. BuiltFlatGraphManager::add_link(
  200. BuiltFlatGraphManager::_normal_simulators[it->first],
  201. "out", coordinator, ss_out.str());
  202. // std::cout << "link = " << BuiltFlatGraphManager <
  203. // SchedulerHandle >::_normal_simulators[it->first]
  204. // ->get_name() << "::" << "out -> "
  205. // << coordinator->get_name()
  206. // << "::" << ss_out.str()
  207. // << std::endl;
  208. }
  209. } else {
  210. if (not BuiltFlatGraphManager::exist_link(
  211. BuiltFlatGraphManager::_top_simulators[it->first],
  212. "out", coordinator, ss_out.str())) {
  213. BuiltFlatGraphManager::add_link(
  214. BuiltFlatGraphManager::_top_simulators[it->first],
  215. "out", coordinator, ss_out.str());
  216. // std::cout << "link = " << BuiltFlatGraphManager <
  217. // SchedulerHandle >::_top_simulators[it->first]
  218. // ->get_name() << "::" << "out -> "
  219. // << coordinator->get_name()
  220. // << "::" << ss_out.str()
  221. // << std::endl;
  222. }
  223. }
  224. }
  225. }
  226. virtual ~BuiltFlatGraphManager()
  227. { }
  228. };
  229. class ParallelBuiltFlatGraphManager :
  230. public FlatGraphManager < GraphParameters >
  231. {
  232. public:
  233. ParallelBuiltFlatGraphManager(
  234. common::Coordinator < common::DoubleTime >* coordinator,
  235. const GraphParameters& parameters) :
  236. FlatGraphManager < GraphParameters >(
  237. coordinator, parameters)
  238. {
  239. ParallelBuiltFlatGraphManager::build_flat_graph(
  240. parameters._graph, parameters._input_edges);
  241. // input
  242. for (Edges::const_iterator it = parameters._input_edges.begin();
  243. it != parameters._input_edges.end(); ++it) {
  244. std::ostringstream ss_in;
  245. ss_in << "in_" << it->first;
  246. if (not coordinator->exist_in_port(ss_in.str())) {
  247. coordinator->add_in_port(ss_in.str());
  248. }
  249. ParallelBuiltFlatGraphManager::add_link(
  250. coordinator, ss_in.str(),
  251. ParallelBuiltFlatGraphManager::_normal_simulators[it->second],
  252. "in");
  253. }
  254. // output
  255. for (Edges::const_iterator it = parameters._output_edges.begin();
  256. it != parameters._output_edges.end(); ++it) {
  257. std::ostringstream ss_out;
  258. ss_out << "out_" << it->first;
  259. if (not coordinator->exist_out_port(ss_out.str())) {
  260. coordinator->add_out_port(ss_out.str());
  261. }
  262. if (not ParallelBuiltFlatGraphManager::exist_link(
  263. ParallelBuiltFlatGraphManager::_normal_simulators[it->first],
  264. "out",
  265. coordinator, ss_out.str())) {
  266. ParallelBuiltFlatGraphManager::add_link(
  267. ParallelBuiltFlatGraphManager::_normal_simulators[it->first], "out",
  268. coordinator, ss_out.str());
  269. }
  270. }
  271. }
  272. void init()
  273. { }
  274. void start(common::DoubleTime::type /* t */)
  275. { }
  276. void transition(
  277. const common::Models < common::DoubleTime >& /* receivers */,
  278. common::DoubleTime::type /* t */)
  279. { }
  280. virtual ~ParallelBuiltFlatGraphManager()
  281. { }
  282. };
  283. template < class GraphBuilder >
  284. class InBuildFlatGraphManager :
  285. public FlatGraphManager < paradevs::common::NoParameters >
  286. {
  287. public:
  288. InBuildFlatGraphManager(
  289. common::Coordinator < common::DoubleTime >* coordinator,
  290. const paradevs::common::NoParameters& parameters) :
  291. FlatGraphManager < paradevs::common::NoParameters >(
  292. coordinator, parameters)
  293. {
  294. GraphBuilder builder;
  295. OrientedGraphs graphs;
  296. InputEdgeList input_edges;
  297. OutputEdgeList output_edges;
  298. Connections parent_connections;
  299. builder.build(graphs, input_edges, output_edges, parent_connections);
  300. InBuildFlatGraphManager < GraphBuilder >::build_flat_graph(
  301. graphs.front(), InputEdges());
  302. }
  303. virtual ~InBuildFlatGraphManager()
  304. { }
  305. };
  306. struct PartitioningParameters
  307. {
  308. int cluster_number;
  309. std::string partitioning_method_name;
  310. int contraction_coef;
  311. bool contraction_coef_flag;
  312. GraphGenerator& generator;
  313. PartitioningParameters(int cn,
  314. const std::string& pmn,
  315. int cc, bool ccf,
  316. GraphGenerator& generator) :
  317. cluster_number(cn), partitioning_method_name(pmn),
  318. contraction_coef(cc), contraction_coef_flag(ccf),
  319. generator(generator)
  320. { }
  321. };
  322. template < class GraphBuilder >
  323. class HeapHierarchicalGraphManager :
  324. public paradevs::pdevs::GraphManager < common::DoubleTime,
  325. PartitioningParameters >
  326. {
  327. public:
  328. HeapHierarchicalGraphManager(
  329. common::Coordinator < common::DoubleTime >* coordinator,
  330. const PartitioningParameters& parameters) :
  331. paradevs::pdevs::GraphManager < common::DoubleTime,
  332. PartitioningParameters >(
  333. coordinator, parameters)
  334. {
  335. GraphBuilder graph_builder(parameters.cluster_number,
  336. parameters.partitioning_method_name,
  337. parameters.contraction_coef,
  338. parameters.contraction_coef_flag,
  339. parameters.generator);
  340. OrientedGraphs graphs;
  341. InputEdgeList input_edges;
  342. OutputEdgeList output_edges;
  343. Connections parent_connections;
  344. graph_builder.build(graphs, input_edges, output_edges,
  345. parent_connections);
  346. // build coordinators (graphs)
  347. for (unsigned int i = 0; i < graphs.size(); ++i) {
  348. Coordinator* coordinator = 0;
  349. std::ostringstream ss;
  350. ss << "S" << i;
  351. coordinator =
  352. new Coordinator(ss.str(), paradevs::common::NoParameters(),
  353. GraphParameters(graphs[i],
  354. input_edges[i],
  355. output_edges[i]));
  356. _coordinators.push_back(coordinator);
  357. HeapHierarchicalGraphManager < GraphBuilder >::add_child(
  358. coordinator);
  359. }
  360. // builds internal connections (edges)
  361. for (Connections::const_iterator it = parent_connections.begin();
  362. it != parent_connections.end(); ++it) {
  363. const Connection& connection = *it;
  364. std::ostringstream ss_out;
  365. std::ostringstream ss_in;
  366. ss_out << "out_" << connection.first.second;
  367. ss_in << "in_" << connection.first.second;
  368. if (not HeapHierarchicalGraphManager <
  369. GraphBuilder >::exist_link(
  370. _coordinators[connection.first.first - 1],
  371. ss_out.str(),
  372. _coordinators[connection.second.first - 1],
  373. ss_in.str())) {
  374. HeapHierarchicalGraphManager <
  375. GraphBuilder >::add_link(
  376. _coordinators[connection.first.first - 1],
  377. ss_out.str(),
  378. _coordinators[connection.second.first - 1],
  379. ss_in.str());
  380. }
  381. }
  382. }
  383. virtual ~HeapHierarchicalGraphManager()
  384. {
  385. for (typename Coordinators::const_iterator it = _coordinators.begin();
  386. it != _coordinators.end(); ++it) {
  387. delete *it;
  388. }
  389. }
  390. private:
  391. typedef paradevs::pdevs::Coordinator <
  392. common::DoubleTime,
  393. BuiltFlatGraphManager,
  394. common::NoParameters,
  395. GraphParameters
  396. > Coordinator;
  397. typedef std::vector < Coordinator* > Coordinators;
  398. Coordinators _coordinators;
  399. };
  400. template < class GraphBuilder >
  401. class ParallelHeapHierarchicalGraphManager :
  402. public paradevs::pdevs::GraphManager < common::DoubleTime,
  403. PartitioningParameters >
  404. {
  405. public:
  406. ParallelHeapHierarchicalGraphManager(
  407. common::Coordinator < common::DoubleTime >* coordinator,
  408. const PartitioningParameters& parameters) :
  409. paradevs::pdevs::GraphManager < common::DoubleTime,
  410. PartitioningParameters >(
  411. coordinator, parameters)
  412. {
  413. GraphBuilder graph_builder(parameters.cluster_number,
  414. parameters.partitioning_method_name,
  415. parameters.contraction_coef,
  416. parameters.contraction_coef_flag,
  417. parameters.generator);
  418. OrientedGraphs graphs;
  419. InputEdgeList input_edges;
  420. OutputEdgeList output_edges;
  421. Connections parent_connections;
  422. graph_builder.build(graphs, input_edges, output_edges,
  423. parent_connections);
  424. // build coordinators (graphs)
  425. for (unsigned int i = 0; i < graphs.size(); ++i) {
  426. ParallelCoordinator* coordinator = 0;
  427. std::ostringstream ss;
  428. ss << "S" << i;
  429. coordinator =
  430. new ParallelCoordinator(ss.str(),
  431. paradevs::common::NoParameters(),
  432. GraphParameters(graphs[i],
  433. input_edges[i],
  434. output_edges[i]));
  435. _coordinators.push_back(coordinator);
  436. ParallelHeapHierarchicalGraphManager < GraphBuilder >::add_child(
  437. coordinator);
  438. }
  439. // builds internal connections (edges)
  440. for (Connections::const_iterator it = parent_connections.begin();
  441. it != parent_connections.end(); ++it) {
  442. const Connection& connection = *it;
  443. std::ostringstream ss_out;
  444. std::ostringstream ss_in;
  445. ss_out << "out_" << connection.first.second;
  446. ss_in << "in_" << connection.first.second;
  447. if (not ParallelHeapHierarchicalGraphManager <
  448. GraphBuilder >::exist_link(
  449. _coordinators[connection.first.first - 1],
  450. ss_out.str(),
  451. _coordinators[connection.second.first - 1],
  452. ss_in.str())) {
  453. ParallelHeapHierarchicalGraphManager <
  454. GraphBuilder >::add_link(
  455. _coordinators[connection.first.first - 1],
  456. ss_out.str(),
  457. _coordinators[connection.second.first - 1],
  458. ss_in.str());
  459. }
  460. }
  461. }
  462. virtual ~ParallelHeapHierarchicalGraphManager()
  463. {
  464. for (typename Coordinators::const_iterator it = _coordinators.begin();
  465. it != _coordinators.end(); ++it) {
  466. delete *it;
  467. }
  468. }
  469. void init()
  470. {
  471. for (typename Coordinators::const_iterator it = _coordinators.begin();
  472. it != _coordinators.end(); ++it) {
  473. (*it)->set_sender(
  474. dynamic_cast < paradevs::pdevs::multithreading::Coordinator <
  475. common::DoubleTime,
  476. ParallelHeapHierarchicalGraphManager <
  477. PartitioningGraphBuilder >,
  478. paradevs::common::NoParameters,
  479. PartitioningParameters >*
  480. >(ParallelHeapHierarchicalGraphManager < GraphBuilder >::
  481. get_coordinator())->get_sender());
  482. }
  483. }
  484. void start(common::DoubleTime::type t)
  485. {
  486. for (typename Coordinators::const_iterator it = _coordinators.begin();
  487. it != _coordinators.end(); ++it) {
  488. (*it)->get_sender().send(
  489. paradevs::pdevs::multithreading::start_message <
  490. paradevs::common::DoubleTime >(t));
  491. }
  492. }
  493. void transition(const common::Models < common::DoubleTime >& receivers,
  494. paradevs::common::DoubleTime::type t)
  495. {
  496. common::Models < common::DoubleTime >::const_iterator it =
  497. receivers.begin();
  498. while (it != receivers.end()) {
  499. if (not (*it)->is_atomic()) {
  500. typename Coordinators::const_iterator itc =
  501. std::find(_coordinators.begin(), _coordinators.end(), *it);
  502. (*itc)->get_sender().send(
  503. paradevs::pdevs::multithreading::transition_message <
  504. paradevs::common::DoubleTime >(t));
  505. }
  506. ++it;
  507. }
  508. }
  509. private:
  510. typedef paradevs::pdevs::multithreading::Coordinator <
  511. common::DoubleTime,
  512. ParallelBuiltFlatGraphManager,
  513. common::NoParameters,
  514. GraphParameters
  515. > ParallelCoordinator;
  516. typedef std::vector < ParallelCoordinator* > Coordinators;
  517. Coordinators _coordinators;
  518. };
  519. } } } // namespace paradevs tests boost_graph
  520. #endif