hierarchical_graph_manager.hpp 43 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973
  1. /**
  2. * @file tests/boost_graph/hierarchical_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_HIERARCHICAL_GRAPH_MANAGER_HPP
  26. #define __TESTS_BOOST_GRAPH_HIERARCHICAL_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 <tests/boost_graph/models.hpp>
  32. #include <tests/boost_graph/graph_manager.hpp>
  33. namespace paradevs { namespace tests { namespace boost_graph {
  34. struct RootHierarchicalParameters
  35. {
  36. int level_number;
  37. GraphGenerator& generator;
  38. RootHierarchicalParameters(int level, GraphGenerator& generator) :
  39. level_number(level), generator(generator)
  40. { }
  41. };
  42. struct HierarchicalParameters
  43. {
  44. int index;
  45. int level_number;
  46. std::map < int, int >& cluster;
  47. OrientedGraph& graph;
  48. HierarchicalParameters(int index,
  49. int level,
  50. std::map < int, int >& cluster,
  51. OrientedGraph& graph) :
  52. index(index), level_number(level), cluster(cluster), graph(graph)
  53. { }
  54. };
  55. template < class SchedulerHandle >
  56. class LeafGraphManager :
  57. public paradevs::pdevs::GraphManager < common::DoubleTime,
  58. SchedulerHandle,
  59. HierarchicalParameters >
  60. {
  61. public:
  62. LeafGraphManager(
  63. common::Coordinator < common::DoubleTime,
  64. SchedulerHandle >* coordinator,
  65. const HierarchicalParameters& parameters) :
  66. paradevs::pdevs::GraphManager < common::DoubleTime, SchedulerHandle,
  67. HierarchicalParameters >(
  68. coordinator, parameters)
  69. {
  70. build_flat_graph(parameters.index, parameters.graph,
  71. parameters.cluster);
  72. // input
  73. {
  74. OrientedGraph::vertex_iterator vertexIt, vertexEnd;
  75. boost::tie(vertexIt, vertexEnd) = boost::vertices(parameters.graph);
  76. for (; vertexIt != vertexEnd; ++vertexIt) {
  77. if (parameters.cluster.at(parameters.graph[*vertexIt]._index) !=
  78. parameters.index) {
  79. OrientedGraph::adjacency_iterator neighbourIt, neighbourEnd;
  80. boost::tie(neighbourIt, neighbourEnd) =
  81. boost::adjacent_vertices(*vertexIt, parameters.graph);
  82. for (; neighbourIt != neighbourEnd; ++neighbourIt) {
  83. std::map < int, int >::const_iterator it =
  84. parameters.cluster.find(
  85. parameters.graph[*neighbourIt]._index);
  86. if (it != parameters.cluster.end() and
  87. it->second == parameters.index) {
  88. std::ostringstream ss_in;
  89. ss_in << "in_"
  90. << parameters.graph[*vertexIt]._index;
  91. if (not coordinator->exist_in_port(ss_in.str())) {
  92. coordinator->add_in_port(ss_in.str());
  93. }
  94. if (not LeafGraphManager <
  95. SchedulerHandle >::exist_link(
  96. coordinator, ss_in.str(),
  97. _normal_simulators[it->second], "in")) {
  98. LeafGraphManager < SchedulerHandle>::add_link(
  99. coordinator, ss_in.str(),
  100. _normal_simulators[it->second], "in");
  101. }
  102. std::cout << "DEBUG: "
  103. << parameters.graph[*neighbourIt]._index
  104. << " input -> "
  105. << parameters.graph[*vertexIt]._index
  106. << " "
  107. << parameters.index << ":" << ss_in.str()
  108. << " -> "
  109. << parameters.graph[*neighbourIt]._index
  110. << ":in"
  111. << std::endl;
  112. }
  113. }
  114. }
  115. }
  116. }
  117. // output
  118. {
  119. OrientedGraph::vertex_iterator vertexIt, vertexEnd;
  120. boost::tie(vertexIt, vertexEnd) = boost::vertices(parameters.graph);
  121. for (; vertexIt != vertexEnd; ++vertexIt) {
  122. if (parameters.cluster.at(parameters.graph[*vertexIt]._index) ==
  123. parameters.index) {
  124. OrientedGraph::adjacency_iterator neighbourIt, neighbourEnd;
  125. boost::tie(neighbourIt, neighbourEnd) =
  126. boost::adjacent_vertices(*vertexIt, parameters.graph);
  127. for (; neighbourIt != neighbourEnd; ++neighbourIt) {
  128. std::map < int, int >::const_iterator it =
  129. parameters.cluster.find(
  130. parameters.graph[*neighbourIt]._index);
  131. if (it != parameters.cluster.end() and
  132. it->second != parameters.index) {
  133. std::ostringstream ss_out;
  134. ss_out << "out_"
  135. << parameters.graph[*vertexIt]._index;
  136. if (not coordinator->exist_out_port(ss_out.str())) {
  137. coordinator->add_out_port(ss_out.str());
  138. }
  139. if (_normal_simulators.find(it->first) !=
  140. _normal_simulators.end()) {
  141. if (not LeafGraphManager <
  142. SchedulerHandle >::exist_link(
  143. _normal_simulators[it->first],
  144. "out", coordinator, ss_out.str())) {
  145. LeafGraphManager <
  146. SchedulerHandle >::add_link(
  147. _normal_simulators[it->first],
  148. "out", coordinator, ss_out.str());
  149. }
  150. std::cout << "DEBUG: "
  151. << parameters.graph[*vertexIt]._index
  152. << " output -> "
  153. << parameters.graph[*neighbourIt]._index
  154. << " "
  155. << parameters.graph[*vertexIt]._index
  156. << ":out -> "
  157. << parameters.index << ":"
  158. << ss_out.str()
  159. << std::endl;
  160. } else {
  161. if (not LeafGraphManager <
  162. SchedulerHandle >::exist_link(
  163. _top_simulators[it->first],
  164. "out", coordinator, ss_out.str())) {
  165. LeafGraphManager <
  166. SchedulerHandle>::add_link(
  167. _top_simulators[it->first],
  168. "out", coordinator, ss_out.str());
  169. }
  170. std::cout << "DEBUG: "
  171. << parameters.graph[*vertexIt]._index
  172. << " output -> "
  173. << parameters.graph[*neighbourIt]._index
  174. << " "
  175. << parameters.graph[*vertexIt]._index
  176. << ":out -> "
  177. << parameters.index << ":"
  178. << ss_out.str()
  179. << std::endl;
  180. }
  181. }
  182. }
  183. }
  184. }
  185. }
  186. }
  187. virtual ~LeafGraphManager()
  188. {
  189. for (typename TopSimulators::const_iterator it =
  190. _top_simulators.begin(); it != _top_simulators.end();
  191. ++it) {
  192. delete it->second;
  193. }
  194. for (typename NormalSimulators::const_iterator it =
  195. _normal_simulators.begin(); it != _normal_simulators.end();
  196. ++it) {
  197. delete it->second;
  198. }
  199. }
  200. private:
  201. void build_flat_graph(int index, const OrientedGraph& g,
  202. const std::map < int, int >& cluster)
  203. {
  204. OrientedGraph::vertex_iterator vertexIt, vertexEnd;
  205. boost::tie(vertexIt, vertexEnd) = boost::vertices(g);
  206. for (; vertexIt != vertexEnd; ++vertexIt) {
  207. std::ostringstream ss;
  208. if (cluster.at(g[*vertexIt]._index) == index) {
  209. ss << "a" << g[*vertexIt]._index;
  210. std::cout << "DEBUG: " << g[*vertexIt]._index << " => "
  211. << index << std::endl;
  212. switch (g[*vertexIt]._type) {
  213. case TOP_PIXEL:
  214. _top_simulators[g[*vertexIt]._index] =
  215. new pdevs::Simulator <
  216. common::DoubleTime, TopPixel < SchedulerHandle >,
  217. SchedulerHandle,
  218. TopPixelParameters >(ss.str(),
  219. TopPixelParameters());
  220. _top_simulators[g[*vertexIt]._index]->add_out_port("out");
  221. LeafGraphManager < SchedulerHandle >::add_child(
  222. _top_simulators[g[*vertexIt]._index]);
  223. break;
  224. case NORMAL_PIXEL:
  225. unsigned int n = 0;
  226. OrientedGraph::vertex_iterator vertexIt2, vertexEnd2;
  227. std::cout << "DEBUG: " << g[*vertexIt]._index << " = [ ";
  228. boost::tie(vertexIt2, vertexEnd2) = boost::vertices(g);
  229. for (; vertexIt2 != vertexEnd2; ++vertexIt2) {
  230. OrientedGraph::adjacency_iterator neighbourIt,
  231. neighbourEnd;
  232. boost::tie(neighbourIt, neighbourEnd) =
  233. boost::adjacent_vertices(*vertexIt2, g);
  234. for (; neighbourIt != neighbourEnd; ++neighbourIt) {
  235. if (g[*neighbourIt]._index == g[*vertexIt]._index) {
  236. ++n;
  237. std::cout << g[*vertexIt2]._index << " ";
  238. }
  239. }
  240. }
  241. std::cout << "]" << std::endl;
  242. std::cout << "DEBUG: " << g[*vertexIt]._index << " => N = "
  243. << n << std::endl;
  244. _normal_simulators[g[*vertexIt]._index] =
  245. new pdevs::Simulator <
  246. common::DoubleTime, NormalPixel < SchedulerHandle >,
  247. SchedulerHandle, NormalPixelParameters >(
  248. ss.str(), NormalPixelParameters(n));
  249. _normal_simulators[g[*vertexIt]._index]->add_in_port("in");
  250. _normal_simulators[g[*vertexIt]._index]->add_out_port("out");
  251. LeafGraphManager < SchedulerHandle >::add_child(
  252. _normal_simulators[g[*vertexIt]._index]);
  253. break;
  254. };
  255. }
  256. }
  257. boost::tie(vertexIt, vertexEnd) = boost::vertices(g);
  258. for (; vertexIt != vertexEnd; ++vertexIt)
  259. {
  260. if (cluster.at(g[*vertexIt]._index) == index) {
  261. OrientedGraph::adjacency_iterator neighbourIt, neighbourEnd;
  262. std::cout << "DEBUG: " << g[*vertexIt]._index << " = [ ";
  263. boost::tie(neighbourIt, neighbourEnd) =
  264. boost::adjacent_vertices(*vertexIt, g);
  265. for (; neighbourIt != neighbourEnd; ++neighbourIt) {
  266. std::map < int, int >::const_iterator it =
  267. cluster.find(g[*neighbourIt]._index);
  268. std::cout << g[*neighbourIt]._index << "/"
  269. << it->second << " ";
  270. }
  271. std::cout << "]" << std::endl;
  272. boost::tie(neighbourIt, neighbourEnd) =
  273. boost::adjacent_vertices(*vertexIt, g);
  274. for (; neighbourIt != neighbourEnd; ++neighbourIt) {
  275. std::map < int, int >::const_iterator it =
  276. cluster.find(g[*neighbourIt]._index);
  277. if (it != cluster.end() and it->second == index) {
  278. paradevs::common::Model < common::DoubleTime,
  279. SchedulerHandle >* a = 0;
  280. paradevs::common::Model < common::DoubleTime,
  281. SchedulerHandle >* b = 0;
  282. if (g[*vertexIt]._type == TOP_PIXEL) {
  283. a = _top_simulators[g[*vertexIt]._index];
  284. } else {
  285. a = _normal_simulators[g[*vertexIt]._index];
  286. }
  287. if (g[*neighbourIt]._type == TOP_PIXEL) {
  288. b = _top_simulators[g[*neighbourIt]._index];
  289. } else {
  290. b = _normal_simulators[g[*neighbourIt]._index];
  291. }
  292. if (LeafGraphManager <
  293. SchedulerHandle >::exist_link(a, "out",
  294. b, "in")) {
  295. std::cout << "== BUG == : "
  296. << g[*vertexIt]._index
  297. << ":out -> "
  298. << g[*neighbourIt]._index
  299. << ":in"
  300. << std::endl;
  301. }
  302. std::cout << "DEBUG: "
  303. << g[*vertexIt]._index
  304. << " internal -> "
  305. << g[*neighbourIt]._index
  306. << " "
  307. << g[*vertexIt]._index
  308. << ":out -> "
  309. << g[*neighbourIt]._index
  310. << ":in"
  311. << std::endl;
  312. LeafGraphManager < SchedulerHandle >::add_link(
  313. a, "out", b, "in");
  314. }
  315. }
  316. }
  317. }
  318. }
  319. typedef std::map < int, pdevs::Simulator <
  320. common::DoubleTime,
  321. TopPixel < SchedulerHandle >,
  322. SchedulerHandle,
  323. TopPixelParameters >* > TopSimulators;
  324. typedef std::map < int, pdevs::Simulator <
  325. common::DoubleTime,
  326. NormalPixel < SchedulerHandle >,
  327. SchedulerHandle,
  328. NormalPixelParameters >* > NormalSimulators;
  329. TopSimulators _top_simulators;
  330. NormalSimulators _normal_simulators;
  331. };
  332. template < class SchedulerHandle >
  333. class HierarchicalGraphManager :
  334. public paradevs::pdevs::GraphManager < common::DoubleTime,
  335. SchedulerHandle,
  336. HierarchicalParameters >
  337. {
  338. public:
  339. HierarchicalGraphManager(
  340. common::Coordinator < common::DoubleTime,
  341. SchedulerHandle >* coordinator,
  342. const HierarchicalParameters& parameters) :
  343. paradevs::pdevs::GraphManager < common::DoubleTime, SchedulerHandle,
  344. HierarchicalParameters >(
  345. coordinator, parameters)
  346. {
  347. std::map < int, int > cluster = parameters.cluster;
  348. int n1 = 1;
  349. int n2 = 0;
  350. for (int i = 1; i <= parameters.level_number; ++i) {
  351. n2 += 1 << i;
  352. }
  353. n2 >>= 1;
  354. n2++;
  355. OrientedGraph::vertex_iterator vertexIt, vertexEnd;
  356. boost::tie(vertexIt, vertexEnd) = boost::vertices(parameters.graph);
  357. for (; vertexIt != vertexEnd; ++vertexIt) {
  358. if (parameters.index ==
  359. parameters.cluster[parameters.graph[*vertexIt]._index]) {
  360. if (rand() % 2) {
  361. parameters.cluster[parameters.graph[*vertexIt]._index] += n1;
  362. } else {
  363. parameters.cluster[parameters.graph[*vertexIt]._index] += n2;
  364. }
  365. }
  366. }
  367. std::map < int, int > copy_cluster = parameters.cluster;
  368. // build coordinators
  369. for (unsigned int i = 0; i < 2; ++i) {
  370. unsigned index = parameters.index + ((i == 0) ? n1 : n2);
  371. if (parameters.level_number > 1) {
  372. Coordinator* coordinator = 0;
  373. std::ostringstream ss;
  374. ss << "S" << index;
  375. coordinator =
  376. new Coordinator(ss.str(),
  377. paradevs::common::NoParameters(),
  378. HierarchicalParameters(
  379. index,
  380. parameters.level_number - 1,
  381. parameters.cluster,
  382. parameters.graph));
  383. _coordinators.push_back(coordinator);
  384. HierarchicalGraphManager < SchedulerHandle >::add_child(
  385. coordinator);
  386. } else {
  387. LeafCoordinator* coordinator = 0;
  388. std::ostringstream ss;
  389. ss << "S" << index;
  390. coordinator =
  391. new LeafCoordinator(ss.str(),
  392. paradevs::common::NoParameters(),
  393. HierarchicalParameters(
  394. index,
  395. -1,
  396. parameters.cluster,
  397. parameters.graph));
  398. _leaf_coordinators.push_back(coordinator);
  399. HierarchicalGraphManager < SchedulerHandle >::add_child(
  400. coordinator);
  401. }
  402. }
  403. // build ports and connections
  404. // input
  405. for (unsigned int i = 0; i < 2; ++i) {
  406. unsigned index = (i == 0) ? n1 : n2;
  407. OrientedGraph::vertex_iterator vertexIt, vertexEnd;
  408. boost::tie(vertexIt, vertexEnd) = boost::vertices(parameters.graph);
  409. for (; vertexIt != vertexEnd; ++vertexIt) {
  410. if (cluster.at(parameters.graph[*vertexIt]._index) !=
  411. parameters.index) {
  412. OrientedGraph::adjacency_iterator neighbourIt, neighbourEnd;
  413. boost::tie(neighbourIt, neighbourEnd) =
  414. boost::adjacent_vertices(*vertexIt, parameters.graph);
  415. for (; neighbourIt != neighbourEnd; ++neighbourIt) {
  416. std::map < int, int >::const_iterator it =
  417. copy_cluster.find(
  418. parameters.graph[*neighbourIt]._index);
  419. if (it != copy_cluster.end() and
  420. it->second == parameters.index + index) {
  421. std::ostringstream ss_in_a;
  422. std::ostringstream ss_in_b;
  423. ss_in_a << "in_"
  424. << parameters.graph[*vertexIt]._index;
  425. ss_in_b << "in_"
  426. << parameters.graph[*vertexIt]._index;
  427. std::cout << "DEBUG: ="
  428. << parameters.index
  429. << " "
  430. << (parameters.index + index)
  431. << " "
  432. << parameters.graph[*vertexIt]._index
  433. << " "
  434. << parameters.index << ":"
  435. << ss_in_a.str() << " -> "
  436. << (parameters.index + index) << ":"
  437. << ss_in_b.str()
  438. << std::endl;
  439. if (not coordinator->exist_in_port(
  440. ss_in_a.str())) {
  441. coordinator->add_in_port(
  442. ss_in_a.str());
  443. }
  444. if (parameters.level_number > 1) {
  445. if (not _coordinators[i]->exist_in_port(
  446. ss_in_b.str())) {
  447. _coordinators[i]->add_in_port(
  448. ss_in_b.str());
  449. }
  450. if (not HierarchicalGraphManager <
  451. SchedulerHandle >::exist_link(
  452. coordinator, ss_in_a.str(),
  453. _coordinators[i], ss_in_b.str())) {
  454. HierarchicalGraphManager <
  455. SchedulerHandle >::add_link(
  456. coordinator, ss_in_a.str(),
  457. _coordinators[i], ss_in_b.str());
  458. }
  459. } else {
  460. if (not _leaf_coordinators[i]->exist_in_port(
  461. ss_in_b.str())) {
  462. _leaf_coordinators[i]->add_in_port(
  463. ss_in_b.str());
  464. }
  465. if (not HierarchicalGraphManager <
  466. SchedulerHandle >::exist_link(
  467. coordinator, ss_in_a.str(),
  468. _leaf_coordinators[i], ss_in_b.str())) {
  469. HierarchicalGraphManager <
  470. SchedulerHandle >::add_link(
  471. coordinator, ss_in_a.str(),
  472. _leaf_coordinators[i], ss_in_b.str());
  473. }
  474. }
  475. }
  476. }
  477. }
  478. }
  479. }
  480. // output
  481. for (unsigned int i = 0; i < 2; ++i) {
  482. unsigned index = (i == 0) ? n1 : n2;
  483. OrientedGraph::vertex_iterator vertexIt, vertexEnd;
  484. boost::tie(vertexIt, vertexEnd) = boost::vertices(parameters.graph);
  485. for (; vertexIt != vertexEnd; ++vertexIt) {
  486. if (copy_cluster.at(parameters.graph[*vertexIt]._index) ==
  487. parameters.index + index) {
  488. OrientedGraph::adjacency_iterator neighbourIt, neighbourEnd;
  489. boost::tie(neighbourIt, neighbourEnd) =
  490. boost::adjacent_vertices(*vertexIt, parameters.graph);
  491. for (; neighbourIt != neighbourEnd; ++neighbourIt) {
  492. std::map < int, int >::const_iterator it =
  493. cluster.find(
  494. parameters.graph[*neighbourIt]._index);
  495. if (it != cluster.end() and
  496. it->second != parameters.index) {
  497. std::ostringstream ss_out_a;
  498. std::ostringstream ss_out_b;
  499. ss_out_a << "out_"
  500. << parameters.graph[*vertexIt]._index;
  501. ss_out_b << "out_"
  502. << parameters.graph[*vertexIt]._index;
  503. if (not coordinator->exist_out_port(
  504. ss_out_b.str())) {
  505. coordinator->add_out_port(
  506. ss_out_b.str());
  507. }
  508. std::cout << "DEBUG: ="
  509. << parameters.index
  510. << " "
  511. << (parameters.index + index)
  512. << " "
  513. << parameters.graph[*vertexIt]._index
  514. << " "
  515. << parameters.graph[*neighbourIt]._index
  516. << " "
  517. << (parameters.index + index) << ":"
  518. << ss_out_a.str() << " -> "
  519. << parameters.index << ":"
  520. << ss_out_b.str()
  521. << std::endl;
  522. if (parameters.level_number > 1) {
  523. if (not _coordinators[i]->exist_out_port(
  524. ss_out_a.str())) {
  525. _coordinators[i]->add_out_port(
  526. ss_out_a.str());
  527. }
  528. if (not HierarchicalGraphManager <
  529. SchedulerHandle >::exist_link(
  530. _coordinators[i],
  531. ss_out_a.str(),
  532. coordinator,
  533. ss_out_b.str())) {
  534. HierarchicalGraphManager <
  535. SchedulerHandle >::add_link(
  536. _coordinators[i],
  537. ss_out_a.str(),
  538. coordinator,
  539. ss_out_b.str());
  540. }
  541. } else {
  542. if (not _leaf_coordinators[i]->exist_out_port(
  543. ss_out_a.str())) {
  544. _leaf_coordinators[i]->add_out_port(
  545. ss_out_a.str());
  546. }
  547. if (not HierarchicalGraphManager <
  548. SchedulerHandle >::exist_link(
  549. _leaf_coordinators[i],
  550. ss_out_a.str(),
  551. coordinator,
  552. ss_out_b.str())) {
  553. HierarchicalGraphManager <
  554. SchedulerHandle >::add_link(
  555. _leaf_coordinators[i],
  556. ss_out_a.str(),
  557. coordinator,
  558. ss_out_b.str());
  559. }
  560. }
  561. }
  562. }
  563. }
  564. }
  565. }
  566. // internal
  567. for (unsigned int i = 0; i < 2; ++i) {
  568. unsigned index1 = (i == 0) ? n1 : n2;
  569. unsigned index2 = (i == 0) ? n2 : n1;
  570. OrientedGraph::vertex_iterator vertexIt, vertexEnd;
  571. boost::tie(vertexIt, vertexEnd) = boost::vertices(parameters.graph);
  572. for (; vertexIt != vertexEnd; ++vertexIt) {
  573. if (copy_cluster.at(parameters.graph[*vertexIt]._index) ==
  574. parameters.index + index1) {
  575. OrientedGraph::adjacency_iterator neighbourIt, neighbourEnd;
  576. boost::tie(neighbourIt, neighbourEnd) =
  577. boost::adjacent_vertices(*vertexIt, parameters.graph);
  578. for (; neighbourIt != neighbourEnd; ++neighbourIt) {
  579. std::map < int, int >::const_iterator it =
  580. copy_cluster.find(
  581. parameters.graph[*neighbourIt]._index);
  582. if (it != copy_cluster.end() and
  583. it->second == parameters.index + index2) {
  584. std::ostringstream ss_out_a;
  585. std::ostringstream ss_out_b;
  586. ss_out_a << "out_"
  587. << parameters.graph[*vertexIt]._index;
  588. ss_out_b << "in_"
  589. << parameters.graph[*vertexIt]._index;
  590. std::cout << "DEBUG: ="
  591. << parameters.index
  592. << " "
  593. << (parameters.index + index1)
  594. << " "
  595. << parameters.graph[*vertexIt]._index
  596. << " "
  597. << (parameters.index + index2)
  598. << " "
  599. << parameters.graph[*neighbourIt]._index
  600. << " "
  601. << (parameters.index + index1) << ":"
  602. << ss_out_a.str()
  603. << " -> "
  604. << (parameters.index + index2) << ":"
  605. << ss_out_b.str()
  606. << std::endl;
  607. if (parameters.level_number > 1) {
  608. if (not _coordinators[i]->exist_out_port(
  609. ss_out_a.str())) {
  610. _coordinators[i]->add_out_port(
  611. ss_out_a.str());
  612. }
  613. if (not _coordinators[(i==0)?1:0]->exist_in_port(
  614. ss_out_b.str())) {
  615. _coordinators[(i==0)?1:0]->add_in_port(
  616. ss_out_b.str());
  617. }
  618. if (not HierarchicalGraphManager <
  619. SchedulerHandle >::exist_link(
  620. _coordinators[i],
  621. ss_out_a.str(),
  622. _coordinators[(i==0)?1:0],
  623. ss_out_b.str())) {
  624. HierarchicalGraphManager <
  625. SchedulerHandle >::add_link(
  626. _coordinators[i],
  627. ss_out_a.str(),
  628. _coordinators[(i==0)?1:0],
  629. ss_out_b.str());
  630. }
  631. } else {
  632. if (not _leaf_coordinators[i]->exist_out_port(
  633. ss_out_a.str())) {
  634. _leaf_coordinators[i]->add_out_port(
  635. ss_out_a.str());
  636. }
  637. if (not _leaf_coordinators[(i==0)?1:0]->exist_in_port(
  638. ss_out_b.str())) {
  639. _leaf_coordinators[(i==0)?1:0]->add_in_port(
  640. ss_out_b.str());
  641. }
  642. if (not HierarchicalGraphManager <
  643. SchedulerHandle >::exist_link(
  644. _leaf_coordinators[i],
  645. ss_out_a.str(),
  646. _leaf_coordinators[(i==0)?1:0],
  647. ss_out_b.str())) {
  648. HierarchicalGraphManager <
  649. SchedulerHandle >::add_link(
  650. _leaf_coordinators[i],
  651. ss_out_a.str(),
  652. _leaf_coordinators[(i==0)?1:0],
  653. ss_out_b.str());
  654. }
  655. }
  656. }
  657. }
  658. }
  659. }
  660. }
  661. }
  662. virtual ~HierarchicalGraphManager()
  663. {
  664. for (typename Coordinators::const_iterator it = _coordinators.begin();
  665. it != _coordinators.end(); ++it) {
  666. delete *it;
  667. }
  668. }
  669. private:
  670. // INTERNODE
  671. typedef paradevs::pdevs::Coordinator <
  672. common::DoubleTime,
  673. SchedulerType,
  674. SchedulerHandle,
  675. HierarchicalGraphManager < SchedulerHandle >,
  676. common::NoParameters,
  677. HierarchicalParameters > Coordinator;
  678. typedef std::vector < Coordinator* > Coordinators;
  679. Coordinators _coordinators;
  680. // LEAF
  681. typedef paradevs::pdevs::Coordinator <
  682. common::DoubleTime,
  683. SchedulerType,
  684. SchedulerHandle,
  685. LeafGraphManager < SchedulerHandle >,
  686. common::NoParameters,
  687. HierarchicalParameters > LeafCoordinator;
  688. typedef std::vector < LeafCoordinator* > LeafCoordinators;
  689. LeafCoordinators _leaf_coordinators;
  690. };
  691. template < class SchedulerHandle, class GraphBuilder >
  692. class RootHierarchicalGraphManager :
  693. public paradevs::pdevs::GraphManager < common::DoubleTime,
  694. SchedulerHandle,
  695. RootHierarchicalParameters >
  696. {
  697. public:
  698. RootHierarchicalGraphManager(
  699. common::Coordinator < common::DoubleTime,
  700. SchedulerHandle >* coordinator,
  701. const RootHierarchicalParameters& parameters) :
  702. paradevs::pdevs::GraphManager < common::DoubleTime, SchedulerHandle,
  703. RootHierarchicalParameters >(
  704. coordinator, parameters)
  705. {
  706. GraphBuilder graph_builder(parameters.generator);
  707. OrientedGraph graph;
  708. graph_builder.build(graph);
  709. if (parameters.level_number == 1) {
  710. std::map < int, int > cluster;
  711. OrientedGraph::vertex_iterator vertexIt, vertexEnd;
  712. boost::tie(vertexIt, vertexEnd) = boost::vertices(graph);
  713. for (; vertexIt != vertexEnd; ++vertexIt) {
  714. cluster[graph[*vertexIt]._index] = 1;
  715. }
  716. {
  717. LeafCoordinator* coordinator = 0;
  718. coordinator =
  719. new LeafCoordinator("S1", paradevs::common::NoParameters(),
  720. HierarchicalParameters(
  721. 1,
  722. -1,
  723. cluster,
  724. graph));
  725. RootHierarchicalGraphManager < SchedulerHandle,
  726. GraphBuilder >::add_child(
  727. coordinator);
  728. }
  729. } else {
  730. int n1 = 1;
  731. int n2 = 0;
  732. for (int i = 1; i <= parameters.level_number; ++i) {
  733. n2 += 1 << i;
  734. }
  735. n2 >>= 1;
  736. n2++;
  737. std::map < int, int > cluster;
  738. std::map < int, int > copy_cluster;
  739. OrientedGraph::vertex_iterator vertexIt, vertexEnd;
  740. boost::tie(vertexIt, vertexEnd) = boost::vertices(graph);
  741. for (; vertexIt != vertexEnd; ++vertexIt) {
  742. if (rand() % 2) {
  743. cluster[graph[*vertexIt]._index] = n1;
  744. } else {
  745. cluster[graph[*vertexIt]._index] = n2;
  746. }
  747. }
  748. copy_cluster = cluster;
  749. // build coordinators (graphs)
  750. for (unsigned int i = 0; i < 2; ++i) {
  751. Coordinator* coordinator = 0;
  752. std::ostringstream ss;
  753. unsigned index = (i == 0) ? n1 : n2;
  754. ss << "S" << index;
  755. coordinator =
  756. new Coordinator(ss.str(), paradevs::common::NoParameters(),
  757. HierarchicalParameters(
  758. index,
  759. parameters.level_number - 1,
  760. cluster,
  761. graph));
  762. _coordinators.push_back(coordinator);
  763. RootHierarchicalGraphManager < SchedulerHandle,
  764. GraphBuilder >::add_child(
  765. coordinator);
  766. }
  767. // build ports and connections
  768. // internal
  769. for (unsigned int i = 0; i < 2; ++i) {
  770. unsigned index = (i == 0) ? n1 : n2;
  771. OrientedGraph::vertex_iterator vertexIt, vertexEnd;
  772. boost::tie(vertexIt, vertexEnd) = boost::vertices(graph);
  773. for (; vertexIt != vertexEnd; ++vertexIt) {
  774. if (copy_cluster.at(graph[*vertexIt]._index) != index) {
  775. OrientedGraph::adjacency_iterator neighbourIt, neighbourEnd;
  776. boost::tie(neighbourIt, neighbourEnd) =
  777. boost::adjacent_vertices(*vertexIt, graph);
  778. for (; neighbourIt != neighbourEnd; ++neighbourIt) {
  779. std::map < int, int >::const_iterator it =
  780. copy_cluster.find(graph[*neighbourIt]._index);
  781. if (it != copy_cluster.end() and it->second == index) {
  782. std::ostringstream ss_in_a;
  783. std::ostringstream ss_in_b;
  784. ss_in_a << "out_" << graph[*vertexIt]._index;
  785. ss_in_b << "in_" << graph[*vertexIt]._index;
  786. std::cout << "DEBUG: =>"
  787. << index
  788. << " "
  789. << graph[*vertexIt]._index
  790. << " "
  791. << ((i == 0) ? n2 : n1)
  792. << " "
  793. << ((i == 0) ? n2 : n1) << ":"
  794. << ss_in_a.str()
  795. << " -> " << index << ":"
  796. << ss_in_b.str()
  797. << std::endl;
  798. if (not _coordinators[i]->exist_in_port(
  799. ss_in_b.str())) {
  800. _coordinators[i]->add_in_port(
  801. ss_in_b.str());
  802. }
  803. if (not _coordinators[(i==0)?1:0]->exist_out_port(
  804. ss_in_a.str())) {
  805. _coordinators[(i==0)?1:0]->add_out_port(
  806. ss_in_a.str());
  807. }
  808. if (not RootHierarchicalGraphManager <
  809. SchedulerHandle, GraphBuilder >::exist_link(
  810. _coordinators[(i==0)?1:0],
  811. ss_in_a.str(),
  812. _coordinators[i],
  813. ss_in_b.str())) {
  814. RootHierarchicalGraphManager <
  815. SchedulerHandle, GraphBuilder >::add_link(
  816. _coordinators[(i==0)?1:0],
  817. ss_in_a.str(),
  818. _coordinators[i],
  819. ss_in_b.str());
  820. }
  821. }
  822. }
  823. }
  824. }
  825. }
  826. }
  827. }
  828. virtual ~RootHierarchicalGraphManager()
  829. {
  830. for (typename Coordinators::const_iterator it = _coordinators.begin();
  831. it != _coordinators.end(); ++it) {
  832. delete *it;
  833. }
  834. }
  835. private:
  836. typedef paradevs::pdevs::Coordinator <
  837. common::DoubleTime,
  838. SchedulerType,
  839. SchedulerHandle,
  840. HierarchicalGraphManager < SchedulerHandle >,
  841. common::NoParameters,
  842. HierarchicalParameters > Coordinator;
  843. typedef std::vector < Coordinator* > Coordinators;
  844. // LEAF
  845. typedef paradevs::pdevs::Coordinator <
  846. common::DoubleTime,
  847. SchedulerType,
  848. SchedulerHandle,
  849. LeafGraphManager < SchedulerHandle >,
  850. common::NoParameters,
  851. HierarchicalParameters > LeafCoordinator;
  852. Coordinators _coordinators;
  853. };
  854. class RootHierarchicalGraphBuilder
  855. {
  856. public:
  857. RootHierarchicalGraphBuilder(GraphGenerator& g) : generator(g)
  858. { }
  859. void build(OrientedGraph& graph)
  860. { generator.generate(graph); }
  861. private:
  862. GraphGenerator& generator;
  863. };
  864. } } } // namespace paradevs tests boost_graph
  865. #endif