compressed_sparse_row_graph.hpp 80 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987
  1. // Copyright (C) 2006 The Trustees of Indiana University.
  2. // Use, modification and distribution is subject to the Boost Software
  3. // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  4. // http://www.boost.org/LICENSE_1_0.txt)
  5. // Authors: Douglas Gregor
  6. // Jeremiah Willcock
  7. // Andrew Lumsdaine
  8. // Distributed compressed sparse row graph type
  9. #ifndef BOOST_GRAPH_DISTRIBUTED_CSR_HPP
  10. #define BOOST_GRAPH_DISTRIBUTED_CSR_HPP
  11. #ifndef BOOST_GRAPH_USE_MPI
  12. #error "Parallel BGL files should not be included unless <boost/graph/use_mpi.hpp> has been included"
  13. #endif
  14. #include <boost/assert.hpp>
  15. #include <boost/graph/compressed_sparse_row_graph.hpp>
  16. #include <boost/graph/distributed/selector.hpp>
  17. #include <boost/mpl/if.hpp>
  18. #include <boost/type_traits/is_same.hpp>
  19. #include <boost/graph/distributed/concepts.hpp>
  20. #include <boost/graph/parallel/properties.hpp>
  21. #include <boost/graph/parallel/distribution.hpp>
  22. #include <boost/property_map/parallel/local_property_map.hpp>
  23. #include <boost/property_map/parallel/distributed_property_map.hpp>
  24. namespace boost {
  25. // Distributed and sequential inplace ctors have the same signature so
  26. // we need a separate tag for distributed inplace ctors
  27. enum distributed_construct_inplace_from_sources_and_targets_t
  28. {distributed_construct_inplace_from_sources_and_targets};
  29. // The number of bits we reserve for the processor ID.
  30. // DPG TBD: This is a hack. It will eventually be a run-time quantity.
  31. static const int processor_bits = 8;
  32. // Tag class for a distributed CSR graph
  33. struct distributed_csr_tag
  34. : public virtual distributed_graph_tag,
  35. public virtual distributed_vertex_list_graph_tag,
  36. public virtual distributed_edge_list_graph_tag,
  37. public virtual incidence_graph_tag,
  38. public virtual adjacency_graph_tag {};
  39. template<typename VertexProperty, typename EdgeProperty,
  40. typename GraphProperty, typename ProcessGroup, typename InVertex,
  41. typename InDistribution, typename InEdgeIndex>
  42. class compressed_sparse_row_graph<
  43. directedS, VertexProperty, EdgeProperty, GraphProperty,
  44. distributedS<ProcessGroup, InVertex, InDistribution>,
  45. InEdgeIndex>
  46. {
  47. typedef compressed_sparse_row_graph self_type;
  48. private:
  49. /**
  50. * Determine the type used to represent vertices in the graph. If
  51. * the user has overridden the default, use the user's
  52. * parameter. Otherwise, fall back to std::size_t.
  53. */
  54. typedef typename mpl::if_<is_same<InVertex, defaultS>,
  55. std::size_t,
  56. InVertex>::type Vertex;
  57. /**
  58. * Determine the type used to represent edges in the graph. If
  59. * the user has overridden the default (which is to be the same as
  60. * the distributed vertex selector type), use the user's
  61. * parameter. Otherwise, fall back to the value of @c Vertex.
  62. */
  63. typedef typename mpl::if_<is_same<InEdgeIndex,
  64. distributedS<ProcessGroup, InVertex,
  65. InDistribution> >,
  66. Vertex,
  67. InEdgeIndex>::type EdgeIndex;
  68. public:
  69. /**
  70. * The type of the CSR graph that will be stored locally.
  71. */
  72. typedef compressed_sparse_row_graph<directedS, VertexProperty, EdgeProperty,
  73. GraphProperty, Vertex, EdgeIndex>
  74. base_type;
  75. // -----------------------------------------------------------------
  76. // Graph concept requirements
  77. typedef Vertex vertex_descriptor;
  78. typedef typename graph_traits<base_type>::edge_descriptor edge_descriptor;
  79. typedef directed_tag directed_category;
  80. typedef allow_parallel_edge_tag edge_parallel_category;
  81. typedef distributed_csr_tag traversal_category;
  82. static vertex_descriptor null_vertex();
  83. // -----------------------------------------------------------------
  84. // Distributed Vertex List Graph concept requirements
  85. typedef Vertex vertices_size_type;
  86. class vertex_iterator;
  87. // -----------------------------------------------------------------
  88. // Distributed Edge List Graph concept requirements
  89. typedef EdgeIndex edges_size_type;
  90. class edge_iterator;
  91. // -----------------------------------------------------------------
  92. // Incidence Graph concept requirements
  93. typedef typename graph_traits<base_type>::out_edge_iterator
  94. out_edge_iterator;
  95. typedef typename graph_traits<base_type>::degree_size_type
  96. degree_size_type;
  97. // -----------------------------------------------------------------
  98. // Adjacency Graph concept requirements
  99. typedef typename graph_traits<base_type>::adjacency_iterator
  100. adjacency_iterator;
  101. // Note: This graph type does not model Bidirectional Graph.
  102. // However, this typedef is required to satisfy graph_traits.
  103. typedef void in_edge_iterator;
  104. // -----------------------------------------------------------------
  105. // Distributed Container concept requirements
  106. typedef ProcessGroup process_group_type;
  107. typedef boost::parallel::variant_distribution<process_group_type, Vertex>
  108. distribution_type;
  109. // -----------------------------------------------------------------
  110. // Workarounds
  111. // NOTE: This graph type does not have old-style graph properties. It only
  112. // accepts bundles.
  113. typedef no_property vertex_property_type;
  114. typedef no_property edge_property_type;
  115. typedef no_property graph_property_type;
  116. typedef typename mpl::if_<is_void<VertexProperty>,
  117. void****,
  118. VertexProperty>::type vertex_bundled;
  119. typedef typename mpl::if_<is_void<EdgeProperty>,
  120. void****,
  121. EdgeProperty>::type edge_bundled;
  122. typedef typename mpl::if_<is_void<GraphProperty>,
  123. void****,
  124. GraphProperty>::type graph_bundled;
  125. // -----------------------------------------------------------------
  126. // Useful types
  127. typedef typename ProcessGroup::process_id_type process_id_type;
  128. // -----------------------------------------------------------------
  129. // Graph constructors
  130. compressed_sparse_row_graph(const ProcessGroup& pg = ProcessGroup())
  131. : m_process_group(pg), m_distribution(parallel::block(pg, 0)) {}
  132. compressed_sparse_row_graph(const GraphProperty& prop,
  133. const ProcessGroup& pg = ProcessGroup())
  134. : m_process_group(pg), m_distribution(parallel::block(pg, 0)) {}
  135. compressed_sparse_row_graph(vertices_size_type numverts,
  136. const ProcessGroup& pg = ProcessGroup())
  137. : m_process_group(pg), m_distribution(parallel::block(pg, 0)),
  138. m_base(numverts)
  139. {}
  140. compressed_sparse_row_graph(vertices_size_type numverts,
  141. const GraphProperty& prop,
  142. const ProcessGroup& pg = ProcessGroup())
  143. : m_process_group(pg), m_distribution(parallel::block(pg, 0)),
  144. m_base(numverts)
  145. {}
  146. template <typename Distribution>
  147. compressed_sparse_row_graph(vertices_size_type numverts,
  148. const ProcessGroup& pg,
  149. const Distribution& dist)
  150. : m_process_group(pg), m_distribution(dist), m_base(numverts) {}
  151. template <typename Distribution>
  152. compressed_sparse_row_graph(vertices_size_type numverts,
  153. const GraphProperty& prop,
  154. const ProcessGroup& pg,
  155. const Distribution& dist)
  156. : m_process_group(pg), m_distribution(dist), m_base(numverts) {}
  157. template <typename InputIterator>
  158. compressed_sparse_row_graph(edges_are_unsorted_t,
  159. InputIterator edge_begin, InputIterator edge_end,
  160. vertices_size_type numverts,
  161. const ProcessGroup& pg = ProcessGroup(),
  162. const GraphProperty& prop = GraphProperty());
  163. template <typename InputIterator, typename Distribution>
  164. compressed_sparse_row_graph(edges_are_unsorted_t,
  165. InputIterator edge_begin, InputIterator edge_end,
  166. vertices_size_type numverts,
  167. const ProcessGroup& pg,
  168. const Distribution& dist,
  169. const GraphProperty& prop = GraphProperty());
  170. template <typename InputIterator, typename EdgePropertyIterator>
  171. compressed_sparse_row_graph(edges_are_unsorted_t,
  172. InputIterator edge_begin, InputIterator edge_end,
  173. EdgePropertyIterator ep_iter,
  174. vertices_size_type numverts,
  175. const ProcessGroup& pg = ProcessGroup(),
  176. const GraphProperty& prop = GraphProperty());
  177. template <typename InputIterator, typename EdgePropertyIterator,
  178. typename Distribution>
  179. compressed_sparse_row_graph(edges_are_unsorted_t,
  180. InputIterator edge_begin, InputIterator edge_end,
  181. EdgePropertyIterator ep_iter,
  182. vertices_size_type numverts,
  183. const ProcessGroup& pg,
  184. const Distribution& dist,
  185. const GraphProperty& prop = GraphProperty());
  186. template <typename InputIterator>
  187. compressed_sparse_row_graph(edges_are_sorted_t,
  188. InputIterator edge_begin, InputIterator edge_end,
  189. vertices_size_type numverts,
  190. edges_size_type numedges = 0,
  191. const ProcessGroup& pg = ProcessGroup(),
  192. const GraphProperty& prop = GraphProperty());
  193. template <typename InputIterator, typename Distribution>
  194. compressed_sparse_row_graph(edges_are_sorted_t,
  195. InputIterator edge_begin, InputIterator edge_end,
  196. vertices_size_type numverts,
  197. const ProcessGroup& pg,
  198. const Distribution& dist,
  199. const GraphProperty& prop = GraphProperty());
  200. template <typename InputIterator, typename EdgePropertyIterator>
  201. compressed_sparse_row_graph(edges_are_sorted_t,
  202. InputIterator edge_begin, InputIterator edge_end,
  203. EdgePropertyIterator ep_iter,
  204. vertices_size_type numverts,
  205. edges_size_type numedges = 0,
  206. const ProcessGroup& pg = ProcessGroup(),
  207. const GraphProperty& prop = GraphProperty());
  208. template <typename InputIterator, typename EdgePropertyIterator,
  209. typename Distribution>
  210. compressed_sparse_row_graph(edges_are_sorted_t,
  211. InputIterator edge_begin, InputIterator edge_end,
  212. EdgePropertyIterator ep_iter,
  213. vertices_size_type numverts,
  214. const ProcessGroup& pg,
  215. const Distribution& dist,
  216. const GraphProperty& prop = GraphProperty());
  217. template <typename MultiPassInputIterator>
  218. compressed_sparse_row_graph(edges_are_unsorted_multi_pass_t,
  219. MultiPassInputIterator edge_begin,
  220. MultiPassInputIterator edge_end,
  221. vertices_size_type numverts,
  222. const ProcessGroup& pg = ProcessGroup(),
  223. const GraphProperty& prop = GraphProperty());
  224. template <typename MultiPassInputIterator, typename Distribution>
  225. compressed_sparse_row_graph(edges_are_unsorted_multi_pass_t,
  226. MultiPassInputIterator edge_begin,
  227. MultiPassInputIterator edge_end,
  228. vertices_size_type numverts,
  229. const ProcessGroup& pg,
  230. const Distribution& dist,
  231. const GraphProperty& prop = GraphProperty());
  232. template <typename MultiPassInputIterator, typename EdgePropertyIterator>
  233. compressed_sparse_row_graph(edges_are_unsorted_multi_pass_t,
  234. MultiPassInputIterator edge_begin,
  235. MultiPassInputIterator edge_end,
  236. EdgePropertyIterator ep_iter,
  237. vertices_size_type numverts,
  238. const ProcessGroup& pg = ProcessGroup(),
  239. const GraphProperty& prop = GraphProperty());
  240. template <typename MultiPassInputIterator, typename EdgePropertyIterator,
  241. typename Distribution>
  242. compressed_sparse_row_graph(edges_are_unsorted_multi_pass_t,
  243. MultiPassInputIterator edge_begin,
  244. MultiPassInputIterator edge_end,
  245. EdgePropertyIterator ep_iter,
  246. vertices_size_type numverts,
  247. const ProcessGroup& pg,
  248. const Distribution& dist,
  249. const GraphProperty& prop = GraphProperty());
  250. template <typename Source>
  251. compressed_sparse_row_graph(distributed_construct_inplace_from_sources_and_targets_t,
  252. std::vector<Source>& sources,
  253. std::vector<vertex_descriptor>& targets,
  254. vertices_size_type numverts,
  255. const ProcessGroup& pg = ProcessGroup(),
  256. const GraphProperty& prop = GraphProperty());
  257. template <typename Distribution, typename Source>
  258. compressed_sparse_row_graph(distributed_construct_inplace_from_sources_and_targets_t,
  259. std::vector<Source>& sources,
  260. std::vector<vertex_descriptor>& targets,
  261. vertices_size_type numverts,
  262. const ProcessGroup& pg,
  263. const Distribution& dist,
  264. const GraphProperty& prop = GraphProperty());
  265. template <typename Source>
  266. compressed_sparse_row_graph(distributed_construct_inplace_from_sources_and_targets_t,
  267. std::vector<Source>& sources,
  268. std::vector<vertex_descriptor>& targets,
  269. std::vector<edge_bundled>& edge_props,
  270. vertices_size_type numverts,
  271. const ProcessGroup& pg = ProcessGroup(),
  272. const GraphProperty& prop = GraphProperty());
  273. template <typename Distribution, typename Source>
  274. compressed_sparse_row_graph(distributed_construct_inplace_from_sources_and_targets_t,
  275. std::vector<Source>& sources,
  276. std::vector<vertex_descriptor>& targets,
  277. std::vector<edge_bundled>& edge_props,
  278. vertices_size_type numverts,
  279. const ProcessGroup& pg,
  280. const Distribution& dist,
  281. const GraphProperty& prop = GraphProperty());
  282. template<typename InputIterator>
  283. compressed_sparse_row_graph(InputIterator edge_begin, InputIterator edge_end,
  284. vertices_size_type numverts,
  285. const ProcessGroup& pg = ProcessGroup(),
  286. const GraphProperty& prop = GraphProperty());
  287. template<typename InputIterator, typename EdgePropertyIterator>
  288. compressed_sparse_row_graph(InputIterator edge_begin, InputIterator edge_end,
  289. EdgePropertyIterator ep_iter,
  290. vertices_size_type numverts,
  291. const ProcessGroup& pg = ProcessGroup(),
  292. const GraphProperty& prop = GraphProperty());
  293. template<typename InputIterator, typename Distribution>
  294. compressed_sparse_row_graph(InputIterator edge_begin, InputIterator edge_end,
  295. vertices_size_type numverts,
  296. const ProcessGroup& pg,
  297. const Distribution& dist,
  298. const GraphProperty& prop = GraphProperty());
  299. template<typename InputIterator, typename EdgePropertyIterator,
  300. typename Distribution>
  301. compressed_sparse_row_graph(InputIterator edge_begin, InputIterator edge_end,
  302. EdgePropertyIterator ep_iter,
  303. vertices_size_type numverts,
  304. const ProcessGroup& pg,
  305. const Distribution& dist,
  306. const GraphProperty& prop = GraphProperty());
  307. base_type& base() { return m_base; }
  308. const base_type& base() const { return m_base; }
  309. process_group_type process_group() const { return m_process_group.base(); }
  310. distribution_type& distribution() { return m_distribution; }
  311. const distribution_type& distribution() const { return m_distribution; }
  312. // Directly access a vertex or edge bundle
  313. vertex_bundled& operator[](vertex_descriptor v)
  314. {
  315. return get(vertex_bundle, *this, v);
  316. }
  317. const vertex_bundled& operator[](vertex_descriptor v) const
  318. {
  319. return get(vertex_bundle, *this, v);
  320. }
  321. edge_bundled& operator[](edge_descriptor e)
  322. {
  323. return get(edge_bundle, *this, e);
  324. }
  325. const edge_bundled& operator[](edge_descriptor e) const
  326. {
  327. return get(edge_bundle, *this, e);
  328. }
  329. // Create a vertex descriptor from a process ID and a local index.
  330. vertex_descriptor
  331. make_vertex_descriptor(process_id_type p, vertex_descriptor v) const
  332. {
  333. vertex_descriptor vertex_local_index_bits =
  334. sizeof(vertex_descriptor) * CHAR_BIT - processor_bits;
  335. return v | ((vertex_descriptor)p << vertex_local_index_bits);
  336. }
  337. // Convert a local vertex descriptor into a global vertex descriptor
  338. vertex_descriptor local_to_global_vertex(vertex_descriptor v) const
  339. {
  340. return make_vertex_descriptor(process_id(m_process_group), v);
  341. }
  342. // Structural modification
  343. vertex_descriptor add_vertex()
  344. {
  345. typename graph_traits<base_type>::vertex_descriptor v
  346. = boost::add_vertex(m_base);
  347. return make_vertex_descriptor(process_id(m_process_group), v);
  348. }
  349. vertex_descriptor add_vertex(const vertex_bundled& p)
  350. {
  351. typename graph_traits<base_type>::vertex_descriptor v
  352. = boost::add_vertex(m_base, p);
  353. return make_vertex_descriptor(process_id(m_process_group), v);
  354. }
  355. vertex_descriptor add_vertices(vertices_size_type count)
  356. {
  357. typename graph_traits<base_type>::vertex_descriptor v
  358. = boost::add_vertices(count, m_base);
  359. return make_vertex_descriptor(process_id(m_process_group), v);
  360. }
  361. template <typename InputIterator>
  362. void
  363. add_edges(InputIterator first, InputIterator last)
  364. { boost::add_edges_global(first, last, get(vertex_local, *this), m_base); }
  365. template <typename InputIterator, typename EdgePropertyIterator>
  366. void
  367. add_edges(InputIterator first, InputIterator last,
  368. EdgePropertyIterator ep_iter,
  369. EdgePropertyIterator ep_iter_end)
  370. { boost::add_edges_global(first, last, ep_iter, ep_iter_end,
  371. get(vertex_local, *this), m_base); }
  372. template <typename InputIterator>
  373. void
  374. add_edges_sorted(InputIterator first, InputIterator last)
  375. { boost::add_edges_sorted_global(first, last,
  376. get(vertex_local, *this), m_base); }
  377. template <typename InputIterator, typename EdgePropertyIterator>
  378. void
  379. add_edges_sorted(InputIterator first_sorted, InputIterator last_sorted,
  380. EdgePropertyIterator ep_iter_sorted)
  381. { boost::add_edges_sorted_global(first_sorted, last_sorted, ep_iter_sorted,
  382. get(vertex_local, *this), m_base); }
  383. protected:
  384. ProcessGroup m_process_group;
  385. distribution_type m_distribution;
  386. base_type m_base;
  387. };
  388. /** @brief Helper macro containing the template parameters for the
  389. * distributed CSR graph.
  390. *
  391. * This macro contains all of the template parameters needed for the
  392. * distributed compressed_sparse_row graph type. It is used to reduce
  393. * the amount of typing required to declare free functions for this
  394. * graph type.
  395. */
  396. #define BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS \
  397. typename VertexProperty, typename EdgeProperty, \
  398. typename GraphProperty, typename ProcessGroup, typename InVertex, \
  399. typename InDistribution, typename InEdgeIndex
  400. /** @brief Helper macro containing the typical instantiation of the
  401. * distributed CSR graph.
  402. *
  403. * This macro contains an instantiation of the distributed CSR graph
  404. * type using the typical template parameters names (e.g., those
  405. * provided by the macro @c
  406. * BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS). It is used to reduce
  407. * the amount of typing required to declare free functions for this
  408. * graph type.
  409. */
  410. #define BOOST_DISTRIB_CSR_GRAPH_TYPE \
  411. compressed_sparse_row_graph< \
  412. directedS, VertexProperty, EdgeProperty, GraphProperty, \
  413. distributedS<ProcessGroup, InVertex, InDistribution>, \
  414. InEdgeIndex>
  415. // -----------------------------------------------------------------
  416. // Graph concept operations
  417. template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
  418. inline typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor
  419. BOOST_DISTRIB_CSR_GRAPH_TYPE::null_vertex()
  420. {
  421. return graph_traits<base_type>::null_vertex();
  422. }
  423. // -----------------------------------------------------------------
  424. // Incidence Graph concept operations
  425. template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
  426. inline typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor
  427. source(typename BOOST_DISTRIB_CSR_GRAPH_TYPE::edge_descriptor e,
  428. const BOOST_DISTRIB_CSR_GRAPH_TYPE&)
  429. { return e.src; }
  430. template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
  431. inline typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor
  432. target(typename BOOST_DISTRIB_CSR_GRAPH_TYPE::edge_descriptor e,
  433. const BOOST_DISTRIB_CSR_GRAPH_TYPE& g)
  434. { return target(e, g.base()); }
  435. template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
  436. inline std::pair<typename BOOST_DISTRIB_CSR_GRAPH_TYPE::out_edge_iterator,
  437. typename BOOST_DISTRIB_CSR_GRAPH_TYPE::out_edge_iterator>
  438. out_edges(typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor u,
  439. const BOOST_DISTRIB_CSR_GRAPH_TYPE& g)
  440. {
  441. typedef typename BOOST_DISTRIB_CSR_GRAPH_TYPE::edges_size_type
  442. edges_size_type;
  443. typedef typename BOOST_DISTRIB_CSR_GRAPH_TYPE::edge_descriptor ed;
  444. typedef typename BOOST_DISTRIB_CSR_GRAPH_TYPE::out_edge_iterator it;
  445. edges_size_type u_local = get(vertex_local, g, u);
  446. edges_size_type u_row_start = g.base().m_forward.m_rowstart[u_local];
  447. edges_size_type next_row_start = g.base().m_forward.m_rowstart[u_local + 1];
  448. return std::make_pair(it(ed(u, u_row_start)),
  449. it(ed(u, (std::max)(u_row_start, next_row_start))));
  450. }
  451. template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
  452. inline typename BOOST_DISTRIB_CSR_GRAPH_TYPE::degree_size_type
  453. out_degree(typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor u,
  454. const BOOST_DISTRIB_CSR_GRAPH_TYPE& g)
  455. {
  456. return out_degree(get(vertex_local, g, u), g.base());
  457. }
  458. // -----------------------------------------------------------------
  459. // DistributedGraph concept requirements
  460. template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
  461. void synchronize(const BOOST_DISTRIB_CSR_GRAPH_TYPE& g)
  462. {
  463. synchronize(g.process_group());
  464. }
  465. template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
  466. ProcessGroup
  467. process_group(const BOOST_DISTRIB_CSR_GRAPH_TYPE& g)
  468. { return g.process_group(); }
  469. // -----------------------------------------------------------------
  470. // Adjacency Graph concept requirements
  471. template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
  472. inline std::pair<typename BOOST_DISTRIB_CSR_GRAPH_TYPE::adjacency_iterator,
  473. typename BOOST_DISTRIB_CSR_GRAPH_TYPE::adjacency_iterator>
  474. adjacent_vertices(typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor u,
  475. const BOOST_DISTRIB_CSR_GRAPH_TYPE& g)
  476. {
  477. return adjacent_vertices(get(vertex_local, g, u), g.base());
  478. }
  479. // -----------------------------------------------------------------
  480. // Distributed Vertex List Graph concept operations
  481. template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
  482. class BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_iterator
  483. : public iterator_adaptor<vertex_iterator,
  484. counting_iterator<Vertex>,
  485. Vertex,
  486. random_access_traversal_tag,
  487. Vertex>
  488. {
  489. typedef iterator_adaptor<vertex_iterator,
  490. counting_iterator<Vertex>,
  491. Vertex,
  492. random_access_traversal_tag,
  493. Vertex> inherited;
  494. public:
  495. vertex_iterator() {}
  496. explicit vertex_iterator(Vertex v, const self_type* graph)
  497. : inherited(counting_iterator<Vertex>(v)), graph(graph) { }
  498. Vertex dereference() const
  499. {
  500. return graph->local_to_global_vertex(*(this->base_reference()));
  501. }
  502. friend class iterator_core_access;
  503. private:
  504. const self_type* graph;
  505. };
  506. template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
  507. inline typename BOOST_DISTRIB_CSR_GRAPH_TYPE::degree_size_type
  508. num_vertices(const BOOST_DISTRIB_CSR_GRAPH_TYPE& g)
  509. {
  510. return num_vertices(g.base());
  511. }
  512. template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
  513. inline std::pair<typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_iterator,
  514. typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_iterator>
  515. vertices(const BOOST_DISTRIB_CSR_GRAPH_TYPE& g)
  516. {
  517. typedef typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_iterator
  518. vertex_iterator;
  519. return std::make_pair(vertex_iterator(0, &g),
  520. vertex_iterator(num_vertices(g), &g));
  521. }
  522. // -----------------------------------------------------------------
  523. // Distributed Edge List Graph concept operations
  524. template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
  525. class BOOST_DISTRIB_CSR_GRAPH_TYPE::edge_iterator
  526. {
  527. public:
  528. typedef std::forward_iterator_tag iterator_category;
  529. typedef edge_descriptor value_type;
  530. typedef const edge_descriptor* pointer;
  531. typedef edge_descriptor reference;
  532. typedef typename int_t<CHAR_BIT * sizeof(EdgeIndex)>::fast difference_type;
  533. edge_iterator() : graph(0), current_edge(), end_of_this_vertex(0) {}
  534. edge_iterator(const compressed_sparse_row_graph& graph,
  535. edge_descriptor current_edge,
  536. EdgeIndex end_of_this_vertex)
  537. : graph(&graph), local_src(current_edge.src), current_edge(current_edge),
  538. end_of_this_vertex(end_of_this_vertex)
  539. {
  540. // The edge that comes in has a local source vertex. Make it global.
  541. current_edge.src = graph.local_to_global_vertex(current_edge.src);
  542. }
  543. // From InputIterator
  544. reference operator*() const { return current_edge; }
  545. pointer operator->() const { return &current_edge; }
  546. bool operator==(const edge_iterator& o) const {
  547. return current_edge == o.current_edge;
  548. }
  549. bool operator!=(const edge_iterator& o) const {
  550. return current_edge != o.current_edge;
  551. }
  552. edge_iterator& operator++()
  553. {
  554. ++current_edge.idx;
  555. while (current_edge.idx == end_of_this_vertex && local_src < num_vertices(*graph)-1) {
  556. ++local_src;
  557. current_edge.src = graph->local_to_global_vertex(local_src);
  558. end_of_this_vertex = graph->base().m_forward.m_rowstart[local_src + 1];
  559. }
  560. return *this;
  561. }
  562. edge_iterator operator++(int) {
  563. edge_iterator temp = *this;
  564. ++*this;
  565. return temp;
  566. }
  567. private:
  568. const compressed_sparse_row_graph* graph;
  569. EdgeIndex local_src;
  570. edge_descriptor current_edge;
  571. EdgeIndex end_of_this_vertex;
  572. };
  573. template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
  574. inline typename BOOST_DISTRIB_CSR_GRAPH_TYPE::edges_size_type
  575. num_edges(const BOOST_DISTRIB_CSR_GRAPH_TYPE& g)
  576. {
  577. return g.base().m_forward.m_column.size();
  578. }
  579. template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
  580. std::pair<typename BOOST_DISTRIB_CSR_GRAPH_TYPE::edge_iterator,
  581. typename BOOST_DISTRIB_CSR_GRAPH_TYPE::edge_iterator>
  582. edges(const BOOST_DISTRIB_CSR_GRAPH_TYPE& g)
  583. {
  584. typedef typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor Vertex;
  585. typedef typename BOOST_DISTRIB_CSR_GRAPH_TYPE::edge_iterator ei;
  586. typedef typename BOOST_DISTRIB_CSR_GRAPH_TYPE::edge_descriptor edgedesc;
  587. if (g.base().m_forward.m_rowstart.size() == 1 ||
  588. g.base().m_forward.m_column.empty()) {
  589. return std::make_pair(ei(), ei());
  590. } else {
  591. // Find the first vertex that has outgoing edges
  592. Vertex src = 0;
  593. while (g.base().m_forward.m_rowstart[src + 1] == 0) ++src;
  594. return std::make_pair(ei(g, edgedesc(src, 0), g.base().m_forward.m_rowstart[src + 1]),
  595. ei(g, edgedesc(num_vertices(g), g.base().m_forward.m_column.size()), 0));
  596. }
  597. }
  598. // -----------------------------------------------------------------
  599. // Graph constructors
  600. // Returns true if a vertex belongs to a process according to a distribution
  601. template <typename OwnerMap, typename ProcessId>
  602. struct local_vertex {
  603. local_vertex(OwnerMap owner, ProcessId id)
  604. : owner(owner), id(id) {}
  605. template <typename Vertex>
  606. bool operator()(Vertex x)
  607. { return get(owner, x) == id; }
  608. template <typename Vertex>
  609. bool operator()(Vertex x) const
  610. { return get(owner, x) == id; }
  611. private:
  612. OwnerMap owner;
  613. ProcessId id;
  614. };
  615. // Returns true if a vertex belongs to a process according to a distribution
  616. template <typename OwnerMap, typename ProcessId>
  617. struct local_edge {
  618. local_edge(OwnerMap owner, ProcessId id)
  619. : owner(owner), id(id) {}
  620. template <typename Vertex>
  621. bool operator()(std::pair<Vertex, Vertex>& x)
  622. { return get(owner, x.first) == id; }
  623. template <typename Vertex>
  624. bool operator()(const std::pair<Vertex, Vertex>& x) const
  625. { return get(owner, x.first) == id; }
  626. private:
  627. OwnerMap owner;
  628. ProcessId id;
  629. };
  630. // Turns an index iterator into a vertex iterator
  631. template<typename IndexIterator, typename Graph>
  632. class index_to_vertex_iterator {
  633. public:
  634. typedef std::input_iterator_tag iterator_category;
  635. typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
  636. typedef std::pair<Vertex, Vertex> value_type;
  637. typedef const value_type& reference;
  638. typedef const value_type* pointer;
  639. typedef void difference_type;
  640. index_to_vertex_iterator(IndexIterator index,
  641. const Graph& g)
  642. : index(index), g(g), current(to_edge(*index)) {}
  643. reference operator*() { current = to_edge(*index); return current; }
  644. pointer operator->() { current = to_edge(*index); return &current; }
  645. index_to_vertex_iterator& operator++()
  646. {
  647. ++index;
  648. return *this;
  649. }
  650. index_to_vertex_iterator operator++(int)
  651. {
  652. index_to_vertex_iterator temp(*this);
  653. ++(*this);
  654. return temp;
  655. }
  656. bool operator==(const index_to_vertex_iterator& other) const
  657. { return index == other.index; }
  658. bool operator!=(const index_to_vertex_iterator& other) const
  659. { return !(*this == other); }
  660. private:
  661. value_type to_edge(const typename std::iterator_traits<IndexIterator>::value_type& x)
  662. { return std::make_pair(vertex(x.first, g), vertex(x.second, g)); }
  663. IndexIterator index;
  664. const Graph& g;
  665. value_type current;
  666. };
  667. template <typename Distribution, typename Graph>
  668. struct index_to_vertex_func {
  669. typedef typename boost::graph_traits<Graph>::vertex_descriptor vertex_descriptor;
  670. typedef typename boost::graph_traits<Graph>::vertices_size_type vertices_size_type;
  671. typedef std::pair<vertex_descriptor, vertex_descriptor> result_type;
  672. typedef std::pair<vertices_size_type, vertices_size_type> base_iterator_type;
  673. index_to_vertex_func(const Distribution& dist, const Graph& g)
  674. : dist(dist), g(g) {}
  675. result_type operator()(const base_iterator_type& p) const
  676. {
  677. return std::make_pair(vertex(p.first, g), vertex(p.second, g));
  678. }
  679. private:
  680. const Distribution& dist;
  681. const Graph& g;
  682. };
  683. // NGE: This method only works with iterators that have a difference_type,
  684. // the index_to_vertex_iterator class above is retained for compatibility
  685. // with BGL generators which have no difference_type
  686. template <typename IndexIterator, typename Distribution, typename Graph>
  687. boost::transform_iterator<index_to_vertex_func<Distribution, Graph>, IndexIterator>
  688. make_index_to_vertex_iterator(IndexIterator it, const Distribution& dist,
  689. const Graph& g) {
  690. return boost::make_transform_iterator(
  691. it, index_to_vertex_func<Distribution, Graph>(dist, g));
  692. }
  693. // Forward declaration of csr_vertex_owner_map
  694. template<typename ProcessID, typename Key> class csr_vertex_owner_map;
  695. template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
  696. template<typename InputIterator>
  697. BOOST_DISTRIB_CSR_GRAPH_TYPE::
  698. compressed_sparse_row_graph(edges_are_unsorted_t,
  699. InputIterator edge_begin, InputIterator edge_end,
  700. vertices_size_type numverts,
  701. const ProcessGroup& pg,
  702. const GraphProperty& prop)
  703. : m_process_group(pg),
  704. m_distribution(parallel::block(m_process_group, numverts)),
  705. m_base(edges_are_unsorted_global,
  706. index_to_vertex_iterator<InputIterator, BOOST_DISTRIB_CSR_GRAPH_TYPE>(edge_begin, *this),
  707. index_to_vertex_iterator<InputIterator, BOOST_DISTRIB_CSR_GRAPH_TYPE>(edge_end, *this),
  708. m_distribution.block_size(process_id(m_process_group), numverts),
  709. get(vertex_local, *this),
  710. local_vertex<csr_vertex_owner_map<process_id_type, vertex_descriptor>,
  711. process_id_type> (get(vertex_owner, *this), process_id(pg)),
  712. prop)
  713. { }
  714. template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
  715. template <typename InputIterator, typename Distribution>
  716. BOOST_DISTRIB_CSR_GRAPH_TYPE::
  717. compressed_sparse_row_graph(edges_are_unsorted_t,
  718. InputIterator edge_begin, InputIterator edge_end,
  719. vertices_size_type numverts,
  720. const ProcessGroup& pg,
  721. const Distribution& dist,
  722. const GraphProperty& prop)
  723. : m_process_group(pg),
  724. m_distribution(dist),
  725. m_base(edges_are_unsorted_global,
  726. index_to_vertex_iterator<InputIterator, BOOST_DISTRIB_CSR_GRAPH_TYPE>(edge_begin, *this),
  727. index_to_vertex_iterator<InputIterator, BOOST_DISTRIB_CSR_GRAPH_TYPE>(edge_end, *this),
  728. m_distribution.block_size(process_id(m_process_group), numverts),
  729. get(vertex_local, *this),
  730. local_vertex<csr_vertex_owner_map<process_id_type, vertex_descriptor>,
  731. process_id_type> (get(vertex_owner, *this), process_id(pg)),
  732. prop)
  733. { }
  734. template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
  735. template<typename InputIterator, typename EdgePropertyIterator>
  736. BOOST_DISTRIB_CSR_GRAPH_TYPE::
  737. compressed_sparse_row_graph(edges_are_unsorted_t,
  738. InputIterator edge_begin, InputIterator edge_end,
  739. EdgePropertyIterator ep_iter,
  740. vertices_size_type numverts,
  741. const ProcessGroup& pg,
  742. const GraphProperty& prop)
  743. : m_process_group(pg),
  744. m_distribution(parallel::block(m_process_group, numverts)),
  745. m_base(edges_are_unsorted_global,
  746. index_to_vertex_iterator<InputIterator, BOOST_DISTRIB_CSR_GRAPH_TYPE>(edge_begin, *this),
  747. index_to_vertex_iterator<InputIterator, BOOST_DISTRIB_CSR_GRAPH_TYPE>(edge_end, *this),
  748. ep_iter,
  749. m_distribution.block_size(process_id(m_process_group), numverts),
  750. get(vertex_local, *this),
  751. local_vertex<csr_vertex_owner_map<process_id_type, vertex_descriptor>,
  752. process_id_type> (get(vertex_owner, *this), process_id(pg)),
  753. prop)
  754. { }
  755. template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
  756. template <typename InputIterator, typename EdgePropertyIterator,
  757. typename Distribution>
  758. BOOST_DISTRIB_CSR_GRAPH_TYPE::
  759. compressed_sparse_row_graph(edges_are_unsorted_t,
  760. InputIterator edge_begin, InputIterator edge_end,
  761. EdgePropertyIterator ep_iter,
  762. vertices_size_type numverts,
  763. const ProcessGroup& pg,
  764. const Distribution& dist,
  765. const GraphProperty& prop)
  766. : m_process_group(pg),
  767. m_distribution(dist),
  768. m_base(edges_are_unsorted_global,
  769. index_to_vertex_iterator<InputIterator, BOOST_DISTRIB_CSR_GRAPH_TYPE>(edge_begin, *this),
  770. index_to_vertex_iterator<InputIterator, BOOST_DISTRIB_CSR_GRAPH_TYPE>(edge_end, *this),
  771. ep_iter,
  772. m_distribution.block_size(process_id(m_process_group), numverts),
  773. get(vertex_local, *this),
  774. local_vertex<csr_vertex_owner_map<process_id_type, vertex_descriptor>,
  775. process_id_type> (get(vertex_owner, *this), process_id(pg)),
  776. prop)
  777. { }
  778. template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
  779. template<typename InputIterator>
  780. BOOST_DISTRIB_CSR_GRAPH_TYPE::
  781. compressed_sparse_row_graph(edges_are_sorted_t,
  782. InputIterator edge_begin, InputIterator edge_end,
  783. vertices_size_type numverts,
  784. edges_size_type numedges, // This is not used as there is no appropriate BGL ctor
  785. const ProcessGroup& pg,
  786. const GraphProperty& prop)
  787. : m_process_group(pg),
  788. m_distribution(parallel::block(m_process_group, numverts)),
  789. m_base(edges_are_sorted_global,
  790. index_to_vertex_iterator<InputIterator, BOOST_DISTRIB_CSR_GRAPH_TYPE>(edge_begin, *this),
  791. index_to_vertex_iterator<InputIterator, BOOST_DISTRIB_CSR_GRAPH_TYPE>(edge_end, *this),
  792. get(vertex_local, *this),
  793. local_vertex<csr_vertex_owner_map<process_id_type, vertex_descriptor>,
  794. process_id_type> (get(vertex_owner, *this), process_id(pg)),
  795. m_distribution.block_size(process_id(m_process_group), numverts),
  796. prop)
  797. { }
  798. template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
  799. template <typename InputIterator, typename Distribution>
  800. BOOST_DISTRIB_CSR_GRAPH_TYPE::
  801. compressed_sparse_row_graph(edges_are_sorted_t,
  802. InputIterator edge_begin, InputIterator edge_end,
  803. vertices_size_type numverts,
  804. const ProcessGroup& pg,
  805. const Distribution& dist,
  806. const GraphProperty& prop)
  807. : m_process_group(pg),
  808. m_distribution(dist),
  809. m_base(edges_are_sorted_global,
  810. index_to_vertex_iterator<InputIterator, BOOST_DISTRIB_CSR_GRAPH_TYPE>(edge_begin, *this),
  811. index_to_vertex_iterator<InputIterator, BOOST_DISTRIB_CSR_GRAPH_TYPE>(edge_end, *this),
  812. get(vertex_local, *this),
  813. local_vertex<csr_vertex_owner_map<process_id_type, vertex_descriptor>,
  814. process_id_type> (get(vertex_owner, *this), process_id(pg)),
  815. m_distribution.block_size(process_id(m_process_group), numverts),
  816. prop)
  817. { }
  818. template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
  819. template<typename InputIterator, typename EdgePropertyIterator>
  820. BOOST_DISTRIB_CSR_GRAPH_TYPE::
  821. compressed_sparse_row_graph(edges_are_sorted_t,
  822. InputIterator edge_begin, InputIterator edge_end,
  823. EdgePropertyIterator ep_iter,
  824. vertices_size_type numverts,
  825. edges_size_type numedges, // This is not used as there is no appropriate BGL ctor
  826. const ProcessGroup& pg,
  827. const GraphProperty& prop)
  828. : m_process_group(pg),
  829. m_distribution(parallel::block(m_process_group, numverts)),
  830. m_base(edges_are_sorted_global,
  831. index_to_vertex_iterator<InputIterator, BOOST_DISTRIB_CSR_GRAPH_TYPE>(edge_begin, *this),
  832. index_to_vertex_iterator<InputIterator, BOOST_DISTRIB_CSR_GRAPH_TYPE>(edge_end, *this),
  833. ep_iter,
  834. get(vertex_local, *this),
  835. local_vertex<csr_vertex_owner_map<process_id_type, vertex_descriptor>,
  836. process_id_type> (get(vertex_owner, *this), process_id(pg)),
  837. m_distribution.block_size(process_id(m_process_group), numverts),
  838. prop)
  839. { }
  840. template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
  841. template<typename InputIterator, typename EdgePropertyIterator,
  842. typename Distribution>
  843. BOOST_DISTRIB_CSR_GRAPH_TYPE::
  844. compressed_sparse_row_graph(edges_are_sorted_t,
  845. InputIterator edge_begin, InputIterator edge_end,
  846. EdgePropertyIterator ep_iter,
  847. vertices_size_type numverts,
  848. const ProcessGroup& pg,
  849. const Distribution& dist,
  850. const GraphProperty& prop)
  851. : m_process_group(pg),
  852. m_distribution(dist),
  853. m_base(edges_are_sorted_global,
  854. index_to_vertex_iterator<InputIterator, BOOST_DISTRIB_CSR_GRAPH_TYPE>(edge_begin, *this),
  855. index_to_vertex_iterator<InputIterator, BOOST_DISTRIB_CSR_GRAPH_TYPE>(edge_end, *this),
  856. ep_iter,
  857. get(vertex_local, *this),
  858. local_vertex<csr_vertex_owner_map<process_id_type, vertex_descriptor>,
  859. process_id_type> (get(vertex_owner, *this), process_id(pg)),
  860. m_distribution.block_size(process_id(m_process_group), numverts),
  861. prop)
  862. { }
  863. template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
  864. template<typename MultiPassInputIterator>
  865. BOOST_DISTRIB_CSR_GRAPH_TYPE::
  866. compressed_sparse_row_graph(edges_are_unsorted_multi_pass_t,
  867. MultiPassInputIterator edge_begin,
  868. MultiPassInputIterator edge_end,
  869. vertices_size_type numverts,
  870. const ProcessGroup& pg,
  871. const GraphProperty& prop)
  872. : m_process_group(pg),
  873. m_distribution(parallel::block(m_process_group, numverts)),
  874. m_base(edges_are_unsorted_multi_pass_global,
  875. make_index_to_vertex_iterator(edge_begin, parallel::block(m_process_group, numverts), *this),
  876. make_index_to_vertex_iterator(edge_end, parallel::block(m_process_group, numverts), *this),
  877. m_distribution.block_size(process_id(m_process_group), numverts),
  878. get(vertex_local, *this),
  879. local_vertex<csr_vertex_owner_map<process_id_type, vertex_descriptor>,
  880. process_id_type> (get(vertex_owner, *this), process_id(pg)),
  881. prop)
  882. { }
  883. template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
  884. template <typename MultiPassInputIterator, typename Distribution>
  885. BOOST_DISTRIB_CSR_GRAPH_TYPE::
  886. compressed_sparse_row_graph(edges_are_unsorted_multi_pass_t,
  887. MultiPassInputIterator edge_begin,
  888. MultiPassInputIterator edge_end,
  889. vertices_size_type numverts,
  890. const ProcessGroup& pg,
  891. const Distribution& dist,
  892. const GraphProperty& prop)
  893. : m_process_group(pg),
  894. m_distribution(dist),
  895. m_base(edges_are_unsorted_multi_pass_global,
  896. make_index_to_vertex_iterator(edge_begin, parallel::block(m_process_group, numverts), *this),
  897. make_index_to_vertex_iterator(edge_end, parallel::block(m_process_group, numverts), *this),
  898. m_distribution.block_size(process_id(m_process_group), numverts),
  899. get(vertex_local, *this),
  900. local_vertex<csr_vertex_owner_map<process_id_type, vertex_descriptor>,
  901. process_id_type> (get(vertex_owner, *this), process_id(pg)),
  902. prop)
  903. { }
  904. template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
  905. template<typename MultiPassInputIterator, typename EdgePropertyIterator>
  906. BOOST_DISTRIB_CSR_GRAPH_TYPE::
  907. compressed_sparse_row_graph(edges_are_unsorted_multi_pass_t,
  908. MultiPassInputIterator edge_begin,
  909. MultiPassInputIterator edge_end,
  910. EdgePropertyIterator ep_iter,
  911. vertices_size_type numverts,
  912. const ProcessGroup& pg,
  913. const GraphProperty& prop)
  914. : m_process_group(pg),
  915. m_distribution(parallel::block(m_process_group, numverts)),
  916. m_base(edges_are_unsorted_multi_pass_global,
  917. make_index_to_vertex_iterator(edge_begin, parallel::block(m_process_group, numverts), *this),
  918. make_index_to_vertex_iterator(edge_end, parallel::block(m_process_group, numverts), *this),
  919. ep_iter,
  920. m_distribution.block_size(process_id(m_process_group), numverts),
  921. get(vertex_local, *this),
  922. local_vertex<csr_vertex_owner_map<process_id_type, vertex_descriptor>,
  923. process_id_type> (get(vertex_owner, *this), process_id(pg)),
  924. prop)
  925. { }
  926. template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
  927. template <typename MultiPassInputIterator, typename EdgePropertyIterator,
  928. typename Distribution>
  929. BOOST_DISTRIB_CSR_GRAPH_TYPE::
  930. compressed_sparse_row_graph(edges_are_unsorted_multi_pass_t,
  931. MultiPassInputIterator edge_begin,
  932. MultiPassInputIterator edge_end,
  933. EdgePropertyIterator ep_iter,
  934. vertices_size_type numverts,
  935. const ProcessGroup& pg,
  936. const Distribution& dist,
  937. const GraphProperty& prop)
  938. : m_process_group(pg),
  939. m_distribution(dist),
  940. m_base(edges_are_unsorted_multi_pass_global,
  941. make_index_to_vertex_iterator(edge_begin, parallel::block(m_process_group, numverts), *this),
  942. make_index_to_vertex_iterator(edge_end, parallel::block(m_process_group, numverts), *this),
  943. ep_iter,
  944. m_distribution.block_size(process_id(m_process_group), numverts),
  945. get(vertex_local, *this),
  946. local_vertex<csr_vertex_owner_map<process_id_type, vertex_descriptor>,
  947. process_id_type> (get(vertex_owner, *this), process_id(pg)),
  948. prop)
  949. { }
  950. template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
  951. template<typename Source>
  952. BOOST_DISTRIB_CSR_GRAPH_TYPE::
  953. compressed_sparse_row_graph(distributed_construct_inplace_from_sources_and_targets_t,
  954. std::vector<Source>& sources,
  955. std::vector<vertex_descriptor>& targets,
  956. vertices_size_type numverts,
  957. const ProcessGroup& pg,
  958. const GraphProperty& prop)
  959. : m_process_group(pg),
  960. m_distribution(parallel::block(m_process_group, numverts)),
  961. m_base(m_distribution.block_size(process_id(m_process_group), numverts))
  962. {
  963. // Convert linear indices to global indices
  964. for (edges_size_type i = 0; i < sources.size(); ++i) {
  965. sources[i] = m_distribution.local(sources[i]);
  966. targets[i] = make_vertex_descriptor(m_distribution(targets[i]),
  967. m_distribution.local(targets[i]));
  968. }
  969. m_base.assign_sources_and_targets_global(
  970. sources, targets, m_distribution.block_size(process_id(m_process_group), numverts),
  971. identity_property_map());
  972. // TODO: set property on m_base?
  973. }
  974. template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
  975. template <typename Distribution, typename Source>
  976. BOOST_DISTRIB_CSR_GRAPH_TYPE::
  977. compressed_sparse_row_graph(distributed_construct_inplace_from_sources_and_targets_t,
  978. std::vector<Source>& sources,
  979. std::vector<vertex_descriptor>& targets,
  980. vertices_size_type numverts,
  981. const ProcessGroup& pg,
  982. const Distribution& dist,
  983. const GraphProperty& prop)
  984. : m_process_group(pg),
  985. m_distribution(dist),
  986. m_base(m_distribution.block_size(process_id(m_process_group), numverts))
  987. {
  988. // Convert linear indices to global indices
  989. for (edges_size_type i = 0; i < sources.size(); ++i) {
  990. sources[i] = m_distribution.local(sources[i]);
  991. targets[i] = make_vertex_descriptor(m_distribution(targets[i]),
  992. m_distribution.local(targets[i]));
  993. }
  994. m_base.assign_sources_and_targets_global(
  995. sources, targets, m_distribution.block_size(process_id(m_process_group), numverts),
  996. identity_property_map());
  997. // TODO: set property on m_base?
  998. }
  999. template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
  1000. template<typename Source>
  1001. BOOST_DISTRIB_CSR_GRAPH_TYPE::
  1002. compressed_sparse_row_graph(distributed_construct_inplace_from_sources_and_targets_t,
  1003. std::vector<Source>& sources,
  1004. std::vector<vertex_descriptor>& targets,
  1005. std::vector<edge_bundled>& edge_props,
  1006. vertices_size_type numverts,
  1007. const ProcessGroup& pg,
  1008. const GraphProperty& prop)
  1009. : m_process_group(pg),
  1010. m_distribution(parallel::block(m_process_group, numverts)),
  1011. m_base(m_distribution.block_size(process_id(m_process_group), numverts))
  1012. {
  1013. // Convert linear indices to global indices
  1014. for (edges_size_type i = 0; i < sources.size(); ++i) {
  1015. sources[i] = m_distribution.local(sources[i]);
  1016. targets[i] = make_vertex_descriptor(m_distribution(targets[i]),
  1017. m_distribution.local(targets[i]));
  1018. }
  1019. m_base.assign_sources_and_targets_global(
  1020. sources, targets, edge_props,
  1021. m_distribution.block_size(process_id(m_process_group), numverts),
  1022. identity_property_map());
  1023. // TODO: set property on m_base?
  1024. }
  1025. template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
  1026. template <typename Distribution, typename Source>
  1027. BOOST_DISTRIB_CSR_GRAPH_TYPE::
  1028. compressed_sparse_row_graph(distributed_construct_inplace_from_sources_and_targets_t,
  1029. std::vector<Source>& sources,
  1030. std::vector<vertex_descriptor>& targets,
  1031. std::vector<edge_bundled>& edge_props,
  1032. vertices_size_type numverts,
  1033. const ProcessGroup& pg,
  1034. const Distribution& dist,
  1035. const GraphProperty& prop)
  1036. : m_process_group(pg),
  1037. m_distribution(dist),
  1038. m_base(m_distribution.block_size(process_id(m_process_group), numverts))
  1039. {
  1040. // Convert linear indices to global indices
  1041. for (edges_size_type i = 0; i < sources.size(); ++i) {
  1042. sources[i] = m_distribution.local(sources[i]);
  1043. targets[i] = make_vertex_descriptor(m_distribution(targets[i]),
  1044. m_distribution.local(targets[i]));
  1045. }
  1046. m_base.assign_sources_and_targets_global(
  1047. sources, targets, edge_props,
  1048. m_distribution.block_size(process_id(m_process_group), numverts),
  1049. identity_property_map());
  1050. // TODO: set property on m_base?
  1051. }
  1052. //
  1053. // Old (untagged) ctors, these default to the unsorted sequential ctors
  1054. //
  1055. template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
  1056. template<typename InputIterator>
  1057. BOOST_DISTRIB_CSR_GRAPH_TYPE::
  1058. compressed_sparse_row_graph(InputIterator edge_begin, InputIterator edge_end,
  1059. vertices_size_type numverts,
  1060. const ProcessGroup& pg,
  1061. const GraphProperty& prop)
  1062. : m_process_group(pg),
  1063. m_distribution(parallel::block(m_process_group, numverts)),
  1064. m_base(edges_are_unsorted_global,
  1065. index_to_vertex_iterator<InputIterator, BOOST_DISTRIB_CSR_GRAPH_TYPE>(edge_begin, *this),
  1066. index_to_vertex_iterator<InputIterator, BOOST_DISTRIB_CSR_GRAPH_TYPE>(edge_end, *this),
  1067. m_distribution.block_size(process_id(m_process_group), numverts),
  1068. get(vertex_local, *this),
  1069. local_vertex<csr_vertex_owner_map<process_id_type, vertex_descriptor>,
  1070. process_id_type> (get(vertex_owner, *this), process_id(pg)),
  1071. prop)
  1072. {
  1073. }
  1074. template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
  1075. template<typename InputIterator, typename EdgePropertyIterator>
  1076. BOOST_DISTRIB_CSR_GRAPH_TYPE::
  1077. compressed_sparse_row_graph(InputIterator edge_begin, InputIterator edge_end,
  1078. EdgePropertyIterator ep_iter,
  1079. vertices_size_type numverts,
  1080. const ProcessGroup& pg,
  1081. const GraphProperty& prop)
  1082. : m_process_group(pg),
  1083. m_distribution(parallel::block(m_process_group, numverts)),
  1084. m_base(edges_are_unsorted_global,
  1085. index_to_vertex_iterator<InputIterator, BOOST_DISTRIB_CSR_GRAPH_TYPE>(edge_begin, *this),
  1086. index_to_vertex_iterator<InputIterator, BOOST_DISTRIB_CSR_GRAPH_TYPE>(edge_end, *this),
  1087. ep_iter,
  1088. m_distribution.block_size(process_id(m_process_group), numverts),
  1089. get(vertex_local, *this),
  1090. local_vertex<csr_vertex_owner_map<process_id_type, vertex_descriptor>,
  1091. process_id_type> (get(vertex_owner, *this), process_id(pg)),
  1092. prop)
  1093. {
  1094. }
  1095. template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
  1096. template<typename InputIterator, typename Distribution>
  1097. BOOST_DISTRIB_CSR_GRAPH_TYPE::
  1098. compressed_sparse_row_graph(InputIterator edge_begin, InputIterator edge_end,
  1099. vertices_size_type numverts,
  1100. const ProcessGroup& pg,
  1101. const Distribution& dist,
  1102. const GraphProperty& prop)
  1103. : m_process_group(pg),
  1104. m_distribution(dist),
  1105. m_base(edges_are_unsorted_global,
  1106. index_to_vertex_iterator<InputIterator, BOOST_DISTRIB_CSR_GRAPH_TYPE>(edge_begin, *this),
  1107. index_to_vertex_iterator<InputIterator, BOOST_DISTRIB_CSR_GRAPH_TYPE>(edge_end, *this),
  1108. m_distribution.block_size(process_id(m_process_group), numverts),
  1109. get(vertex_local, *this),
  1110. local_vertex<csr_vertex_owner_map<process_id_type, vertex_descriptor>,
  1111. process_id_type> (get(vertex_owner, *this), process_id(pg)),
  1112. prop)
  1113. {
  1114. }
  1115. template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
  1116. template<typename InputIterator, typename EdgePropertyIterator,
  1117. typename Distribution>
  1118. BOOST_DISTRIB_CSR_GRAPH_TYPE::
  1119. compressed_sparse_row_graph(InputIterator edge_begin, InputIterator edge_end,
  1120. EdgePropertyIterator ep_iter,
  1121. vertices_size_type numverts,
  1122. const ProcessGroup& pg,
  1123. const Distribution& dist,
  1124. const GraphProperty& prop)
  1125. : m_process_group(pg),
  1126. m_distribution(dist),
  1127. m_base(edges_are_unsorted_global,
  1128. index_to_vertex_iterator<InputIterator, BOOST_DISTRIB_CSR_GRAPH_TYPE>(edge_begin, *this),
  1129. index_to_vertex_iterator<InputIterator, BOOST_DISTRIB_CSR_GRAPH_TYPE>(edge_end, *this),
  1130. m_distribution.block_size(process_id(m_process_group), numverts),
  1131. get(vertex_local, *this),
  1132. local_vertex<csr_vertex_owner_map<process_id_type, vertex_descriptor>,
  1133. process_id_type> (get(vertex_owner, *this), process_id(pg)),
  1134. prop)
  1135. {
  1136. }
  1137. // -----------------------------------------------------------------
  1138. // Vertex Global Property Map
  1139. template<typename ProcessID, typename Key>
  1140. class csr_vertex_global_map
  1141. {
  1142. public:
  1143. // -----------------------------------------------------------------
  1144. // Readable Property Map concept requirements
  1145. typedef std::pair<ProcessID, Key> value_type;
  1146. typedef value_type reference;
  1147. typedef Key key_type;
  1148. typedef readable_property_map_tag category;
  1149. };
  1150. template<typename ProcessID, typename Key>
  1151. inline std::pair<ProcessID, Key>
  1152. get(csr_vertex_global_map<ProcessID, Key>,
  1153. typename csr_vertex_global_map<ProcessID, Key>::key_type k)
  1154. {
  1155. const int local_index_bits = sizeof(Key) * CHAR_BIT - processor_bits;
  1156. const Key local_index_mask = Key(-1) >> processor_bits;
  1157. return std::pair<ProcessID, Key>(k >> local_index_bits,
  1158. k & local_index_mask);
  1159. }
  1160. template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
  1161. class property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, vertex_global_t>
  1162. {
  1163. public:
  1164. typedef csr_vertex_global_map<
  1165. typename ProcessGroup::process_id_type,
  1166. typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor> type;
  1167. typedef type const_type;
  1168. };
  1169. template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
  1170. inline
  1171. typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, vertex_global_t>::type
  1172. get(vertex_global_t, BOOST_DISTRIB_CSR_GRAPH_TYPE& g)
  1173. {
  1174. typedef typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, vertex_global_t>
  1175. ::type result_type;
  1176. return result_type();
  1177. }
  1178. template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
  1179. inline
  1180. std::pair<typename ProcessGroup::process_id_type,
  1181. typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor>
  1182. get(vertex_global_t, BOOST_DISTRIB_CSR_GRAPH_TYPE& g,
  1183. typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor k)
  1184. {
  1185. return get(vertex_global,
  1186. const_cast<const BOOST_DISTRIB_CSR_GRAPH_TYPE&>(g),
  1187. k);
  1188. }
  1189. template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
  1190. inline
  1191. typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, vertex_global_t>::const_type
  1192. get(vertex_global_t, const BOOST_DISTRIB_CSR_GRAPH_TYPE& g)
  1193. {
  1194. typedef typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, vertex_global_t>
  1195. ::const_type result_type;
  1196. return result_type();
  1197. }
  1198. template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
  1199. inline
  1200. std::pair<typename ProcessGroup::process_id_type,
  1201. typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor>
  1202. get(vertex_global_t, const BOOST_DISTRIB_CSR_GRAPH_TYPE& g,
  1203. typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor k)
  1204. {
  1205. typedef typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor
  1206. vertex_descriptor;
  1207. typedef std::pair<typename ProcessGroup::process_id_type, vertex_descriptor>
  1208. result_type;
  1209. const int local_index_bits =
  1210. sizeof(vertex_descriptor) * CHAR_BIT - processor_bits;
  1211. const vertex_descriptor local_index_mask =
  1212. vertex_descriptor(-1) >> processor_bits;
  1213. return result_type(k >> local_index_bits, k & local_index_mask);
  1214. }
  1215. // -----------------------------------------------------------------
  1216. // Extra, common functions
  1217. template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
  1218. inline typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor
  1219. vertex(typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertices_size_type i,
  1220. const BOOST_DISTRIB_CSR_GRAPH_TYPE& g)
  1221. {
  1222. return g.make_vertex_descriptor(g.distribution()(i),
  1223. g.distribution().local(i));
  1224. }
  1225. // Unlike for an adjacency_matrix, edge_range and edge take lg(out_degree(i))
  1226. // time
  1227. template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
  1228. inline std::pair<typename BOOST_DISTRIB_CSR_GRAPH_TYPE::out_edge_iterator,
  1229. typename BOOST_DISTRIB_CSR_GRAPH_TYPE::out_edge_iterator>
  1230. edge_range(typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor i,
  1231. typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor j,
  1232. const BOOST_DISTRIB_CSR_GRAPH_TYPE& g)
  1233. {
  1234. typedef typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor Vertex;
  1235. typedef typename BOOST_DISTRIB_CSR_GRAPH_TYPE::edges_size_type EdgeIndex;
  1236. typedef typename std::vector<Vertex>::const_iterator adj_iter;
  1237. typedef typename BOOST_DISTRIB_CSR_GRAPH_TYPE::out_edge_iterator out_edge_iter;
  1238. typedef typename BOOST_DISTRIB_CSR_GRAPH_TYPE::edge_descriptor edge_desc;
  1239. std::pair<adj_iter, adj_iter> raw_adjacencies = adjacent_vertices(i, g);
  1240. std::pair<adj_iter, adj_iter> adjacencies =
  1241. std::equal_range(raw_adjacencies.first, raw_adjacencies.second, j);
  1242. EdgeIndex idx_begin = adjacencies.first - g.base().m_forward.m_column.begin();
  1243. EdgeIndex idx_end = adjacencies.second - g.base().m_forward.m_column.begin();
  1244. return std::make_pair(out_edge_iter(edge_desc(i, idx_begin)),
  1245. out_edge_iter(edge_desc(i, idx_end)));
  1246. }
  1247. template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
  1248. inline std::pair<typename BOOST_DISTRIB_CSR_GRAPH_TYPE::edge_descriptor, bool>
  1249. edge(typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor i,
  1250. typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor j,
  1251. const BOOST_DISTRIB_CSR_GRAPH_TYPE& g)
  1252. {
  1253. typedef typename BOOST_DISTRIB_CSR_GRAPH_TYPE::out_edge_iterator out_edge_iter;
  1254. std::pair<out_edge_iter, out_edge_iter> range = edge_range(i, j, g);
  1255. if (range.first == range.second)
  1256. return std::make_pair(typename BOOST_DISTRIB_CSR_GRAPH_TYPE::edge_descriptor(),
  1257. false);
  1258. else
  1259. return std::make_pair(*range.first, true);
  1260. }
  1261. // A helper that turns requests for property maps for const graphs
  1262. // into property maps for non-const graphs.
  1263. template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS, typename Property>
  1264. class property_map<const BOOST_DISTRIB_CSR_GRAPH_TYPE, Property>
  1265. {
  1266. public:
  1267. typedef typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, Property>
  1268. ::const_type type;
  1269. typedef type const_type;
  1270. };
  1271. // -----------------------------------------------------------------
  1272. // Structural modifiers
  1273. #if 0
  1274. template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
  1275. typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor
  1276. add_vertex(BOOST_DISTRIB_CSR_GRAPH_TYPE& g)
  1277. { return g.add_vertex(); }
  1278. template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
  1279. typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor
  1280. add_vertex(const typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_bundled& p,
  1281. BOOST_DISTRIB_CSR_GRAPH_TYPE& g)
  1282. { return g.add_vertex(p); }
  1283. template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
  1284. typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor
  1285. add_vertices(typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertices_size_type count,
  1286. BOOST_DISTRIB_CSR_GRAPH_TYPE& g)
  1287. { return g.add_vertices(count); }
  1288. template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS, typename InputIterator>
  1289. void
  1290. add_edges(InputIterator first, InputIterator last,
  1291. BOOST_DISTRIB_CSR_GRAPH_TYPE& g)
  1292. { g.add_edges(first, last); }
  1293. template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS, typename InputIterator,
  1294. typename EdgePropertyIterator>
  1295. void
  1296. add_edges(InputIterator first, InputIterator last,
  1297. EdgePropertyIterator ep_iter,
  1298. EdgePropertyIterator ep_iter_end,
  1299. BOOST_DISTRIB_CSR_GRAPH_TYPE& g)
  1300. { return g.add_edges(first, last, ep_iter, ep_iter_end); }
  1301. template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS, typename InputIterator>
  1302. void
  1303. add_edges_sorted(InputIterator first, InputIterator last,
  1304. BOOST_DISTRIB_CSR_GRAPH_TYPE& g)
  1305. { return g.add_edges_sorted(first, last); }
  1306. template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS, typename InputIterator,
  1307. typename EdgePropertyIterator>
  1308. void
  1309. add_edges_sorted(InputIterator first_sorted, InputIterator last_sorted,
  1310. EdgePropertyIterator ep_iter_sorted,
  1311. BOOST_DISTRIB_CSR_GRAPH_TYPE& g)
  1312. { g.add_edges_sorted(first_sorted, last_sorted, ep_iter_sorted); }
  1313. #endif
  1314. // -----------------------------------------------------------------
  1315. // Vertex Owner Property Map
  1316. template<typename ProcessID, typename Key>
  1317. class csr_vertex_owner_map
  1318. {
  1319. public:
  1320. // -----------------------------------------------------------------
  1321. // Readable Property Map concept requirements
  1322. typedef ProcessID value_type;
  1323. typedef value_type reference;
  1324. typedef Key key_type;
  1325. typedef readable_property_map_tag category;
  1326. };
  1327. template<typename ProcessID, typename Key>
  1328. inline ProcessID
  1329. get(csr_vertex_owner_map<ProcessID, Key> pm,
  1330. typename csr_vertex_owner_map<ProcessID, Key>::key_type k)
  1331. {
  1332. const int local_index_bits = sizeof(Key) * CHAR_BIT - processor_bits;
  1333. return k >> local_index_bits;
  1334. }
  1335. template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
  1336. class property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, vertex_owner_t>
  1337. {
  1338. public:
  1339. typedef csr_vertex_owner_map<
  1340. typename ProcessGroup::process_id_type,
  1341. typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor> type;
  1342. typedef type const_type;
  1343. };
  1344. template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
  1345. inline
  1346. typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, vertex_owner_t>::type
  1347. get(vertex_owner_t, BOOST_DISTRIB_CSR_GRAPH_TYPE& g)
  1348. {
  1349. typedef typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, vertex_owner_t>
  1350. ::type result_type;
  1351. return result_type();
  1352. }
  1353. template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
  1354. inline typename ProcessGroup::process_id_type
  1355. get(vertex_owner_t, BOOST_DISTRIB_CSR_GRAPH_TYPE& g,
  1356. typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor k)
  1357. {
  1358. return get(vertex_owner,
  1359. const_cast<const BOOST_DISTRIB_CSR_GRAPH_TYPE&>(g),
  1360. k);
  1361. }
  1362. template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
  1363. inline
  1364. typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, vertex_owner_t>::const_type
  1365. get(vertex_owner_t, const BOOST_DISTRIB_CSR_GRAPH_TYPE& g)
  1366. {
  1367. typedef typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, vertex_owner_t>
  1368. ::const_type result_type;
  1369. return result_type();
  1370. }
  1371. template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
  1372. inline typename ProcessGroup::process_id_type
  1373. get(vertex_owner_t, const BOOST_DISTRIB_CSR_GRAPH_TYPE& g,
  1374. typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor k)
  1375. {
  1376. typedef typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor
  1377. vertex_descriptor;
  1378. const int local_index_bits =
  1379. sizeof(vertex_descriptor) * CHAR_BIT - processor_bits;
  1380. return k >> local_index_bits;
  1381. }
  1382. // -----------------------------------------------------------------
  1383. // Vertex Local Property Map
  1384. template<typename Key>
  1385. class csr_vertex_local_map
  1386. {
  1387. public:
  1388. // -----------------------------------------------------------------
  1389. // Readable Property Map concept requirements
  1390. typedef Key value_type;
  1391. typedef value_type reference;
  1392. typedef Key key_type;
  1393. typedef readable_property_map_tag category;
  1394. };
  1395. template<typename Key>
  1396. inline Key
  1397. get(csr_vertex_local_map<Key> pm,
  1398. typename csr_vertex_local_map<Key>::key_type k)
  1399. {
  1400. const Key local_index_mask = Key(-1) >> processor_bits;
  1401. return k & local_index_mask;
  1402. }
  1403. template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
  1404. class property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, vertex_local_t>
  1405. {
  1406. public:
  1407. typedef csr_vertex_local_map<
  1408. typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor> type;
  1409. typedef type const_type;
  1410. };
  1411. template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
  1412. inline
  1413. typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, vertex_local_t>::type
  1414. get(vertex_local_t, BOOST_DISTRIB_CSR_GRAPH_TYPE& g)
  1415. {
  1416. typedef typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, vertex_local_t>
  1417. ::type result_type;
  1418. return result_type();
  1419. }
  1420. template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
  1421. inline typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor
  1422. get(vertex_local_t, BOOST_DISTRIB_CSR_GRAPH_TYPE& g,
  1423. typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor k)
  1424. {
  1425. return get(vertex_local,
  1426. const_cast<const BOOST_DISTRIB_CSR_GRAPH_TYPE&>(g),
  1427. k);
  1428. }
  1429. template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
  1430. inline
  1431. typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, vertex_local_t>::const_type
  1432. get(vertex_local_t, const BOOST_DISTRIB_CSR_GRAPH_TYPE& g)
  1433. {
  1434. typedef typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, vertex_local_t>
  1435. ::const_type result_type;
  1436. return result_type();
  1437. }
  1438. template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
  1439. inline typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor
  1440. get(vertex_local_t, const BOOST_DISTRIB_CSR_GRAPH_TYPE& g,
  1441. typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor k)
  1442. {
  1443. typedef typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor
  1444. vertex_descriptor;
  1445. const vertex_descriptor local_index_mask =
  1446. vertex_descriptor(-1) >> processor_bits;
  1447. return k & local_index_mask;
  1448. }
  1449. // -----------------------------------------------------------------
  1450. // Vertex Index Property Map
  1451. template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
  1452. class property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, vertex_index_t>
  1453. {
  1454. typedef typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE,
  1455. vertex_global_t>::const_type
  1456. global_map;
  1457. typedef typename BOOST_DISTRIB_CSR_GRAPH_TYPE::process_group_type
  1458. process_group_type;
  1459. typedef property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, vertex_local_t> local;
  1460. public:
  1461. typedef local_property_map<process_group_type,
  1462. global_map,
  1463. typename local::type> type;
  1464. typedef local_property_map<process_group_type,
  1465. global_map,
  1466. typename local::const_type> const_type;
  1467. };
  1468. template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
  1469. inline
  1470. typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, vertex_index_t>::type
  1471. get(vertex_index_t, BOOST_DISTRIB_CSR_GRAPH_TYPE& g)
  1472. {
  1473. typedef typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, vertex_index_t>
  1474. ::type result_type;
  1475. return result_type(g.process_group(), get(vertex_global, g),
  1476. get(vertex_local, g));
  1477. }
  1478. template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
  1479. inline typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertices_size_type
  1480. get(vertex_index_t, BOOST_DISTRIB_CSR_GRAPH_TYPE& g,
  1481. typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor k)
  1482. {
  1483. return get(vertex_local, g, k);
  1484. }
  1485. template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
  1486. inline
  1487. typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, vertex_index_t>::const_type
  1488. get(vertex_index_t, const BOOST_DISTRIB_CSR_GRAPH_TYPE& g)
  1489. {
  1490. typedef typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, vertex_index_t>
  1491. ::const_type result_type;
  1492. return result_type(g.process_group(), get(vertex_global, g),
  1493. get(vertex_local, g));
  1494. }
  1495. template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
  1496. inline typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertices_size_type
  1497. get(vertex_index_t, const BOOST_DISTRIB_CSR_GRAPH_TYPE& g,
  1498. typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor k)
  1499. {
  1500. return get(vertex_local, g, k);
  1501. }
  1502. // -----------------------------------------------------------------
  1503. // Vertex Local Index Property Map
  1504. template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
  1505. class property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, vertex_local_index_t>
  1506. : public property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, vertex_local_t> { };
  1507. template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
  1508. inline
  1509. typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, vertex_local_index_t>::type
  1510. get(vertex_local_index_t, BOOST_DISTRIB_CSR_GRAPH_TYPE& g)
  1511. {
  1512. return get(vertex_local, g);
  1513. }
  1514. template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
  1515. inline typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertices_size_type
  1516. get(vertex_local_index_t, BOOST_DISTRIB_CSR_GRAPH_TYPE& g,
  1517. typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor k)
  1518. {
  1519. return get(vertex_local, g, k);
  1520. }
  1521. template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
  1522. inline
  1523. typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, vertex_local_index_t>::const_type
  1524. get(vertex_local_index_t, const BOOST_DISTRIB_CSR_GRAPH_TYPE& g)
  1525. {
  1526. return get(vertex_local, g);
  1527. }
  1528. template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
  1529. inline typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertices_size_type
  1530. get(vertex_local_index_t, const BOOST_DISTRIB_CSR_GRAPH_TYPE& g,
  1531. typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor k)
  1532. {
  1533. return get(vertex_local, g, k);
  1534. }
  1535. // -----------------------------------------------------------------
  1536. // Edge Global Property Map
  1537. template<typename ProcessID, typename Vertex, typename EdgeIndex>
  1538. class csr_edge_global_map
  1539. {
  1540. public:
  1541. // -----------------------------------------------------------------
  1542. // Readable Property Map concept requirements
  1543. typedef detail::csr_edge_descriptor<Vertex, EdgeIndex> key_type;
  1544. typedef std::pair<ProcessID, detail::csr_edge_descriptor<Vertex, EdgeIndex> > value_type;
  1545. typedef value_type reference;
  1546. typedef readable_property_map_tag category;
  1547. };
  1548. template<typename ProcessID, typename Vertex, typename EdgeIndex>
  1549. inline std::pair<ProcessID, detail::csr_edge_descriptor<Vertex, EdgeIndex> >
  1550. get(csr_edge_global_map<ProcessID, Vertex, EdgeIndex> pm,
  1551. typename csr_edge_global_map<ProcessID, Vertex, EdgeIndex>::key_type k)
  1552. {
  1553. const int local_index_bits = sizeof(Vertex) * CHAR_BIT - processor_bits;
  1554. const Vertex local_index_mask = Vertex(-1) >> processor_bits;
  1555. return std::pair<ProcessID, detail::csr_edge_descriptor<Vertex, EdgeIndex> >
  1556. ((k.src >> local_index_bits),
  1557. detail::csr_edge_descriptor<Vertex, EdgeIndex>(k.src & local_index_mask, k.idx));
  1558. }
  1559. template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
  1560. class property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, edge_global_t>
  1561. {
  1562. public:
  1563. typedef csr_edge_global_map<
  1564. typename ProcessGroup::process_id_type,
  1565. typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor,
  1566. typename BOOST_DISTRIB_CSR_GRAPH_TYPE::edges_size_type> type;
  1567. typedef type const_type;
  1568. };
  1569. template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
  1570. inline
  1571. typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, edge_global_t>::type
  1572. get(edge_global_t, BOOST_DISTRIB_CSR_GRAPH_TYPE& g)
  1573. {
  1574. typedef typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, edge_global_t>
  1575. ::type result_type;
  1576. return result_type();
  1577. }
  1578. template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
  1579. inline
  1580. std::pair<typename ProcessGroup::process_id_type,
  1581. typename BOOST_DISTRIB_CSR_GRAPH_TYPE::base_type::edge_descriptor>
  1582. get(edge_global_t, BOOST_DISTRIB_CSR_GRAPH_TYPE& g,
  1583. typename BOOST_DISTRIB_CSR_GRAPH_TYPE::edge_descriptor k)
  1584. {
  1585. return get(edge_global,
  1586. const_cast<const BOOST_DISTRIB_CSR_GRAPH_TYPE&>(g),
  1587. k);
  1588. }
  1589. template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
  1590. inline
  1591. typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, edge_global_t>::const_type
  1592. get(edge_global_t, const BOOST_DISTRIB_CSR_GRAPH_TYPE& g)
  1593. {
  1594. typedef typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, edge_global_t>
  1595. ::const_type result_type;
  1596. return result_type();
  1597. }
  1598. template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
  1599. inline
  1600. std::pair<typename ProcessGroup::process_id_type,
  1601. typename BOOST_DISTRIB_CSR_GRAPH_TYPE::base_type::edge_descriptor>
  1602. get(edge_global_t, const BOOST_DISTRIB_CSR_GRAPH_TYPE& g,
  1603. typename BOOST_DISTRIB_CSR_GRAPH_TYPE::edge_descriptor k)
  1604. {
  1605. typedef typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor
  1606. vertex_descriptor;
  1607. const int local_index_bits =
  1608. sizeof(vertex_descriptor) * CHAR_BIT - processor_bits;
  1609. const typename BOOST_DISTRIB_CSR_GRAPH_TYPE::edges_size_type local_index_mask =
  1610. typename BOOST_DISTRIB_CSR_GRAPH_TYPE::edges_size_type(-1) >> processor_bits;
  1611. typedef std::pair<typename ProcessGroup::process_id_type,
  1612. typename BOOST_DISTRIB_CSR_GRAPH_TYPE::base_type::edge_descriptor>
  1613. result_type;
  1614. return result_type(k.src >> local_index_bits,
  1615. typename BOOST_DISTRIB_CSR_GRAPH_TYPE::base_type::edge_descriptor
  1616. (k.src & local_index_mask, k.idx));
  1617. }
  1618. // -----------------------------------------------------------------
  1619. // Edge Index Property Map
  1620. template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
  1621. class property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, edge_index_t>
  1622. {
  1623. typedef typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, edge_global_t>
  1624. ::type global_map;
  1625. public:
  1626. typedef local_property_map<
  1627. typename BOOST_DISTRIB_CSR_GRAPH_TYPE::process_group_type,
  1628. global_map,
  1629. typename property_map<typename BOOST_DISTRIB_CSR_GRAPH_TYPE::base_type, edge_index_t>::type
  1630. > type;
  1631. typedef type const_type;
  1632. };
  1633. template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
  1634. inline
  1635. typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, edge_index_t>::type
  1636. get(edge_index_t, BOOST_DISTRIB_CSR_GRAPH_TYPE& g)
  1637. {
  1638. typedef typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, edge_index_t>
  1639. ::type result_type;
  1640. return result_type(g.process_group(), get(edge_global, g),
  1641. get(edge_index, g.base()));
  1642. }
  1643. template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
  1644. inline typename BOOST_DISTRIB_CSR_GRAPH_TYPE::edges_size_type
  1645. get(edge_index_t, BOOST_DISTRIB_CSR_GRAPH_TYPE& g,
  1646. typename BOOST_DISTRIB_CSR_GRAPH_TYPE::edge_descriptor k)
  1647. {
  1648. return k.idx;
  1649. }
  1650. template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
  1651. inline
  1652. typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, edge_index_t>::const_type
  1653. get(edge_index_t, const BOOST_DISTRIB_CSR_GRAPH_TYPE& g)
  1654. {
  1655. typedef typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, edge_index_t>
  1656. ::const_type result_type;
  1657. return result_type(g.process_group(), get(edge_global, g),
  1658. get(edge_index, g.base()));
  1659. }
  1660. template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
  1661. inline typename BOOST_DISTRIB_CSR_GRAPH_TYPE::edges_size_type
  1662. get(edge_index_t, const BOOST_DISTRIB_CSR_GRAPH_TYPE& g,
  1663. typename BOOST_DISTRIB_CSR_GRAPH_TYPE::edge_descriptor k)
  1664. {
  1665. return k.idx;
  1666. }
  1667. template <BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS, typename Tag>
  1668. class property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, Tag> {
  1669. typedef BOOST_DISTRIB_CSR_GRAPH_TYPE graph_type;
  1670. typedef typename graph_type::process_group_type process_group_type;
  1671. typedef typename graph_type::base_type base_graph_type;
  1672. typedef typename property_map<base_graph_type, Tag>::type
  1673. local_pmap;
  1674. typedef typename property_map<base_graph_type, Tag>::const_type
  1675. local_const_pmap;
  1676. typedef graph_traits<graph_type> traits;
  1677. typedef typename graph_traits<base_graph_type>::vertex_descriptor local_vertex;
  1678. typedef typename property_traits<local_pmap>::key_type local_key_type;
  1679. typedef typename property_traits<local_pmap>::value_type value_type;
  1680. typedef typename property_map<graph_type, vertex_global_t>::const_type
  1681. vertex_global_map;
  1682. typedef typename property_map<graph_type, edge_global_t>::const_type
  1683. edge_global_map;
  1684. typedef typename mpl::if_<is_same<typename detail::property_kind_from_graph<base_graph_type, Tag>::type,
  1685. vertex_property_tag>,
  1686. vertex_global_map, edge_global_map>::type
  1687. global_map;
  1688. public:
  1689. typedef ::boost::parallel::distributed_property_map<
  1690. process_group_type, global_map, local_pmap> type;
  1691. typedef ::boost::parallel::distributed_property_map<
  1692. process_group_type, global_map, local_const_pmap> const_type;
  1693. };
  1694. template <BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS, typename Tag>
  1695. typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, Tag>::type
  1696. get(Tag tag, BOOST_DISTRIB_CSR_GRAPH_TYPE& g)
  1697. {
  1698. typedef BOOST_DISTRIB_CSR_GRAPH_TYPE Graph;
  1699. typedef typename property_map<Graph, Tag>::type result_type;
  1700. typedef typename property_traits<result_type>::value_type value_type;
  1701. typedef typename property_reduce<Tag>::template apply<value_type>
  1702. reduce;
  1703. typedef typename mpl::if_<is_same<typename detail::property_kind_from_graph<Graph, Tag>::type,
  1704. vertex_property_tag>,
  1705. vertex_global_t, edge_global_t>::type
  1706. global_map_t;
  1707. return result_type(g.process_group(), get(global_map_t(), g),
  1708. get(tag, g.base()), reduce());
  1709. }
  1710. template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS, typename Tag>
  1711. typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, Tag>::const_type
  1712. get(Tag tag, const BOOST_DISTRIB_CSR_GRAPH_TYPE& g)
  1713. {
  1714. typedef BOOST_DISTRIB_CSR_GRAPH_TYPE Graph;
  1715. typedef typename property_map<Graph, Tag>::const_type result_type;
  1716. typedef typename property_traits<result_type>::value_type value_type;
  1717. typedef typename property_reduce<Tag>::template apply<value_type>
  1718. reduce;
  1719. typedef typename property_traits<result_type>::key_type descriptor;
  1720. typedef typename graph_traits<Graph>::vertex_descriptor vertex_descriptor;
  1721. typedef typename mpl::if_<is_same<descriptor, vertex_descriptor>,
  1722. vertex_global_t, edge_global_t>::type
  1723. global_map_t;
  1724. return result_type(g.process_group(), get(global_map_t(), g),
  1725. get(tag, g.base()), reduce());
  1726. }
  1727. namespace mpi {
  1728. template<typename Vertex, typename EdgeIndex>
  1729. struct is_mpi_datatype<boost::detail::csr_edge_descriptor<Vertex, EdgeIndex> >
  1730. : mpl::true_ { };
  1731. }
  1732. namespace serialization {
  1733. template<typename Vertex, typename EdgeIndex>
  1734. struct is_bitwise_serializable<boost::detail::csr_edge_descriptor<Vertex, EdgeIndex> >
  1735. : mpl::true_ { };
  1736. template<typename Vertex, typename EdgeIndex>
  1737. struct implementation_level<boost::detail::csr_edge_descriptor<Vertex, EdgeIndex> >
  1738. : mpl::int_<object_serializable> {} ;
  1739. template<typename Vertex, typename EdgeIndex>
  1740. struct tracking_level<boost::detail::csr_edge_descriptor<Vertex, EdgeIndex> >
  1741. : mpl::int_<track_never> {} ;
  1742. }
  1743. } // end namespace boost
  1744. #endif // BOOST_GRAPH_DISTRIBUTED_CSR_HPP