compressed_sparse_row_graph.hpp 80 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988
  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