1 // Copyright (C) 2006 The Trustees of Indiana University.
3 // Use, modification and distribution is subject to the Boost Software
4 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
5 // http://www.boost.org/LICENSE_1_0.txt)
7 // Authors: Douglas Gregor
11 // Distributed compressed sparse row graph type
13 #ifndef BOOST_GRAPH_DISTRIBUTED_CSR_HPP
14 #define BOOST_GRAPH_DISTRIBUTED_CSR_HPP
16 #ifndef BOOST_GRAPH_USE_MPI
17 #error "Parallel BGL files should not be included unless <boost/graph/use_mpi.hpp> has been included"
20 #include <boost/assert.hpp>
21 #include <boost/graph/compressed_sparse_row_graph.hpp>
22 #include <boost/graph/distributed/selector.hpp>
23 #include <boost/mpl/if.hpp>
24 #include <boost/type_traits/is_same.hpp>
25 #include <boost/graph/distributed/concepts.hpp>
26 #include <boost/graph/parallel/properties.hpp>
27 #include <boost/graph/parallel/distribution.hpp>
28 #include <boost/property_map/parallel/local_property_map.hpp>
29 #include <boost/property_map/parallel/distributed_property_map.hpp>
33 // Distributed and sequential inplace ctors have the same signature so
34 // we need a separate tag for distributed inplace ctors
35 enum distributed_construct_inplace_from_sources_and_targets_t
36 {distributed_construct_inplace_from_sources_and_targets};
38 // The number of bits we reserve for the processor ID.
39 // DPG TBD: This is a hack. It will eventually be a run-time quantity.
40 static const int processor_bits = 8;
42 // Tag class for a distributed CSR graph
43 struct distributed_csr_tag
44 : public virtual distributed_graph_tag,
45 public virtual distributed_vertex_list_graph_tag,
46 public virtual distributed_edge_list_graph_tag,
47 public virtual incidence_graph_tag,
48 public virtual adjacency_graph_tag {};
50 template<typename VertexProperty, typename EdgeProperty,
51 typename GraphProperty, typename ProcessGroup, typename InVertex,
52 typename InDistribution, typename InEdgeIndex>
53 class compressed_sparse_row_graph<
54 directedS, VertexProperty, EdgeProperty, GraphProperty,
55 distributedS<ProcessGroup, InVertex, InDistribution>,
58 typedef compressed_sparse_row_graph self_type;
62 * Determine the type used to represent vertices in the graph. If
63 * the user has overridden the default, use the user's
64 * parameter. Otherwise, fall back to std::size_t.
66 typedef typename mpl::if_<is_same<InVertex, defaultS>,
68 InVertex>::type Vertex;
71 * Determine the type used to represent edges in the graph. If
72 * the user has overridden the default (which is to be the same as
73 * the distributed vertex selector type), use the user's
74 * parameter. Otherwise, fall back to the value of @c Vertex.
76 typedef typename mpl::if_<is_same<InEdgeIndex,
77 distributedS<ProcessGroup, InVertex,
80 InEdgeIndex>::type EdgeIndex;
84 * The type of the CSR graph that will be stored locally.
86 typedef compressed_sparse_row_graph<directedS, VertexProperty, EdgeProperty,
87 GraphProperty, Vertex, EdgeIndex>
90 // -----------------------------------------------------------------
91 // Graph concept requirements
92 typedef Vertex vertex_descriptor;
93 typedef typename graph_traits<base_type>::edge_descriptor edge_descriptor;
94 typedef directed_tag directed_category;
95 typedef allow_parallel_edge_tag edge_parallel_category;
96 typedef distributed_csr_tag traversal_category;
97 static vertex_descriptor null_vertex();
99 // -----------------------------------------------------------------
100 // Distributed Vertex List Graph concept requirements
101 typedef Vertex vertices_size_type;
102 class vertex_iterator;
104 // -----------------------------------------------------------------
105 // Distributed Edge List Graph concept requirements
106 typedef EdgeIndex edges_size_type;
109 // -----------------------------------------------------------------
110 // Incidence Graph concept requirements
111 typedef typename graph_traits<base_type>::out_edge_iterator
113 typedef typename graph_traits<base_type>::degree_size_type
116 // -----------------------------------------------------------------
117 // Adjacency Graph concept requirements
118 typedef typename graph_traits<base_type>::adjacency_iterator
121 // Note: This graph type does not model Bidirectional Graph.
122 // However, this typedef is required to satisfy graph_traits.
123 typedef void in_edge_iterator;
125 // -----------------------------------------------------------------
126 // Distributed Container concept requirements
127 typedef ProcessGroup process_group_type;
128 typedef boost::parallel::variant_distribution<process_group_type, Vertex>
131 // -----------------------------------------------------------------
133 // NOTE: This graph type does not have old-style graph properties. It only
135 typedef no_property vertex_property_type;
136 typedef no_property edge_property_type;
137 typedef no_property graph_property_type;
138 typedef typename mpl::if_<is_void<VertexProperty>,
140 VertexProperty>::type vertex_bundled;
141 typedef typename mpl::if_<is_void<EdgeProperty>,
143 EdgeProperty>::type edge_bundled;
144 typedef typename mpl::if_<is_void<GraphProperty>,
146 GraphProperty>::type graph_bundled;
148 // -----------------------------------------------------------------
150 typedef typename ProcessGroup::process_id_type process_id_type;
152 // -----------------------------------------------------------------
153 // Graph constructors
154 compressed_sparse_row_graph(const ProcessGroup& pg = ProcessGroup())
155 : m_process_group(pg), m_distribution(parallel::block(pg, 0)) {}
157 compressed_sparse_row_graph(const GraphProperty& prop,
158 const ProcessGroup& pg = ProcessGroup())
159 : m_process_group(pg), m_distribution(parallel::block(pg, 0)) {}
161 compressed_sparse_row_graph(vertices_size_type numverts,
162 const ProcessGroup& pg = ProcessGroup())
163 : m_process_group(pg), m_distribution(parallel::block(pg, 0)),
167 compressed_sparse_row_graph(vertices_size_type numverts,
168 const GraphProperty& prop,
169 const ProcessGroup& pg = ProcessGroup())
170 : m_process_group(pg), m_distribution(parallel::block(pg, 0)),
174 template <typename Distribution>
175 compressed_sparse_row_graph(vertices_size_type numverts,
176 const ProcessGroup& pg,
177 const Distribution& dist)
178 : m_process_group(pg), m_distribution(dist), m_base(numverts) {}
180 template <typename Distribution>
181 compressed_sparse_row_graph(vertices_size_type numverts,
182 const GraphProperty& prop,
183 const ProcessGroup& pg,
184 const Distribution& dist)
185 : m_process_group(pg), m_distribution(dist), m_base(numverts) {}
187 template <typename InputIterator>
188 compressed_sparse_row_graph(edges_are_unsorted_t,
189 InputIterator edge_begin, InputIterator edge_end,
190 vertices_size_type numverts,
191 const ProcessGroup& pg = ProcessGroup(),
192 const GraphProperty& prop = GraphProperty());
194 template <typename InputIterator, typename Distribution>
195 compressed_sparse_row_graph(edges_are_unsorted_t,
196 InputIterator edge_begin, InputIterator edge_end,
197 vertices_size_type numverts,
198 const ProcessGroup& pg,
199 const Distribution& dist,
200 const GraphProperty& prop = GraphProperty());
202 template <typename InputIterator, typename EdgePropertyIterator>
203 compressed_sparse_row_graph(edges_are_unsorted_t,
204 InputIterator edge_begin, InputIterator edge_end,
205 EdgePropertyIterator ep_iter,
206 vertices_size_type numverts,
207 const ProcessGroup& pg = ProcessGroup(),
208 const GraphProperty& prop = GraphProperty());
210 template <typename InputIterator, typename EdgePropertyIterator,
211 typename Distribution>
212 compressed_sparse_row_graph(edges_are_unsorted_t,
213 InputIterator edge_begin, InputIterator edge_end,
214 EdgePropertyIterator ep_iter,
215 vertices_size_type numverts,
216 const ProcessGroup& pg,
217 const Distribution& dist,
218 const GraphProperty& prop = GraphProperty());
220 template <typename InputIterator>
221 compressed_sparse_row_graph(edges_are_sorted_t,
222 InputIterator edge_begin, InputIterator edge_end,
223 vertices_size_type numverts,
224 edges_size_type numedges = 0,
225 const ProcessGroup& pg = ProcessGroup(),
226 const GraphProperty& prop = GraphProperty());
228 template <typename InputIterator, typename Distribution>
229 compressed_sparse_row_graph(edges_are_sorted_t,
230 InputIterator edge_begin, InputIterator edge_end,
231 vertices_size_type numverts,
232 const ProcessGroup& pg,
233 const Distribution& dist,
234 const GraphProperty& prop = GraphProperty());
236 template <typename InputIterator, typename EdgePropertyIterator>
237 compressed_sparse_row_graph(edges_are_sorted_t,
238 InputIterator edge_begin, InputIterator edge_end,
239 EdgePropertyIterator ep_iter,
240 vertices_size_type numverts,
241 edges_size_type numedges = 0,
242 const ProcessGroup& pg = ProcessGroup(),
243 const GraphProperty& prop = GraphProperty());
245 template <typename InputIterator, typename EdgePropertyIterator,
246 typename Distribution>
247 compressed_sparse_row_graph(edges_are_sorted_t,
248 InputIterator edge_begin, InputIterator edge_end,
249 EdgePropertyIterator ep_iter,
250 vertices_size_type numverts,
251 const ProcessGroup& pg,
252 const Distribution& dist,
253 const GraphProperty& prop = GraphProperty());
255 template <typename MultiPassInputIterator>
256 compressed_sparse_row_graph(edges_are_unsorted_multi_pass_t,
257 MultiPassInputIterator edge_begin,
258 MultiPassInputIterator edge_end,
259 vertices_size_type numverts,
260 const ProcessGroup& pg = ProcessGroup(),
261 const GraphProperty& prop = GraphProperty());
263 template <typename MultiPassInputIterator, typename Distribution>
264 compressed_sparse_row_graph(edges_are_unsorted_multi_pass_t,
265 MultiPassInputIterator edge_begin,
266 MultiPassInputIterator edge_end,
267 vertices_size_type numverts,
268 const ProcessGroup& pg,
269 const Distribution& dist,
270 const GraphProperty& prop = GraphProperty());
272 template <typename MultiPassInputIterator, typename EdgePropertyIterator>
273 compressed_sparse_row_graph(edges_are_unsorted_multi_pass_t,
274 MultiPassInputIterator edge_begin,
275 MultiPassInputIterator edge_end,
276 EdgePropertyIterator ep_iter,
277 vertices_size_type numverts,
278 const ProcessGroup& pg = ProcessGroup(),
279 const GraphProperty& prop = GraphProperty());
281 template <typename MultiPassInputIterator, typename EdgePropertyIterator,
282 typename Distribution>
283 compressed_sparse_row_graph(edges_are_unsorted_multi_pass_t,
284 MultiPassInputIterator edge_begin,
285 MultiPassInputIterator edge_end,
286 EdgePropertyIterator ep_iter,
287 vertices_size_type numverts,
288 const ProcessGroup& pg,
289 const Distribution& dist,
290 const GraphProperty& prop = GraphProperty());
292 template <typename Source>
293 compressed_sparse_row_graph(distributed_construct_inplace_from_sources_and_targets_t,
294 std::vector<Source>& sources,
295 std::vector<vertex_descriptor>& targets,
296 vertices_size_type numverts,
297 const ProcessGroup& pg = ProcessGroup(),
298 const GraphProperty& prop = GraphProperty());
300 template <typename Distribution, typename Source>
301 compressed_sparse_row_graph(distributed_construct_inplace_from_sources_and_targets_t,
302 std::vector<Source>& sources,
303 std::vector<vertex_descriptor>& targets,
304 vertices_size_type numverts,
305 const ProcessGroup& pg,
306 const Distribution& dist,
307 const GraphProperty& prop = GraphProperty());
309 template <typename Source>
310 compressed_sparse_row_graph(distributed_construct_inplace_from_sources_and_targets_t,
311 std::vector<Source>& sources,
312 std::vector<vertex_descriptor>& targets,
313 std::vector<edge_bundled>& edge_props,
314 vertices_size_type numverts,
315 const ProcessGroup& pg = ProcessGroup(),
316 const GraphProperty& prop = GraphProperty());
318 template <typename Distribution, typename Source>
319 compressed_sparse_row_graph(distributed_construct_inplace_from_sources_and_targets_t,
320 std::vector<Source>& sources,
321 std::vector<vertex_descriptor>& targets,
322 std::vector<edge_bundled>& edge_props,
323 vertices_size_type numverts,
324 const ProcessGroup& pg,
325 const Distribution& dist,
326 const GraphProperty& prop = GraphProperty());
328 template<typename InputIterator>
329 compressed_sparse_row_graph(InputIterator edge_begin, InputIterator edge_end,
330 vertices_size_type numverts,
331 const ProcessGroup& pg = ProcessGroup(),
332 const GraphProperty& prop = GraphProperty());
334 template<typename InputIterator, typename EdgePropertyIterator>
335 compressed_sparse_row_graph(InputIterator edge_begin, InputIterator edge_end,
336 EdgePropertyIterator ep_iter,
337 vertices_size_type numverts,
338 const ProcessGroup& pg = ProcessGroup(),
339 const GraphProperty& prop = GraphProperty());
341 template<typename InputIterator, typename Distribution>
342 compressed_sparse_row_graph(InputIterator edge_begin, InputIterator edge_end,
343 vertices_size_type numverts,
344 const ProcessGroup& pg,
345 const Distribution& dist,
346 const GraphProperty& prop = GraphProperty());
348 template<typename InputIterator, typename EdgePropertyIterator,
349 typename Distribution>
350 compressed_sparse_row_graph(InputIterator edge_begin, InputIterator edge_end,
351 EdgePropertyIterator ep_iter,
352 vertices_size_type numverts,
353 const ProcessGroup& pg,
354 const Distribution& dist,
355 const GraphProperty& prop = GraphProperty());
357 base_type& base() { return m_base; }
358 const base_type& base() const { return m_base; }
360 process_group_type process_group() const { return m_process_group.base(); }
362 distribution_type& distribution() { return m_distribution; }
363 const distribution_type& distribution() const { return m_distribution; }
365 // Directly access a vertex or edge bundle
366 vertex_bundled& operator[](vertex_descriptor v)
368 return get(vertex_bundle, *this, v);
371 const vertex_bundled& operator[](vertex_descriptor v) const
373 return get(vertex_bundle, *this, v);
376 edge_bundled& operator[](edge_descriptor e)
378 return get(edge_bundle, *this, e);
381 const edge_bundled& operator[](edge_descriptor e) const
383 return get(edge_bundle, *this, e);
386 // Create a vertex descriptor from a process ID and a local index.
388 make_vertex_descriptor(process_id_type p, vertex_descriptor v) const
390 vertex_descriptor vertex_local_index_bits =
391 sizeof(vertex_descriptor) * CHAR_BIT - processor_bits;
392 return v | ((vertex_descriptor)p << vertex_local_index_bits);
395 // Convert a local vertex descriptor into a global vertex descriptor
396 vertex_descriptor local_to_global_vertex(vertex_descriptor v) const
398 return make_vertex_descriptor(process_id(m_process_group), v);
401 // Structural modification
402 vertex_descriptor add_vertex()
404 typename graph_traits<base_type>::vertex_descriptor v
405 = boost::add_vertex(m_base);
407 return make_vertex_descriptor(process_id(m_process_group), v);
410 vertex_descriptor add_vertex(const vertex_bundled& p)
412 typename graph_traits<base_type>::vertex_descriptor v
413 = boost::add_vertex(m_base, p);
415 return make_vertex_descriptor(process_id(m_process_group), v);
418 vertex_descriptor add_vertices(vertices_size_type count)
420 typename graph_traits<base_type>::vertex_descriptor v
421 = boost::add_vertices(count, m_base);
423 return make_vertex_descriptor(process_id(m_process_group), v);
426 template <typename InputIterator>
428 add_edges(InputIterator first, InputIterator last)
429 { boost::add_edges_global(first, last, get(vertex_local, *this), m_base); }
431 template <typename InputIterator, typename EdgePropertyIterator>
433 add_edges(InputIterator first, InputIterator last,
434 EdgePropertyIterator ep_iter,
435 EdgePropertyIterator ep_iter_end)
436 { boost::add_edges_global(first, last, ep_iter, ep_iter_end,
437 get(vertex_local, *this), m_base); }
439 template <typename InputIterator>
441 add_edges_sorted(InputIterator first, InputIterator last)
442 { boost::add_edges_sorted_global(first, last,
443 get(vertex_local, *this), m_base); }
445 template <typename InputIterator, typename EdgePropertyIterator>
447 add_edges_sorted(InputIterator first_sorted, InputIterator last_sorted,
448 EdgePropertyIterator ep_iter_sorted)
449 { boost::add_edges_sorted_global(first_sorted, last_sorted, ep_iter_sorted,
450 get(vertex_local, *this), m_base); }
453 ProcessGroup m_process_group;
454 distribution_type m_distribution;
458 /** @brief Helper macro containing the template parameters for the
459 * distributed CSR graph.
461 * This macro contains all of the template parameters needed for the
462 * distributed compressed_sparse_row graph type. It is used to reduce
463 * the amount of typing required to declare free functions for this
466 #define BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS \
467 typename VertexProperty, typename EdgeProperty, \
468 typename GraphProperty, typename ProcessGroup, typename InVertex, \
469 typename InDistribution, typename InEdgeIndex
471 /** @brief Helper macro containing the typical instantiation of the
472 * distributed CSR graph.
474 * This macro contains an instantiation of the distributed CSR graph
475 * type using the typical template parameters names (e.g., those
476 * provided by the macro @c
477 * BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS). It is used to reduce
478 * the amount of typing required to declare free functions for this
481 #define BOOST_DISTRIB_CSR_GRAPH_TYPE \
482 compressed_sparse_row_graph< \
483 directedS, VertexProperty, EdgeProperty, GraphProperty, \
484 distributedS<ProcessGroup, InVertex, InDistribution>, \
487 // -----------------------------------------------------------------
488 // Graph concept operations
489 template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
490 inline typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor
491 BOOST_DISTRIB_CSR_GRAPH_TYPE::null_vertex()
493 return graph_traits<base_type>::null_vertex();
496 // -----------------------------------------------------------------
497 // Incidence Graph concept operations
498 template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
499 inline typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor
500 source(typename BOOST_DISTRIB_CSR_GRAPH_TYPE::edge_descriptor e,
501 const BOOST_DISTRIB_CSR_GRAPH_TYPE&)
504 template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
505 inline typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor
506 target(typename BOOST_DISTRIB_CSR_GRAPH_TYPE::edge_descriptor e,
507 const BOOST_DISTRIB_CSR_GRAPH_TYPE& g)
508 { return target(e, g.base()); }
510 template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
511 inline std::pair<typename BOOST_DISTRIB_CSR_GRAPH_TYPE::out_edge_iterator,
512 typename BOOST_DISTRIB_CSR_GRAPH_TYPE::out_edge_iterator>
513 out_edges(typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor u,
514 const BOOST_DISTRIB_CSR_GRAPH_TYPE& g)
516 typedef typename BOOST_DISTRIB_CSR_GRAPH_TYPE::edges_size_type
518 typedef typename BOOST_DISTRIB_CSR_GRAPH_TYPE::edge_descriptor ed;
519 typedef typename BOOST_DISTRIB_CSR_GRAPH_TYPE::out_edge_iterator it;
520 edges_size_type u_local = get(vertex_local, g, u);
521 edges_size_type u_row_start = g.base().m_forward.m_rowstart[u_local];
522 edges_size_type next_row_start = g.base().m_forward.m_rowstart[u_local + 1];
523 return std::make_pair(it(ed(u, u_row_start)),
524 it(ed(u, (std::max)(u_row_start, next_row_start))));
527 template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
528 inline typename BOOST_DISTRIB_CSR_GRAPH_TYPE::degree_size_type
529 out_degree(typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor u,
530 const BOOST_DISTRIB_CSR_GRAPH_TYPE& g)
532 return out_degree(get(vertex_local, g, u), g.base());
535 // -----------------------------------------------------------------
536 // DistributedGraph concept requirements
537 template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
538 void synchronize(const BOOST_DISTRIB_CSR_GRAPH_TYPE& g)
540 synchronize(g.process_group());
543 template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
545 process_group(const BOOST_DISTRIB_CSR_GRAPH_TYPE& g)
546 { return g.process_group(); }
549 // -----------------------------------------------------------------
550 // Adjacency Graph concept requirements
551 template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
552 inline std::pair<typename BOOST_DISTRIB_CSR_GRAPH_TYPE::adjacency_iterator,
553 typename BOOST_DISTRIB_CSR_GRAPH_TYPE::adjacency_iterator>
554 adjacent_vertices(typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor u,
555 const BOOST_DISTRIB_CSR_GRAPH_TYPE& g)
557 return adjacent_vertices(get(vertex_local, g, u), g.base());
560 // -----------------------------------------------------------------
561 // Distributed Vertex List Graph concept operations
562 template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
563 class BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_iterator
564 : public iterator_adaptor<vertex_iterator,
565 counting_iterator<Vertex>,
567 random_access_traversal_tag,
570 typedef iterator_adaptor<vertex_iterator,
571 counting_iterator<Vertex>,
573 random_access_traversal_tag,
578 explicit vertex_iterator(Vertex v, const self_type* graph)
579 : inherited(counting_iterator<Vertex>(v)), graph(graph) { }
581 Vertex dereference() const
583 return graph->local_to_global_vertex(*(this->base_reference()));
586 friend class iterator_core_access;
589 const self_type* graph;
592 template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
593 inline typename BOOST_DISTRIB_CSR_GRAPH_TYPE::degree_size_type
594 num_vertices(const BOOST_DISTRIB_CSR_GRAPH_TYPE& g)
596 return num_vertices(g.base());
599 template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
600 inline std::pair<typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_iterator,
601 typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_iterator>
602 vertices(const BOOST_DISTRIB_CSR_GRAPH_TYPE& g)
604 typedef typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_iterator
606 return std::make_pair(vertex_iterator(0, &g),
607 vertex_iterator(num_vertices(g), &g));
610 // -----------------------------------------------------------------
611 // Distributed Edge List Graph concept operations
612 template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
613 class BOOST_DISTRIB_CSR_GRAPH_TYPE::edge_iterator
616 typedef std::forward_iterator_tag iterator_category;
617 typedef edge_descriptor value_type;
619 typedef const edge_descriptor* pointer;
621 typedef edge_descriptor reference;
622 typedef typename int_t<CHAR_BIT * sizeof(EdgeIndex)>::fast difference_type;
624 edge_iterator() : graph(0), current_edge(), end_of_this_vertex(0) {}
626 edge_iterator(const compressed_sparse_row_graph& graph,
627 edge_descriptor current_edge,
628 EdgeIndex end_of_this_vertex)
629 : graph(&graph), local_src(current_edge.src), current_edge(current_edge),
630 end_of_this_vertex(end_of_this_vertex)
632 // The edge that comes in has a local source vertex. Make it global.
633 current_edge.src = graph.local_to_global_vertex(current_edge.src);
636 // From InputIterator
637 reference operator*() const { return current_edge; }
638 pointer operator->() const { return ¤t_edge; }
640 bool operator==(const edge_iterator& o) const {
641 return current_edge == o.current_edge;
643 bool operator!=(const edge_iterator& o) const {
644 return current_edge != o.current_edge;
647 edge_iterator& operator++()
650 while (current_edge.idx == end_of_this_vertex && local_src < num_vertices(*graph)-1) {
652 current_edge.src = graph->local_to_global_vertex(local_src);
653 end_of_this_vertex = graph->base().m_forward.m_rowstart[local_src + 1];
658 edge_iterator operator++(int) {
659 edge_iterator temp = *this;
665 const compressed_sparse_row_graph* graph;
667 edge_descriptor current_edge;
668 EdgeIndex end_of_this_vertex;
671 template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
672 inline typename BOOST_DISTRIB_CSR_GRAPH_TYPE::edges_size_type
673 num_edges(const BOOST_DISTRIB_CSR_GRAPH_TYPE& g)
675 return g.base().m_forward.m_column.size();
678 template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
679 std::pair<typename BOOST_DISTRIB_CSR_GRAPH_TYPE::edge_iterator,
680 typename BOOST_DISTRIB_CSR_GRAPH_TYPE::edge_iterator>
681 edges(const BOOST_DISTRIB_CSR_GRAPH_TYPE& g)
683 typedef typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor Vertex;
684 typedef typename BOOST_DISTRIB_CSR_GRAPH_TYPE::edge_iterator ei;
685 typedef typename BOOST_DISTRIB_CSR_GRAPH_TYPE::edge_descriptor edgedesc;
686 if (g.base().m_forward.m_rowstart.size() == 1 ||
687 g.base().m_forward.m_column.empty()) {
688 return std::make_pair(ei(), ei());
690 // Find the first vertex that has outgoing edges
692 while (g.base().m_forward.m_rowstart[src + 1] == 0) ++src;
693 return std::make_pair(ei(g, edgedesc(src, 0), g.base().m_forward.m_rowstart[src + 1]),
694 ei(g, edgedesc(num_vertices(g), g.base().m_forward.m_column.size()), 0));
698 // -----------------------------------------------------------------
699 // Graph constructors
701 // Returns true if a vertex belongs to a process according to a distribution
702 template <typename OwnerMap, typename ProcessId>
703 struct local_vertex {
705 local_vertex(OwnerMap owner, ProcessId id)
706 : owner(owner), id(id) {}
708 template <typename Vertex>
709 bool operator()(Vertex x)
710 { return get(owner, x) == id; }
712 template <typename Vertex>
713 bool operator()(Vertex x) const
714 { return get(owner, x) == id; }
721 // Returns true if a vertex belongs to a process according to a distribution
722 template <typename OwnerMap, typename ProcessId>
725 local_edge(OwnerMap owner, ProcessId id)
726 : owner(owner), id(id) {}
728 template <typename Vertex>
729 bool operator()(std::pair<Vertex, Vertex>& x)
730 { return get(owner, x.first) == id; }
732 template <typename Vertex>
733 bool operator()(const std::pair<Vertex, Vertex>& x) const
734 { return get(owner, x.first) == id; }
741 // Turns an index iterator into a vertex iterator
742 template<typename IndexIterator, typename Graph>
743 class index_to_vertex_iterator {
746 typedef std::input_iterator_tag iterator_category;
747 typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
748 typedef std::pair<Vertex, Vertex> value_type;
749 typedef const value_type& reference;
750 typedef const value_type* pointer;
751 typedef void difference_type;
753 index_to_vertex_iterator(IndexIterator index,
755 : index(index), g(g), current(to_edge(*index)) {}
757 reference operator*() { current = to_edge(*index); return current; }
758 pointer operator->() { current = to_edge(*index); return ¤t; }
760 index_to_vertex_iterator& operator++()
766 index_to_vertex_iterator operator++(int)
768 index_to_vertex_iterator temp(*this);
773 bool operator==(const index_to_vertex_iterator& other) const
774 { return index == other.index; }
776 bool operator!=(const index_to_vertex_iterator& other) const
777 { return !(*this == other); }
780 value_type to_edge(const typename std::iterator_traits<IndexIterator>::value_type& x)
781 { return std::make_pair(vertex(x.first, g), vertex(x.second, g)); }
788 template <typename Distribution, typename Graph>
789 struct index_to_vertex_func {
791 typedef typename boost::graph_traits<Graph>::vertex_descriptor vertex_descriptor;
792 typedef typename boost::graph_traits<Graph>::vertices_size_type vertices_size_type;
793 typedef std::pair<vertex_descriptor, vertex_descriptor> result_type;
794 typedef std::pair<vertices_size_type, vertices_size_type> base_iterator_type;
796 index_to_vertex_func(const Distribution& dist, const Graph& g)
797 : dist(dist), g(g) {}
800 result_type operator()(const base_iterator_type& p) const
802 return std::make_pair(vertex(p.first, g), vertex(p.second, g));
806 const Distribution& dist;
810 // NGE: This method only works with iterators that have a difference_type,
811 // the index_to_vertex_iterator class above is retained for compatibility
812 // with BGL generators which have no difference_type
813 template <typename IndexIterator, typename Distribution, typename Graph>
814 boost::transform_iterator<index_to_vertex_func<Distribution, Graph>, IndexIterator>
815 make_index_to_vertex_iterator(IndexIterator it, const Distribution& dist,
817 return boost::make_transform_iterator(
818 it, index_to_vertex_func<Distribution, Graph>(dist, g));
821 // Forward declaration of csr_vertex_owner_map
822 template<typename ProcessID, typename Key> class csr_vertex_owner_map;
824 template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
825 template<typename InputIterator>
826 BOOST_DISTRIB_CSR_GRAPH_TYPE::
827 compressed_sparse_row_graph(edges_are_unsorted_t,
828 InputIterator edge_begin, InputIterator edge_end,
829 vertices_size_type numverts,
830 const ProcessGroup& pg,
831 const GraphProperty& prop)
832 : m_process_group(pg),
833 m_distribution(parallel::block(m_process_group, numverts)),
834 m_base(edges_are_unsorted_global,
835 index_to_vertex_iterator<InputIterator, BOOST_DISTRIB_CSR_GRAPH_TYPE>(edge_begin, *this),
836 index_to_vertex_iterator<InputIterator, BOOST_DISTRIB_CSR_GRAPH_TYPE>(edge_end, *this),
837 m_distribution.block_size(process_id(m_process_group), numverts),
838 get(vertex_local, *this),
839 local_vertex<csr_vertex_owner_map<process_id_type, vertex_descriptor>,
840 process_id_type> (get(vertex_owner, *this), process_id(pg)),
844 template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
845 template <typename InputIterator, typename Distribution>
846 BOOST_DISTRIB_CSR_GRAPH_TYPE::
847 compressed_sparse_row_graph(edges_are_unsorted_t,
848 InputIterator edge_begin, InputIterator edge_end,
849 vertices_size_type numverts,
850 const ProcessGroup& pg,
851 const Distribution& dist,
852 const GraphProperty& prop)
853 : m_process_group(pg),
854 m_distribution(dist),
855 m_base(edges_are_unsorted_global,
856 index_to_vertex_iterator<InputIterator, BOOST_DISTRIB_CSR_GRAPH_TYPE>(edge_begin, *this),
857 index_to_vertex_iterator<InputIterator, BOOST_DISTRIB_CSR_GRAPH_TYPE>(edge_end, *this),
858 m_distribution.block_size(process_id(m_process_group), numverts),
859 get(vertex_local, *this),
860 local_vertex<csr_vertex_owner_map<process_id_type, vertex_descriptor>,
861 process_id_type> (get(vertex_owner, *this), process_id(pg)),
865 template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
866 template<typename InputIterator, typename EdgePropertyIterator>
867 BOOST_DISTRIB_CSR_GRAPH_TYPE::
868 compressed_sparse_row_graph(edges_are_unsorted_t,
869 InputIterator edge_begin, InputIterator edge_end,
870 EdgePropertyIterator ep_iter,
871 vertices_size_type numverts,
872 const ProcessGroup& pg,
873 const GraphProperty& prop)
874 : m_process_group(pg),
875 m_distribution(parallel::block(m_process_group, numverts)),
876 m_base(edges_are_unsorted_global,
877 index_to_vertex_iterator<InputIterator, BOOST_DISTRIB_CSR_GRAPH_TYPE>(edge_begin, *this),
878 index_to_vertex_iterator<InputIterator, BOOST_DISTRIB_CSR_GRAPH_TYPE>(edge_end, *this),
880 m_distribution.block_size(process_id(m_process_group), numverts),
881 get(vertex_local, *this),
882 local_vertex<csr_vertex_owner_map<process_id_type, vertex_descriptor>,
883 process_id_type> (get(vertex_owner, *this), process_id(pg)),
887 template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
888 template <typename InputIterator, typename EdgePropertyIterator,
889 typename Distribution>
890 BOOST_DISTRIB_CSR_GRAPH_TYPE::
891 compressed_sparse_row_graph(edges_are_unsorted_t,
892 InputIterator edge_begin, InputIterator edge_end,
893 EdgePropertyIterator ep_iter,
894 vertices_size_type numverts,
895 const ProcessGroup& pg,
896 const Distribution& dist,
897 const GraphProperty& prop)
898 : m_process_group(pg),
899 m_distribution(dist),
900 m_base(edges_are_unsorted_global,
901 index_to_vertex_iterator<InputIterator, BOOST_DISTRIB_CSR_GRAPH_TYPE>(edge_begin, *this),
902 index_to_vertex_iterator<InputIterator, BOOST_DISTRIB_CSR_GRAPH_TYPE>(edge_end, *this),
904 m_distribution.block_size(process_id(m_process_group), numverts),
905 get(vertex_local, *this),
906 local_vertex<csr_vertex_owner_map<process_id_type, vertex_descriptor>,
907 process_id_type> (get(vertex_owner, *this), process_id(pg)),
911 template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
912 template<typename InputIterator>
913 BOOST_DISTRIB_CSR_GRAPH_TYPE::
914 compressed_sparse_row_graph(edges_are_sorted_t,
915 InputIterator edge_begin, InputIterator edge_end,
916 vertices_size_type numverts,
917 edges_size_type numedges, // This is not used as there is no appropriate BGL ctor
918 const ProcessGroup& pg,
919 const GraphProperty& prop)
920 : m_process_group(pg),
921 m_distribution(parallel::block(m_process_group, numverts)),
922 m_base(edges_are_sorted_global,
923 index_to_vertex_iterator<InputIterator, BOOST_DISTRIB_CSR_GRAPH_TYPE>(edge_begin, *this),
924 index_to_vertex_iterator<InputIterator, BOOST_DISTRIB_CSR_GRAPH_TYPE>(edge_end, *this),
925 get(vertex_local, *this),
926 local_vertex<csr_vertex_owner_map<process_id_type, vertex_descriptor>,
927 process_id_type> (get(vertex_owner, *this), process_id(pg)),
928 m_distribution.block_size(process_id(m_process_group), numverts),
932 template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
933 template <typename InputIterator, typename Distribution>
934 BOOST_DISTRIB_CSR_GRAPH_TYPE::
935 compressed_sparse_row_graph(edges_are_sorted_t,
936 InputIterator edge_begin, InputIterator edge_end,
937 vertices_size_type numverts,
938 const ProcessGroup& pg,
939 const Distribution& dist,
940 const GraphProperty& prop)
941 : m_process_group(pg),
942 m_distribution(dist),
943 m_base(edges_are_sorted_global,
944 index_to_vertex_iterator<InputIterator, BOOST_DISTRIB_CSR_GRAPH_TYPE>(edge_begin, *this),
945 index_to_vertex_iterator<InputIterator, BOOST_DISTRIB_CSR_GRAPH_TYPE>(edge_end, *this),
946 get(vertex_local, *this),
947 local_vertex<csr_vertex_owner_map<process_id_type, vertex_descriptor>,
948 process_id_type> (get(vertex_owner, *this), process_id(pg)),
949 m_distribution.block_size(process_id(m_process_group), numverts),
953 template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
954 template<typename InputIterator, typename EdgePropertyIterator>
955 BOOST_DISTRIB_CSR_GRAPH_TYPE::
956 compressed_sparse_row_graph(edges_are_sorted_t,
957 InputIterator edge_begin, InputIterator edge_end,
958 EdgePropertyIterator ep_iter,
959 vertices_size_type numverts,
960 edges_size_type numedges, // This is not used as there is no appropriate BGL ctor
961 const ProcessGroup& pg,
962 const GraphProperty& prop)
963 : m_process_group(pg),
964 m_distribution(parallel::block(m_process_group, numverts)),
965 m_base(edges_are_sorted_global,
966 index_to_vertex_iterator<InputIterator, BOOST_DISTRIB_CSR_GRAPH_TYPE>(edge_begin, *this),
967 index_to_vertex_iterator<InputIterator, BOOST_DISTRIB_CSR_GRAPH_TYPE>(edge_end, *this),
969 get(vertex_local, *this),
970 local_vertex<csr_vertex_owner_map<process_id_type, vertex_descriptor>,
971 process_id_type> (get(vertex_owner, *this), process_id(pg)),
972 m_distribution.block_size(process_id(m_process_group), numverts),
976 template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
977 template<typename InputIterator, typename EdgePropertyIterator,
978 typename Distribution>
979 BOOST_DISTRIB_CSR_GRAPH_TYPE::
980 compressed_sparse_row_graph(edges_are_sorted_t,
981 InputIterator edge_begin, InputIterator edge_end,
982 EdgePropertyIterator ep_iter,
983 vertices_size_type numverts,
984 const ProcessGroup& pg,
985 const Distribution& dist,
986 const GraphProperty& prop)
987 : m_process_group(pg),
988 m_distribution(dist),
989 m_base(edges_are_sorted_global,
990 index_to_vertex_iterator<InputIterator, BOOST_DISTRIB_CSR_GRAPH_TYPE>(edge_begin, *this),
991 index_to_vertex_iterator<InputIterator, BOOST_DISTRIB_CSR_GRAPH_TYPE>(edge_end, *this),
993 get(vertex_local, *this),
994 local_vertex<csr_vertex_owner_map<process_id_type, vertex_descriptor>,
995 process_id_type> (get(vertex_owner, *this), process_id(pg)),
996 m_distribution.block_size(process_id(m_process_group), numverts),
1000 template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
1001 template<typename MultiPassInputIterator>
1002 BOOST_DISTRIB_CSR_GRAPH_TYPE::
1003 compressed_sparse_row_graph(edges_are_unsorted_multi_pass_t,
1004 MultiPassInputIterator edge_begin,
1005 MultiPassInputIterator edge_end,
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(edges_are_unsorted_multi_pass_global,
1012 make_index_to_vertex_iterator(edge_begin, parallel::block(m_process_group, numverts), *this),
1013 make_index_to_vertex_iterator(edge_end, parallel::block(m_process_group, numverts), *this),
1014 m_distribution.block_size(process_id(m_process_group), numverts),
1015 get(vertex_local, *this),
1016 local_vertex<csr_vertex_owner_map<process_id_type, vertex_descriptor>,
1017 process_id_type> (get(vertex_owner, *this), process_id(pg)),
1021 template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
1022 template <typename MultiPassInputIterator, typename Distribution>
1023 BOOST_DISTRIB_CSR_GRAPH_TYPE::
1024 compressed_sparse_row_graph(edges_are_unsorted_multi_pass_t,
1025 MultiPassInputIterator edge_begin,
1026 MultiPassInputIterator edge_end,
1027 vertices_size_type numverts,
1028 const ProcessGroup& pg,
1029 const Distribution& dist,
1030 const GraphProperty& prop)
1031 : m_process_group(pg),
1032 m_distribution(dist),
1033 m_base(edges_are_unsorted_multi_pass_global,
1034 make_index_to_vertex_iterator(edge_begin, parallel::block(m_process_group, numverts), *this),
1035 make_index_to_vertex_iterator(edge_end, parallel::block(m_process_group, numverts), *this),
1036 m_distribution.block_size(process_id(m_process_group), numverts),
1037 get(vertex_local, *this),
1038 local_vertex<csr_vertex_owner_map<process_id_type, vertex_descriptor>,
1039 process_id_type> (get(vertex_owner, *this), process_id(pg)),
1044 template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
1045 template<typename MultiPassInputIterator, typename EdgePropertyIterator>
1046 BOOST_DISTRIB_CSR_GRAPH_TYPE::
1047 compressed_sparse_row_graph(edges_are_unsorted_multi_pass_t,
1048 MultiPassInputIterator edge_begin,
1049 MultiPassInputIterator edge_end,
1050 EdgePropertyIterator ep_iter,
1051 vertices_size_type numverts,
1052 const ProcessGroup& pg,
1053 const GraphProperty& prop)
1054 : m_process_group(pg),
1055 m_distribution(parallel::block(m_process_group, numverts)),
1056 m_base(edges_are_unsorted_multi_pass_global,
1057 make_index_to_vertex_iterator(edge_begin, parallel::block(m_process_group, numverts), *this),
1058 make_index_to_vertex_iterator(edge_end, parallel::block(m_process_group, numverts), *this),
1060 m_distribution.block_size(process_id(m_process_group), numverts),
1061 get(vertex_local, *this),
1062 local_vertex<csr_vertex_owner_map<process_id_type, vertex_descriptor>,
1063 process_id_type> (get(vertex_owner, *this), process_id(pg)),
1067 template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
1068 template <typename MultiPassInputIterator, typename EdgePropertyIterator,
1069 typename Distribution>
1070 BOOST_DISTRIB_CSR_GRAPH_TYPE::
1071 compressed_sparse_row_graph(edges_are_unsorted_multi_pass_t,
1072 MultiPassInputIterator edge_begin,
1073 MultiPassInputIterator edge_end,
1074 EdgePropertyIterator ep_iter,
1075 vertices_size_type numverts,
1076 const ProcessGroup& pg,
1077 const Distribution& dist,
1078 const GraphProperty& prop)
1079 : m_process_group(pg),
1080 m_distribution(dist),
1081 m_base(edges_are_unsorted_multi_pass_global,
1082 make_index_to_vertex_iterator(edge_begin, parallel::block(m_process_group, numverts), *this),
1083 make_index_to_vertex_iterator(edge_end, parallel::block(m_process_group, numverts), *this),
1085 m_distribution.block_size(process_id(m_process_group), numverts),
1086 get(vertex_local, *this),
1087 local_vertex<csr_vertex_owner_map<process_id_type, vertex_descriptor>,
1088 process_id_type> (get(vertex_owner, *this), process_id(pg)),
1092 template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
1093 template<typename Source>
1094 BOOST_DISTRIB_CSR_GRAPH_TYPE::
1095 compressed_sparse_row_graph(distributed_construct_inplace_from_sources_and_targets_t,
1096 std::vector<Source>& sources,
1097 std::vector<vertex_descriptor>& targets,
1098 vertices_size_type numverts,
1099 const ProcessGroup& pg,
1100 const GraphProperty& prop)
1101 : m_process_group(pg),
1102 m_distribution(parallel::block(m_process_group, numverts)),
1103 m_base(m_distribution.block_size(process_id(m_process_group), numverts))
1105 // Convert linear indices to global indices
1106 for (edges_size_type i = 0; i < sources.size(); ++i) {
1107 sources[i] = m_distribution.local(sources[i]);
1108 targets[i] = make_vertex_descriptor(m_distribution(targets[i]),
1109 m_distribution.local(targets[i]));
1112 m_base.assign_sources_and_targets_global(
1113 sources, targets, m_distribution.block_size(process_id(m_process_group), numverts),
1114 identity_property_map());
1116 // TODO: set property on m_base?
1119 template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
1120 template <typename Distribution, typename Source>
1121 BOOST_DISTRIB_CSR_GRAPH_TYPE::
1122 compressed_sparse_row_graph(distributed_construct_inplace_from_sources_and_targets_t,
1123 std::vector<Source>& sources,
1124 std::vector<vertex_descriptor>& targets,
1125 vertices_size_type numverts,
1126 const ProcessGroup& pg,
1127 const Distribution& dist,
1128 const GraphProperty& prop)
1129 : m_process_group(pg),
1130 m_distribution(dist),
1131 m_base(m_distribution.block_size(process_id(m_process_group), numverts))
1133 // Convert linear indices to global indices
1134 for (edges_size_type i = 0; i < sources.size(); ++i) {
1135 sources[i] = m_distribution.local(sources[i]);
1136 targets[i] = make_vertex_descriptor(m_distribution(targets[i]),
1137 m_distribution.local(targets[i]));
1140 m_base.assign_sources_and_targets_global(
1141 sources, targets, m_distribution.block_size(process_id(m_process_group), numverts),
1142 identity_property_map());
1144 // TODO: set property on m_base?
1147 template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
1148 template<typename Source>
1149 BOOST_DISTRIB_CSR_GRAPH_TYPE::
1150 compressed_sparse_row_graph(distributed_construct_inplace_from_sources_and_targets_t,
1151 std::vector<Source>& sources,
1152 std::vector<vertex_descriptor>& targets,
1153 std::vector<edge_bundled>& edge_props,
1154 vertices_size_type numverts,
1155 const ProcessGroup& pg,
1156 const GraphProperty& prop)
1157 : m_process_group(pg),
1158 m_distribution(parallel::block(m_process_group, numverts)),
1159 m_base(m_distribution.block_size(process_id(m_process_group), numverts))
1161 // Convert linear indices to global indices
1162 for (edges_size_type i = 0; i < sources.size(); ++i) {
1163 sources[i] = m_distribution.local(sources[i]);
1164 targets[i] = make_vertex_descriptor(m_distribution(targets[i]),
1165 m_distribution.local(targets[i]));
1168 m_base.assign_sources_and_targets_global(
1169 sources, targets, edge_props,
1170 m_distribution.block_size(process_id(m_process_group), numverts),
1171 identity_property_map());
1173 // TODO: set property on m_base?
1176 template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
1177 template <typename Distribution, typename Source>
1178 BOOST_DISTRIB_CSR_GRAPH_TYPE::
1179 compressed_sparse_row_graph(distributed_construct_inplace_from_sources_and_targets_t,
1180 std::vector<Source>& sources,
1181 std::vector<vertex_descriptor>& targets,
1182 std::vector<edge_bundled>& edge_props,
1183 vertices_size_type numverts,
1184 const ProcessGroup& pg,
1185 const Distribution& dist,
1186 const GraphProperty& prop)
1187 : m_process_group(pg),
1188 m_distribution(dist),
1189 m_base(m_distribution.block_size(process_id(m_process_group), numverts))
1191 // Convert linear indices to global indices
1192 for (edges_size_type i = 0; i < sources.size(); ++i) {
1193 sources[i] = m_distribution.local(sources[i]);
1194 targets[i] = make_vertex_descriptor(m_distribution(targets[i]),
1195 m_distribution.local(targets[i]));
1198 m_base.assign_sources_and_targets_global(
1199 sources, targets, edge_props,
1200 m_distribution.block_size(process_id(m_process_group), numverts),
1201 identity_property_map());
1203 // TODO: set property on m_base?
1207 // Old (untagged) ctors, these default to the unsorted sequential ctors
1209 template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
1210 template<typename InputIterator>
1211 BOOST_DISTRIB_CSR_GRAPH_TYPE::
1212 compressed_sparse_row_graph(InputIterator edge_begin, InputIterator edge_end,
1213 vertices_size_type numverts,
1214 const ProcessGroup& pg,
1215 const GraphProperty& prop)
1216 : m_process_group(pg),
1217 m_distribution(parallel::block(m_process_group, numverts)),
1218 m_base(edges_are_unsorted_global,
1219 index_to_vertex_iterator<InputIterator, BOOST_DISTRIB_CSR_GRAPH_TYPE>(edge_begin, *this),
1220 index_to_vertex_iterator<InputIterator, BOOST_DISTRIB_CSR_GRAPH_TYPE>(edge_end, *this),
1221 m_distribution.block_size(process_id(m_process_group), numverts),
1222 get(vertex_local, *this),
1223 local_vertex<csr_vertex_owner_map<process_id_type, vertex_descriptor>,
1224 process_id_type> (get(vertex_owner, *this), process_id(pg)),
1230 template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
1231 template<typename InputIterator, typename EdgePropertyIterator>
1232 BOOST_DISTRIB_CSR_GRAPH_TYPE::
1233 compressed_sparse_row_graph(InputIterator edge_begin, InputIterator edge_end,
1234 EdgePropertyIterator ep_iter,
1235 vertices_size_type numverts,
1236 const ProcessGroup& pg,
1237 const GraphProperty& prop)
1238 : m_process_group(pg),
1240 m_distribution(parallel::block(m_process_group, numverts)),
1241 m_base(edges_are_unsorted_global,
1242 index_to_vertex_iterator<InputIterator, BOOST_DISTRIB_CSR_GRAPH_TYPE>(edge_begin, *this),
1243 index_to_vertex_iterator<InputIterator, BOOST_DISTRIB_CSR_GRAPH_TYPE>(edge_end, *this),
1245 m_distribution.block_size(process_id(m_process_group), numverts),
1246 get(vertex_local, *this),
1247 local_vertex<csr_vertex_owner_map<process_id_type, vertex_descriptor>,
1248 process_id_type> (get(vertex_owner, *this), process_id(pg)),
1253 template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
1254 template<typename InputIterator, typename Distribution>
1255 BOOST_DISTRIB_CSR_GRAPH_TYPE::
1256 compressed_sparse_row_graph(InputIterator edge_begin, InputIterator edge_end,
1257 vertices_size_type numverts,
1258 const ProcessGroup& pg,
1259 const Distribution& dist,
1260 const GraphProperty& prop)
1261 : m_process_group(pg),
1262 m_distribution(dist),
1263 m_base(edges_are_unsorted_global,
1264 index_to_vertex_iterator<InputIterator, BOOST_DISTRIB_CSR_GRAPH_TYPE>(edge_begin, *this),
1265 index_to_vertex_iterator<InputIterator, BOOST_DISTRIB_CSR_GRAPH_TYPE>(edge_end, *this),
1266 m_distribution.block_size(process_id(m_process_group), numverts),
1267 get(vertex_local, *this),
1268 local_vertex<csr_vertex_owner_map<process_id_type, vertex_descriptor>,
1269 process_id_type> (get(vertex_owner, *this), process_id(pg)),
1274 template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
1275 template<typename InputIterator, typename EdgePropertyIterator,
1276 typename Distribution>
1277 BOOST_DISTRIB_CSR_GRAPH_TYPE::
1278 compressed_sparse_row_graph(InputIterator edge_begin, InputIterator edge_end,
1279 EdgePropertyIterator ep_iter,
1280 vertices_size_type numverts,
1281 const ProcessGroup& pg,
1282 const Distribution& dist,
1283 const GraphProperty& prop)
1284 : m_process_group(pg),
1285 m_distribution(dist),
1286 m_base(edges_are_unsorted_global,
1287 index_to_vertex_iterator<InputIterator, BOOST_DISTRIB_CSR_GRAPH_TYPE>(edge_begin, *this),
1288 index_to_vertex_iterator<InputIterator, BOOST_DISTRIB_CSR_GRAPH_TYPE>(edge_end, *this),
1289 m_distribution.block_size(process_id(m_process_group), numverts),
1290 get(vertex_local, *this),
1291 local_vertex<csr_vertex_owner_map<process_id_type, vertex_descriptor>,
1292 process_id_type> (get(vertex_owner, *this), process_id(pg)),
1297 // -----------------------------------------------------------------
1298 // Vertex Global Property Map
1299 template<typename ProcessID, typename Key>
1300 class csr_vertex_global_map
1303 // -----------------------------------------------------------------
1304 // Readable Property Map concept requirements
1305 typedef std::pair<ProcessID, Key> value_type;
1306 typedef value_type reference;
1307 typedef Key key_type;
1308 typedef readable_property_map_tag category;
1311 template<typename ProcessID, typename Key>
1312 inline std::pair<ProcessID, Key>
1313 get(csr_vertex_global_map<ProcessID, Key>,
1314 typename csr_vertex_global_map<ProcessID, Key>::key_type k)
1316 const int local_index_bits = sizeof(Key) * CHAR_BIT - processor_bits;
1317 const Key local_index_mask = Key(-1) >> processor_bits;
1319 return std::pair<ProcessID, Key>(k >> local_index_bits,
1320 k & local_index_mask);
1323 template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
1324 class property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, vertex_global_t>
1327 typedef csr_vertex_global_map<
1328 typename ProcessGroup::process_id_type,
1329 typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor> type;
1330 typedef type const_type;
1333 template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
1335 typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, vertex_global_t>::type
1336 get(vertex_global_t, BOOST_DISTRIB_CSR_GRAPH_TYPE& g)
1338 typedef typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, vertex_global_t>
1340 return result_type();
1343 template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
1345 std::pair<typename ProcessGroup::process_id_type,
1346 typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor>
1347 get(vertex_global_t, BOOST_DISTRIB_CSR_GRAPH_TYPE& g,
1348 typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor k)
1350 return get(vertex_global,
1351 const_cast<const BOOST_DISTRIB_CSR_GRAPH_TYPE&>(g),
1355 template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
1357 typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, vertex_global_t>::const_type
1358 get(vertex_global_t, const BOOST_DISTRIB_CSR_GRAPH_TYPE& g)
1360 typedef typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, vertex_global_t>
1361 ::const_type result_type;
1362 return result_type();
1365 template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
1367 std::pair<typename ProcessGroup::process_id_type,
1368 typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor>
1369 get(vertex_global_t, const BOOST_DISTRIB_CSR_GRAPH_TYPE& g,
1370 typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor k)
1372 typedef typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor
1374 typedef std::pair<typename ProcessGroup::process_id_type, vertex_descriptor>
1376 const int local_index_bits =
1377 sizeof(vertex_descriptor) * CHAR_BIT - processor_bits;
1378 const vertex_descriptor local_index_mask =
1379 vertex_descriptor(-1) >> processor_bits;
1381 return result_type(k >> local_index_bits, k & local_index_mask);
1384 // -----------------------------------------------------------------
1385 // Extra, common functions
1386 template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
1387 inline typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor
1388 vertex(typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertices_size_type i,
1389 const BOOST_DISTRIB_CSR_GRAPH_TYPE& g)
1391 return g.make_vertex_descriptor(g.distribution()(i),
1392 g.distribution().local(i));
1395 // Unlike for an adjacency_matrix, edge_range and edge take lg(out_degree(i))
1397 template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
1398 inline std::pair<typename BOOST_DISTRIB_CSR_GRAPH_TYPE::out_edge_iterator,
1399 typename BOOST_DISTRIB_CSR_GRAPH_TYPE::out_edge_iterator>
1400 edge_range(typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor i,
1401 typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor j,
1402 const BOOST_DISTRIB_CSR_GRAPH_TYPE& g)
1404 typedef typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor Vertex;
1405 typedef typename BOOST_DISTRIB_CSR_GRAPH_TYPE::edges_size_type EdgeIndex;
1406 typedef typename std::vector<Vertex>::const_iterator adj_iter;
1407 typedef typename BOOST_DISTRIB_CSR_GRAPH_TYPE::out_edge_iterator out_edge_iter;
1408 typedef typename BOOST_DISTRIB_CSR_GRAPH_TYPE::edge_descriptor edge_desc;
1409 std::pair<adj_iter, adj_iter> raw_adjacencies = adjacent_vertices(i, g);
1410 std::pair<adj_iter, adj_iter> adjacencies =
1411 std::equal_range(raw_adjacencies.first, raw_adjacencies.second, j);
1412 EdgeIndex idx_begin = adjacencies.first - g.base().m_forward.m_column.begin();
1413 EdgeIndex idx_end = adjacencies.second - g.base().m_forward.m_column.begin();
1414 return std::make_pair(out_edge_iter(edge_desc(i, idx_begin)),
1415 out_edge_iter(edge_desc(i, idx_end)));
1418 template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
1419 inline std::pair<typename BOOST_DISTRIB_CSR_GRAPH_TYPE::edge_descriptor, bool>
1420 edge(typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor i,
1421 typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor j,
1422 const BOOST_DISTRIB_CSR_GRAPH_TYPE& g)
1424 typedef typename BOOST_DISTRIB_CSR_GRAPH_TYPE::out_edge_iterator out_edge_iter;
1425 std::pair<out_edge_iter, out_edge_iter> range = edge_range(i, j, g);
1426 if (range.first == range.second)
1427 return std::make_pair(typename BOOST_DISTRIB_CSR_GRAPH_TYPE::edge_descriptor(),
1430 return std::make_pair(*range.first, true);
1433 // A helper that turns requests for property maps for const graphs
1434 // into property maps for non-const graphs.
1435 template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS, typename Property>
1436 class property_map<const BOOST_DISTRIB_CSR_GRAPH_TYPE, Property>
1439 typedef typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, Property>
1441 typedef type const_type;
1444 // -----------------------------------------------------------------
1445 // Structural modifiers
1448 template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
1449 typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor
1450 add_vertex(BOOST_DISTRIB_CSR_GRAPH_TYPE& g)
1451 { return g.add_vertex(); }
1453 template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
1454 typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor
1455 add_vertex(const typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_bundled& p,
1456 BOOST_DISTRIB_CSR_GRAPH_TYPE& g)
1457 { return g.add_vertex(p); }
1459 template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
1460 typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor
1461 add_vertices(typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertices_size_type count,
1462 BOOST_DISTRIB_CSR_GRAPH_TYPE& g)
1463 { return g.add_vertices(count); }
1465 template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS, typename InputIterator>
1467 add_edges(InputIterator first, InputIterator last,
1468 BOOST_DISTRIB_CSR_GRAPH_TYPE& g)
1469 { g.add_edges(first, last); }
1471 template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS, typename InputIterator,
1472 typename EdgePropertyIterator>
1474 add_edges(InputIterator first, InputIterator last,
1475 EdgePropertyIterator ep_iter,
1476 EdgePropertyIterator ep_iter_end,
1477 BOOST_DISTRIB_CSR_GRAPH_TYPE& g)
1478 { return g.add_edges(first, last, ep_iter, ep_iter_end); }
1480 template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS, typename InputIterator>
1482 add_edges_sorted(InputIterator first, InputIterator last,
1483 BOOST_DISTRIB_CSR_GRAPH_TYPE& g)
1484 { return g.add_edges_sorted(first, last); }
1486 template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS, typename InputIterator,
1487 typename EdgePropertyIterator>
1489 add_edges_sorted(InputIterator first_sorted, InputIterator last_sorted,
1490 EdgePropertyIterator ep_iter_sorted,
1491 BOOST_DISTRIB_CSR_GRAPH_TYPE& g)
1492 { g.add_edges_sorted(first_sorted, last_sorted, ep_iter_sorted); }
1495 // -----------------------------------------------------------------
1496 // Vertex Owner Property Map
1497 template<typename ProcessID, typename Key>
1498 class csr_vertex_owner_map
1501 // -----------------------------------------------------------------
1502 // Readable Property Map concept requirements
1503 typedef ProcessID value_type;
1504 typedef value_type reference;
1505 typedef Key key_type;
1506 typedef readable_property_map_tag category;
1509 template<typename ProcessID, typename Key>
1511 get(csr_vertex_owner_map<ProcessID, Key> pm,
1512 typename csr_vertex_owner_map<ProcessID, Key>::key_type k)
1514 const int local_index_bits = sizeof(Key) * CHAR_BIT - processor_bits;
1515 return k >> local_index_bits;
1518 template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
1519 class property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, vertex_owner_t>
1522 typedef csr_vertex_owner_map<
1523 typename ProcessGroup::process_id_type,
1524 typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor> type;
1525 typedef type const_type;
1528 template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
1530 typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, vertex_owner_t>::type
1531 get(vertex_owner_t, BOOST_DISTRIB_CSR_GRAPH_TYPE& g)
1533 typedef typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, vertex_owner_t>
1535 return result_type();
1538 template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
1539 inline typename ProcessGroup::process_id_type
1540 get(vertex_owner_t, BOOST_DISTRIB_CSR_GRAPH_TYPE& g,
1541 typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor k)
1543 return get(vertex_owner,
1544 const_cast<const BOOST_DISTRIB_CSR_GRAPH_TYPE&>(g),
1548 template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
1550 typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, vertex_owner_t>::const_type
1551 get(vertex_owner_t, const BOOST_DISTRIB_CSR_GRAPH_TYPE& g)
1553 typedef typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, vertex_owner_t>
1554 ::const_type result_type;
1555 return result_type();
1558 template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
1559 inline typename ProcessGroup::process_id_type
1560 get(vertex_owner_t, const BOOST_DISTRIB_CSR_GRAPH_TYPE& g,
1561 typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor k)
1563 typedef typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor
1565 const int local_index_bits =
1566 sizeof(vertex_descriptor) * CHAR_BIT - processor_bits;
1567 return k >> local_index_bits;
1570 // -----------------------------------------------------------------
1571 // Vertex Local Property Map
1572 template<typename Key>
1573 class csr_vertex_local_map
1576 // -----------------------------------------------------------------
1577 // Readable Property Map concept requirements
1578 typedef Key value_type;
1579 typedef value_type reference;
1580 typedef Key key_type;
1581 typedef readable_property_map_tag category;
1584 template<typename Key>
1586 get(csr_vertex_local_map<Key> pm,
1587 typename csr_vertex_local_map<Key>::key_type k)
1589 const Key local_index_mask = Key(-1) >> processor_bits;
1590 return k & local_index_mask;
1593 template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
1594 class property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, vertex_local_t>
1597 typedef csr_vertex_local_map<
1598 typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor> type;
1599 typedef type const_type;
1602 template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
1604 typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, vertex_local_t>::type
1605 get(vertex_local_t, BOOST_DISTRIB_CSR_GRAPH_TYPE& g)
1607 typedef typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, vertex_local_t>
1609 return result_type();
1612 template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
1613 inline typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor
1614 get(vertex_local_t, BOOST_DISTRIB_CSR_GRAPH_TYPE& g,
1615 typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor k)
1617 return get(vertex_local,
1618 const_cast<const BOOST_DISTRIB_CSR_GRAPH_TYPE&>(g),
1622 template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
1624 typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, vertex_local_t>::const_type
1625 get(vertex_local_t, const BOOST_DISTRIB_CSR_GRAPH_TYPE& g)
1627 typedef typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, vertex_local_t>
1628 ::const_type result_type;
1629 return result_type();
1632 template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
1633 inline typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor
1634 get(vertex_local_t, const BOOST_DISTRIB_CSR_GRAPH_TYPE& g,
1635 typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor k)
1637 typedef typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor
1639 const vertex_descriptor local_index_mask =
1640 vertex_descriptor(-1) >> processor_bits;
1641 return k & local_index_mask;
1644 // -----------------------------------------------------------------
1645 // Vertex Index Property Map
1646 template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
1647 class property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, vertex_index_t>
1649 typedef typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE,
1650 vertex_global_t>::const_type
1652 typedef typename BOOST_DISTRIB_CSR_GRAPH_TYPE::process_group_type
1655 typedef property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, vertex_local_t> local;
1658 typedef local_property_map<process_group_type,
1660 typename local::type> type;
1661 typedef local_property_map<process_group_type,
1663 typename local::const_type> const_type;
1666 template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
1668 typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, vertex_index_t>::type
1669 get(vertex_index_t, BOOST_DISTRIB_CSR_GRAPH_TYPE& g)
1671 typedef typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, vertex_index_t>
1674 return result_type(g.process_group(), get(vertex_global, g),
1675 get(vertex_local, g));
1678 template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
1679 inline typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertices_size_type
1680 get(vertex_index_t, BOOST_DISTRIB_CSR_GRAPH_TYPE& g,
1681 typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor k)
1683 return get(vertex_local, g, k);
1686 template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
1688 typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, vertex_index_t>::const_type
1689 get(vertex_index_t, const BOOST_DISTRIB_CSR_GRAPH_TYPE& g)
1691 typedef typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, vertex_index_t>
1692 ::const_type result_type;
1693 return result_type(g.process_group(), get(vertex_global, g),
1694 get(vertex_local, g));
1697 template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
1698 inline typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertices_size_type
1699 get(vertex_index_t, const BOOST_DISTRIB_CSR_GRAPH_TYPE& g,
1700 typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor k)
1702 return get(vertex_local, g, k);
1705 // -----------------------------------------------------------------
1706 // Vertex Local Index Property Map
1707 template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
1708 class property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, vertex_local_index_t>
1709 : public property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, vertex_local_t> { };
1711 template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
1713 typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, vertex_local_index_t>::type
1714 get(vertex_local_index_t, BOOST_DISTRIB_CSR_GRAPH_TYPE& g)
1716 return get(vertex_local, g);
1719 template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
1720 inline typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertices_size_type
1721 get(vertex_local_index_t, BOOST_DISTRIB_CSR_GRAPH_TYPE& g,
1722 typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor k)
1724 return get(vertex_local, g, k);
1727 template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
1729 typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, vertex_local_index_t>::const_type
1730 get(vertex_local_index_t, const BOOST_DISTRIB_CSR_GRAPH_TYPE& g)
1732 return get(vertex_local, g);
1735 template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
1736 inline typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertices_size_type
1737 get(vertex_local_index_t, const BOOST_DISTRIB_CSR_GRAPH_TYPE& g,
1738 typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor k)
1740 return get(vertex_local, g, k);
1743 // -----------------------------------------------------------------
1744 // Edge Global Property Map
1745 template<typename ProcessID, typename Vertex, typename EdgeIndex>
1746 class csr_edge_global_map
1749 // -----------------------------------------------------------------
1750 // Readable Property Map concept requirements
1751 typedef detail::csr_edge_descriptor<Vertex, EdgeIndex> key_type;
1752 typedef std::pair<ProcessID, detail::csr_edge_descriptor<Vertex, EdgeIndex> > value_type;
1753 typedef value_type reference;
1754 typedef readable_property_map_tag category;
1757 template<typename ProcessID, typename Vertex, typename EdgeIndex>
1758 inline std::pair<ProcessID, detail::csr_edge_descriptor<Vertex, EdgeIndex> >
1759 get(csr_edge_global_map<ProcessID, Vertex, EdgeIndex> pm,
1760 typename csr_edge_global_map<ProcessID, Vertex, EdgeIndex>::key_type k)
1762 const int local_index_bits = sizeof(Vertex) * CHAR_BIT - processor_bits;
1763 const Vertex local_index_mask = Vertex(-1) >> processor_bits;
1764 return std::pair<ProcessID, detail::csr_edge_descriptor<Vertex, EdgeIndex> >
1765 ((k.src >> local_index_bits),
1766 detail::csr_edge_descriptor<Vertex, EdgeIndex>(k.src & local_index_mask, k.idx));
1769 template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
1770 class property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, edge_global_t>
1773 typedef csr_edge_global_map<
1774 typename ProcessGroup::process_id_type,
1775 typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor,
1776 typename BOOST_DISTRIB_CSR_GRAPH_TYPE::edges_size_type> type;
1777 typedef type const_type;
1780 template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
1782 typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, edge_global_t>::type
1783 get(edge_global_t, BOOST_DISTRIB_CSR_GRAPH_TYPE& g)
1785 typedef typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, edge_global_t>
1787 return result_type();
1790 template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
1792 std::pair<typename ProcessGroup::process_id_type,
1793 typename BOOST_DISTRIB_CSR_GRAPH_TYPE::base_type::edge_descriptor>
1794 get(edge_global_t, BOOST_DISTRIB_CSR_GRAPH_TYPE& g,
1795 typename BOOST_DISTRIB_CSR_GRAPH_TYPE::edge_descriptor k)
1797 return get(edge_global,
1798 const_cast<const BOOST_DISTRIB_CSR_GRAPH_TYPE&>(g),
1802 template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
1804 typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, edge_global_t>::const_type
1805 get(edge_global_t, const BOOST_DISTRIB_CSR_GRAPH_TYPE& g)
1807 typedef typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, edge_global_t>
1808 ::const_type result_type;
1809 return result_type();
1812 template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
1814 std::pair<typename ProcessGroup::process_id_type,
1815 typename BOOST_DISTRIB_CSR_GRAPH_TYPE::base_type::edge_descriptor>
1816 get(edge_global_t, const BOOST_DISTRIB_CSR_GRAPH_TYPE& g,
1817 typename BOOST_DISTRIB_CSR_GRAPH_TYPE::edge_descriptor k)
1819 typedef typename BOOST_DISTRIB_CSR_GRAPH_TYPE::vertex_descriptor
1822 const int local_index_bits =
1823 sizeof(vertex_descriptor) * CHAR_BIT - processor_bits;
1824 const typename BOOST_DISTRIB_CSR_GRAPH_TYPE::edges_size_type local_index_mask =
1825 typename BOOST_DISTRIB_CSR_GRAPH_TYPE::edges_size_type(-1) >> processor_bits;
1827 typedef std::pair<typename ProcessGroup::process_id_type,
1828 typename BOOST_DISTRIB_CSR_GRAPH_TYPE::base_type::edge_descriptor>
1831 return result_type(k.src >> local_index_bits,
1832 typename BOOST_DISTRIB_CSR_GRAPH_TYPE::base_type::edge_descriptor
1833 (k.src & local_index_mask, k.idx));
1836 // -----------------------------------------------------------------
1837 // Edge Index Property Map
1838 template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
1839 class property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, edge_index_t>
1841 typedef typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, edge_global_t>
1845 typedef local_property_map<
1846 typename BOOST_DISTRIB_CSR_GRAPH_TYPE::process_group_type,
1848 typename property_map<typename BOOST_DISTRIB_CSR_GRAPH_TYPE::base_type, edge_index_t>::type
1850 typedef type const_type;
1853 template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
1855 typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, edge_index_t>::type
1856 get(edge_index_t, BOOST_DISTRIB_CSR_GRAPH_TYPE& g)
1858 typedef typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, edge_index_t>
1860 return result_type(g.process_group(), get(edge_global, g),
1861 get(edge_index, g.base()));
1864 template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
1865 inline typename BOOST_DISTRIB_CSR_GRAPH_TYPE::edges_size_type
1866 get(edge_index_t, BOOST_DISTRIB_CSR_GRAPH_TYPE& g,
1867 typename BOOST_DISTRIB_CSR_GRAPH_TYPE::edge_descriptor k)
1872 template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
1874 typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, edge_index_t>::const_type
1875 get(edge_index_t, const BOOST_DISTRIB_CSR_GRAPH_TYPE& g)
1877 typedef typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, edge_index_t>
1878 ::const_type result_type;
1879 return result_type(g.process_group(), get(edge_global, g),
1880 get(edge_index, g.base()));
1883 template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS>
1884 inline typename BOOST_DISTRIB_CSR_GRAPH_TYPE::edges_size_type
1885 get(edge_index_t, const BOOST_DISTRIB_CSR_GRAPH_TYPE& g,
1886 typename BOOST_DISTRIB_CSR_GRAPH_TYPE::edge_descriptor k)
1891 template <BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS, typename Tag>
1892 class property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, Tag> {
1893 typedef BOOST_DISTRIB_CSR_GRAPH_TYPE graph_type;
1894 typedef typename graph_type::process_group_type process_group_type;
1895 typedef typename graph_type::base_type base_graph_type;
1896 typedef typename property_map<base_graph_type, Tag>::type
1898 typedef typename property_map<base_graph_type, Tag>::const_type
1901 typedef graph_traits<graph_type> traits;
1902 typedef typename graph_traits<base_graph_type>::vertex_descriptor local_vertex;
1903 typedef typename property_traits<local_pmap>::key_type local_key_type;
1905 typedef typename property_traits<local_pmap>::value_type value_type;
1907 typedef typename property_map<graph_type, vertex_global_t>::const_type
1909 typedef typename property_map<graph_type, edge_global_t>::const_type
1912 typedef typename mpl::if_<is_same<typename detail::property_kind_from_graph<base_graph_type, Tag>::type,
1913 vertex_property_tag>,
1914 vertex_global_map, edge_global_map>::type
1918 typedef ::boost::parallel::distributed_property_map<
1919 process_group_type, global_map, local_pmap> type;
1921 typedef ::boost::parallel::distributed_property_map<
1922 process_group_type, global_map, local_const_pmap> const_type;
1925 template <BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS, typename Tag>
1926 typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, Tag>::type
1927 get(Tag tag, BOOST_DISTRIB_CSR_GRAPH_TYPE& g)
1929 typedef BOOST_DISTRIB_CSR_GRAPH_TYPE Graph;
1930 typedef typename property_map<Graph, Tag>::type result_type;
1931 typedef typename property_traits<result_type>::value_type value_type;
1932 typedef typename property_reduce<Tag>::template apply<value_type>
1935 typedef typename mpl::if_<is_same<typename detail::property_kind_from_graph<Graph, Tag>::type,
1936 vertex_property_tag>,
1937 vertex_global_t, edge_global_t>::type
1940 return result_type(g.process_group(), get(global_map_t(), g),
1941 get(tag, g.base()), reduce());
1944 template<BOOST_DISTRIB_CSR_GRAPH_TEMPLATE_PARMS, typename Tag>
1945 typename property_map<BOOST_DISTRIB_CSR_GRAPH_TYPE, Tag>::const_type
1946 get(Tag tag, const BOOST_DISTRIB_CSR_GRAPH_TYPE& g)
1948 typedef BOOST_DISTRIB_CSR_GRAPH_TYPE Graph;
1949 typedef typename property_map<Graph, Tag>::const_type result_type;
1950 typedef typename property_traits<result_type>::value_type value_type;
1951 typedef typename property_reduce<Tag>::template apply<value_type>
1954 typedef typename property_traits<result_type>::key_type descriptor;
1955 typedef typename graph_traits<Graph>::vertex_descriptor vertex_descriptor;
1956 typedef typename mpl::if_<is_same<descriptor, vertex_descriptor>,
1957 vertex_global_t, edge_global_t>::type
1960 return result_type(g.process_group(), get(global_map_t(), g),
1961 get(tag, g.base()), reduce());
1965 template<typename Vertex, typename EdgeIndex>
1966 struct is_mpi_datatype<boost::detail::csr_edge_descriptor<Vertex, EdgeIndex> >
1970 namespace serialization {
1971 template<typename Vertex, typename EdgeIndex>
1972 struct is_bitwise_serializable<boost::detail::csr_edge_descriptor<Vertex, EdgeIndex> >
1975 template<typename Vertex, typename EdgeIndex>
1976 struct implementation_level<boost::detail::csr_edge_descriptor<Vertex, EdgeIndex> >
1977 : mpl::int_<object_serializable> {} ;
1979 template<typename Vertex, typename EdgeIndex>
1980 struct tracking_level<boost::detail::csr_edge_descriptor<Vertex, EdgeIndex> >
1981 : mpl::int_<track_never> {} ;
1985 } // end namespace boost
1987 #endif // BOOST_GRAPH_DISTRIBUTED_CSR_HPP