File indexing completed on 2025-01-18 09:37:14
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_GRAPH_DISTRIBUTED_ADJACENCY_LIST_HPP
0012 #define BOOST_GRAPH_DISTRIBUTED_ADJACENCY_LIST_HPP
0013
0014 #ifndef BOOST_GRAPH_USE_MPI
0015 #error "Parallel BGL files should not be included unless <boost/graph/use_mpi.hpp> has been included"
0016 #endif
0017
0018 #include <boost/core/uncaught_exceptions.hpp>
0019 #include <boost/graph/adjacency_list.hpp>
0020 #include <boost/graph/properties.hpp>
0021 #include <boost/graph/graph_traits.hpp>
0022 #include <boost/graph/iteration_macros.hpp>
0023 #include <boost/graph/distributed/concepts.hpp>
0024 #include <boost/iterator/transform_iterator.hpp>
0025 #include <boost/property_map/property_map.hpp>
0026 #include <boost/property_map/parallel/parallel_property_maps.hpp>
0027 #include <boost/graph/adjacency_iterator.hpp>
0028 #include <boost/property_map/parallel/distributed_property_map.hpp>
0029 #include <boost/property_map/parallel/local_property_map.hpp>
0030 #include <boost/graph/parallel/detail/property_holders.hpp>
0031 #include <boost/mpl/if.hpp>
0032 #include <boost/type_traits/is_same.hpp>
0033 #include <boost/assert.hpp>
0034 #include <list>
0035 #include <iterator>
0036 #include <algorithm>
0037 #include <boost/limits.hpp>
0038 #include <boost/graph/parallel/properties.hpp>
0039 #include <boost/graph/parallel/distribution.hpp>
0040 #include <boost/graph/parallel/algorithm.hpp>
0041 #include <boost/graph/distributed/selector.hpp>
0042 #include <boost/graph/parallel/process_group.hpp>
0043 #include <boost/pending/container_traits.hpp>
0044
0045
0046 #include <boost/function/function2.hpp>
0047
0048
0049 #include <boost/serialization/base_object.hpp>
0050 #include <boost/mpi/datatype.hpp>
0051 #include <boost/pending/property_serialize.hpp>
0052 #include <boost/graph/distributed/unsafe_serialize.hpp>
0053
0054
0055 #include <boost/graph/distributed/named_graph.hpp>
0056
0057 #include <boost/graph/distributed/shuffled_distribution.hpp>
0058
0059 namespace boost {
0060
0061
0062
0063 typedef short processor_id_type;
0064
0065
0066
0067
0068 enum edge_target_processor_id_t { edge_target_processor_id };
0069 BOOST_INSTALL_PROPERTY(edge, target_processor_id);
0070
0071
0072 enum edge_locally_owned_t { edge_locally_owned };
0073 BOOST_INSTALL_PROPERTY(edge, locally_owned);
0074
0075
0076 enum vertex_in_edges_t { vertex_in_edges };
0077 BOOST_INSTALL_PROPERTY(vertex, in_edges);
0078
0079
0080 struct directed_distributed_adj_list_tag
0081 : public virtual distributed_graph_tag,
0082 public virtual distributed_vertex_list_graph_tag,
0083 public virtual distributed_edge_list_graph_tag,
0084 public virtual incidence_graph_tag,
0085 public virtual adjacency_graph_tag {};
0086
0087
0088 struct bidirectional_distributed_adj_list_tag
0089 : public virtual distributed_graph_tag,
0090 public virtual distributed_vertex_list_graph_tag,
0091 public virtual distributed_edge_list_graph_tag,
0092 public virtual incidence_graph_tag,
0093 public virtual adjacency_graph_tag,
0094 public virtual bidirectional_graph_tag {};
0095
0096
0097 struct undirected_distributed_adj_list_tag
0098 : public virtual distributed_graph_tag,
0099 public virtual distributed_vertex_list_graph_tag,
0100 public virtual distributed_edge_list_graph_tag,
0101 public virtual incidence_graph_tag,
0102 public virtual adjacency_graph_tag,
0103 public virtual bidirectional_graph_tag {};
0104
0105 namespace detail {
0106 template<typename Archiver, typename Directed, typename Vertex>
0107 void
0108 serialize(Archiver& ar, edge_base<Directed, Vertex>& e,
0109 const unsigned int )
0110 {
0111 ar & unsafe_serialize(e.m_source)
0112 & unsafe_serialize(e.m_target);
0113 }
0114
0115 template<typename Archiver, typename Directed, typename Vertex>
0116 void
0117 serialize(Archiver& ar, edge_desc_impl<Directed, Vertex>& e,
0118 const unsigned int )
0119 {
0120 ar & boost::serialization::base_object<edge_base<Directed, Vertex> >(e)
0121 & unsafe_serialize(e.m_eproperty);
0122 }
0123 }
0124
0125 namespace detail { namespace parallel {
0126
0127
0128
0129
0130
0131
0132
0133 template<typename LocalDescriptor>
0134 struct global_descriptor
0135 {
0136 typedef LocalDescriptor local_descriptor_type;
0137
0138 global_descriptor() : owner(), local() { }
0139
0140 global_descriptor(processor_id_type owner, LocalDescriptor local)
0141 : owner(owner), local(local) { }
0142
0143 processor_id_type owner;
0144 LocalDescriptor local;
0145
0146
0147
0148
0149
0150
0151
0152 struct generator
0153 {
0154 typedef global_descriptor<LocalDescriptor> result_type;
0155 typedef LocalDescriptor argument_type;
0156
0157 generator() {}
0158 generator(processor_id_type owner) : owner(owner) {}
0159
0160 result_type operator()(argument_type v) const
0161 { return result_type(owner, v); }
0162
0163 private:
0164 processor_id_type owner;
0165 };
0166
0167 template<typename Archiver>
0168 void serialize(Archiver& ar, const unsigned int )
0169 {
0170 ar & owner & unsafe_serialize(local);
0171 }
0172 };
0173
0174
0175 template<typename LocalDescriptor>
0176 inline processor_id_type owner(const global_descriptor<LocalDescriptor>& v)
0177 { return v.owner; }
0178
0179
0180 template<typename LocalDescriptor>
0181 inline LocalDescriptor local(const global_descriptor<LocalDescriptor>& v)
0182 { return v.local; }
0183
0184
0185 template<typename LocalDescriptor>
0186 inline bool
0187 operator==(const global_descriptor<LocalDescriptor>& u,
0188 const global_descriptor<LocalDescriptor>& v)
0189 {
0190 return u.owner == v.owner && u.local == v.local;
0191 }
0192
0193
0194 template<typename LocalDescriptor>
0195 inline bool
0196 operator!=(const global_descriptor<LocalDescriptor>& u,
0197 const global_descriptor<LocalDescriptor>& v)
0198 { return !(u == v); }
0199
0200 template<typename LocalDescriptor>
0201 inline bool
0202 operator<(const global_descriptor<LocalDescriptor>& u,
0203 const global_descriptor<LocalDescriptor>& v)
0204 {
0205 return (u.owner) < v.owner || (u.owner == v.owner && (u.local) < v.local);
0206 }
0207
0208 template<typename LocalDescriptor>
0209 inline bool
0210 operator<=(const global_descriptor<LocalDescriptor>& u,
0211 const global_descriptor<LocalDescriptor>& v)
0212 {
0213 return u.owner <= v.owner || (u.owner == v.owner && u.local <= v.local);
0214 }
0215
0216 template<typename LocalDescriptor>
0217 inline bool
0218 operator>(const global_descriptor<LocalDescriptor>& u,
0219 const global_descriptor<LocalDescriptor>& v)
0220 {
0221 return v < u;
0222 }
0223
0224 template<typename LocalDescriptor>
0225 inline bool
0226 operator>=(const global_descriptor<LocalDescriptor>& u,
0227 const global_descriptor<LocalDescriptor>& v)
0228 {
0229 return v <= u;
0230 }
0231
0232
0233
0234
0235
0236
0237
0238 template<typename LocalDescriptor>
0239 struct global_descriptor_property_map
0240 {
0241 typedef std::pair<processor_id_type, LocalDescriptor> value_type;
0242 typedef value_type reference;
0243 typedef global_descriptor<LocalDescriptor> key_type;
0244 typedef readable_property_map_tag category;
0245 };
0246
0247 template<typename LocalDescriptor>
0248 inline std::pair<processor_id_type, LocalDescriptor>
0249 get(global_descriptor_property_map<LocalDescriptor>,
0250 global_descriptor<LocalDescriptor> x)
0251 {
0252 return std::pair<processor_id_type, LocalDescriptor>(x.owner, x.local);
0253 }
0254
0255
0256
0257
0258
0259 template<typename LocalDescriptor>
0260 struct owner_property_map
0261 {
0262 typedef processor_id_type value_type;
0263 typedef value_type reference;
0264 typedef global_descriptor<LocalDescriptor> key_type;
0265 typedef readable_property_map_tag category;
0266 };
0267
0268 template<typename LocalDescriptor>
0269 inline processor_id_type
0270 get(owner_property_map<LocalDescriptor>,
0271 global_descriptor<LocalDescriptor> x)
0272 {
0273 return x.owner;
0274 }
0275
0276
0277
0278
0279
0280 template<typename LocalDescriptor>
0281 struct local_descriptor_property_map
0282 {
0283 typedef LocalDescriptor value_type;
0284 typedef value_type reference;
0285 typedef global_descriptor<LocalDescriptor> key_type;
0286 typedef readable_property_map_tag category;
0287 };
0288
0289 template<typename LocalDescriptor>
0290 inline LocalDescriptor
0291 get(local_descriptor_property_map<LocalDescriptor>,
0292 global_descriptor<LocalDescriptor> x)
0293 {
0294 return x.local;
0295 }
0296
0297
0298
0299
0300
0301
0302 template<typename Edge>
0303 struct stored_in_edge
0304 {
0305 stored_in_edge(processor_id_type sp, Edge e)
0306 : source_processor(sp), e(e) {}
0307
0308 processor_id_type source_processor;
0309 Edge e;
0310 };
0311
0312
0313
0314
0315
0316
0317
0318 template<typename Edge>
0319 struct edge_descriptor
0320 {
0321 edge_descriptor(processor_id_type sp = processor_id_type(),
0322 processor_id_type tp = processor_id_type(),
0323 bool owns = false, Edge ld = Edge())
0324 : source_processor(sp), target_processor(tp),
0325 source_owns_edge(owns), local(ld) {}
0326
0327 processor_id_type owner() const
0328 {
0329 return source_owns_edge? source_processor : target_processor;
0330 }
0331
0332
0333 processor_id_type source_processor;
0334
0335
0336 processor_id_type target_processor;
0337
0338
0339
0340 bool source_owns_edge;
0341
0342
0343 Edge local;
0344
0345
0346
0347
0348
0349
0350 template<typename Graph>
0351 class out_generator
0352 {
0353 typedef typename Graph::directed_selector directed_selector;
0354
0355 public:
0356 typedef edge_descriptor<Edge> result_type;
0357 typedef Edge argument_type;
0358
0359 out_generator() : g(0) {}
0360 explicit out_generator(const Graph& g) : g(&g) {}
0361
0362 result_type operator()(argument_type e) const
0363 { return map(e, directed_selector()); }
0364
0365 private:
0366 result_type map(argument_type e, directedS) const
0367 {
0368 return result_type(g->processor(),
0369 get(edge_target_processor_id, g->base(), e),
0370 true, e);
0371 }
0372
0373 result_type map(argument_type e, bidirectionalS) const
0374 {
0375 return result_type(g->processor(),
0376 get(edge_target_processor_id, g->base(), e),
0377 true, e);
0378 }
0379
0380 result_type map(argument_type e, undirectedS) const
0381 {
0382 return result_type(g->processor(),
0383 get(edge_target_processor_id, g->base(), e),
0384 get(edge_locally_owned, g->base(), e),
0385 e);
0386 }
0387
0388 const Graph* g;
0389 };
0390
0391
0392
0393
0394
0395
0396 template<typename Graph>
0397 class in_generator
0398 {
0399 typedef typename Graph::directed_selector DirectedS;
0400
0401 public:
0402 typedef typename boost::mpl::if_<is_same<DirectedS, bidirectionalS>,
0403 stored_in_edge<Edge>,
0404 Edge>::type argument_type;
0405 typedef edge_descriptor<Edge> result_type;
0406
0407 in_generator() : g(0) {}
0408 explicit in_generator(const Graph& g) : g(&g) {}
0409
0410 result_type operator()(argument_type e) const
0411 { return map(e, DirectedS()); }
0412
0413 private:
0414
0415
0416
0417
0418 result_type map(argument_type e, bidirectionalS) const
0419 {
0420 return result_type(e.source_processor,
0421 g->processor(),
0422 true,
0423 e.e);
0424 }
0425
0426
0427
0428
0429
0430
0431
0432
0433
0434
0435 result_type map(argument_type e, undirectedS) const
0436 {
0437 typename Graph::local_edge_descriptor local_edge(e);
0438
0439
0440
0441
0442 using std::swap;
0443 swap(local_edge.m_source, local_edge.m_target);
0444 return result_type(get(edge_target_processor_id, g->base(), e),
0445 g->processor(),
0446 !get(edge_locally_owned, g->base(), e),
0447 local_edge);
0448 }
0449
0450 const Graph* g;
0451 };
0452
0453 private:
0454 friend class boost::serialization::access;
0455
0456 template<typename Archiver>
0457 void serialize(Archiver& ar, const unsigned int )
0458 {
0459 ar
0460 & source_processor
0461 & target_processor
0462 & source_owns_edge
0463 & local;
0464 }
0465 };
0466
0467
0468 template<typename Edge>
0469 inline processor_id_type
0470 owner(const edge_descriptor<Edge>& e)
0471 { return e.source_owns_edge? e.source_processor : e.target_processor; }
0472
0473
0474 template<typename Edge>
0475 inline Edge
0476 local(const edge_descriptor<Edge>& e)
0477 { return e.local; }
0478
0479
0480
0481
0482
0483 template<typename Edge>
0484 struct edge_global_property_map
0485 {
0486 typedef std::pair<processor_id_type, Edge> value_type;
0487 typedef value_type reference;
0488 typedef edge_descriptor<Edge> key_type;
0489 typedef readable_property_map_tag category;
0490 };
0491
0492 template<typename Edge>
0493 inline std::pair<processor_id_type, Edge>
0494 get(edge_global_property_map<Edge>, const edge_descriptor<Edge>& e)
0495 {
0496 typedef std::pair<processor_id_type, Edge> result_type;
0497 return result_type(e.source_owns_edge? e.source_processor
0498 : e.target_processor,
0499 e.local);
0500 }
0501
0502
0503
0504
0505
0506 template<typename Edge>
0507 struct edge_owner_property_map
0508 {
0509 typedef processor_id_type value_type;
0510 typedef value_type reference;
0511 typedef edge_descriptor<Edge> key_type;
0512 typedef readable_property_map_tag category;
0513 };
0514
0515 template<typename Edge>
0516 inline processor_id_type
0517 get(edge_owner_property_map<Edge>, const edge_descriptor<Edge>& e)
0518 {
0519 return e.source_owns_edge? e.source_processor : e.target_processor;
0520 }
0521
0522
0523
0524
0525
0526 template<typename Edge>
0527 struct edge_local_property_map
0528 {
0529 typedef Edge value_type;
0530 typedef value_type reference;
0531 typedef edge_descriptor<Edge> key_type;
0532 typedef readable_property_map_tag category;
0533 };
0534
0535 template<typename Edge>
0536 inline Edge
0537 get(edge_local_property_map<Edge>,
0538 const edge_descriptor<Edge>& e)
0539 {
0540 return e.local;
0541 }
0542
0543
0544
0545
0546
0547
0548 template<typename Edge>
0549 inline bool
0550 operator==(const edge_descriptor<Edge>& e1,
0551 const edge_descriptor<Edge>& e2)
0552 {
0553 return (e1.source_processor == e2.source_processor
0554 && e1.target_processor == e2.target_processor
0555 && e1.local == e2.local);
0556 }
0557
0558
0559 template<typename Edge>
0560 inline bool
0561 operator!=(const edge_descriptor<Edge>& e1,
0562 const edge_descriptor<Edge>& e2)
0563 { return !(e1 == e2); }
0564
0565
0566
0567
0568
0569
0570
0571 template<typename OutEdgeListS, typename ProcessGroup,
0572 typename InVertexListS, typename InDistribution,
0573 typename DirectedS, typename VertexProperty,
0574 typename EdgeProperty, typename GraphProperty,
0575 typename EdgeListS>
0576 struct adjacency_list_config
0577 {
0578 typedef typename mpl::if_<is_same<InVertexListS, defaultS>,
0579 vecS, InVertexListS>::type
0580 VertexListS;
0581
0582
0583 typedef property<edge_target_processor_id_t, processor_id_type,
0584 EdgeProperty> edge_property_with_id;
0585
0586
0587 typedef typename boost::mpl::if_<is_same<DirectedS, undirectedS>,
0588 property<edge_locally_owned_t, bool,
0589 edge_property_with_id>,
0590 edge_property_with_id>::type
0591 base_edge_property_type;
0592
0593
0594 typedef typename adjacency_list_traits<OutEdgeListS,
0595 VertexListS,
0596 directedS>::edge_descriptor
0597 local_edge_descriptor;
0598
0599
0600 typedef stored_in_edge<local_edge_descriptor> bidir_stored_edge;
0601
0602
0603
0604 typedef typename container_gen<EdgeListS, bidir_stored_edge>::type
0605 in_edge_list_type;
0606
0607
0608
0609 typedef typename boost::mpl::if_<is_same<DirectedS, bidirectionalS>,
0610 property<vertex_in_edges_t, in_edge_list_type,
0611 VertexProperty>,
0612 VertexProperty>::type
0613 base_vertex_property_type;
0614
0615
0616 typedef adjacency_list<OutEdgeListS,
0617 distributedS<ProcessGroup,
0618 VertexListS,
0619 InDistribution>,
0620 DirectedS, VertexProperty, EdgeProperty,
0621 GraphProperty, EdgeListS>
0622 graph_type;
0623
0624
0625 typedef adjacency_list<OutEdgeListS, VertexListS, directedS,
0626 base_vertex_property_type,
0627 base_edge_property_type,
0628 GraphProperty,
0629 EdgeListS>
0630 inherited;
0631
0632 typedef InDistribution in_distribution_type;
0633 typedef typename inherited::vertices_size_type vertices_size_type;
0634
0635 typedef typename ::boost::graph::distributed::select_distribution<
0636 in_distribution_type, VertexProperty, vertices_size_type,
0637 ProcessGroup>::type
0638 base_distribution_type;
0639
0640 typedef ::boost::graph::distributed::shuffled_distribution<
0641 base_distribution_type> distribution_type;
0642
0643 typedef VertexProperty vertex_property_type;
0644 typedef EdgeProperty edge_property_type;
0645 typedef ProcessGroup process_group_type;
0646
0647 typedef VertexListS vertex_list_selector;
0648 typedef OutEdgeListS out_edge_list_selector;
0649 typedef DirectedS directed_selector;
0650 typedef GraphProperty graph_property_type;
0651 typedef EdgeListS edge_list_selector;
0652 };
0653
0654
0655 template<typename IteratorPair, typename VertexIndexMap>
0656 void
0657 maybe_initialize_vertex_indices(IteratorPair p, VertexIndexMap to_index,
0658 read_write_property_map_tag)
0659 {
0660 typedef typename property_traits<VertexIndexMap>::value_type index_t;
0661 index_t next_index = 0;
0662 while (p.first != p.second)
0663 put(to_index, *p.first++, next_index++);
0664 }
0665
0666 template<typename IteratorPair, typename VertexIndexMap>
0667 inline void
0668 maybe_initialize_vertex_indices(IteratorPair p, VertexIndexMap to_index,
0669 readable_property_map_tag)
0670 {
0671
0672 }
0673
0674 template<typename IteratorPair, typename VertexIndexMap>
0675 inline void
0676 maybe_initialize_vertex_indices(IteratorPair p, VertexIndexMap to_index)
0677 {
0678 typedef typename property_traits<VertexIndexMap>::category category;
0679 maybe_initialize_vertex_indices(p, to_index, category());
0680 }
0681
0682 template<typename IteratorPair>
0683 inline void
0684 maybe_initialize_vertex_indices(IteratorPair p,
0685 ::boost::detail::error_property_not_found)
0686 { }
0687
0688
0689
0690
0691
0692
0693
0694
0695
0696 template<typename Vertex, typename LocalVertex>
0697 struct msg_add_edge_data
0698 {
0699 msg_add_edge_data() { }
0700
0701 msg_add_edge_data(Vertex source, Vertex target)
0702 : source(source.local), target(target) { }
0703
0704
0705
0706 LocalVertex source;
0707
0708
0709 Vertex target;
0710
0711 template<typename Archiver>
0712 void serialize(Archiver& ar, const unsigned int )
0713 {
0714 ar & unsafe_serialize(source) & target;
0715 }
0716 };
0717
0718
0719
0720
0721
0722 template<typename Vertex, typename LocalVertex, typename EdgeProperty>
0723 struct msg_add_edge_with_property_data
0724 : msg_add_edge_data<Vertex, LocalVertex>,
0725 maybe_store_property<EdgeProperty>
0726 {
0727 private:
0728 typedef msg_add_edge_data<Vertex, LocalVertex> inherited_data;
0729 typedef maybe_store_property<EdgeProperty> inherited_property;
0730
0731 public:
0732 msg_add_edge_with_property_data() { }
0733
0734 msg_add_edge_with_property_data(Vertex source,
0735 Vertex target,
0736 const EdgeProperty& property)
0737 : inherited_data(source, target),
0738 inherited_property(property) { }
0739
0740 template<typename Archiver>
0741 void serialize(Archiver& ar, const unsigned int )
0742 {
0743 ar & boost::serialization::base_object<inherited_data>(*this)
0744 & boost::serialization::base_object<inherited_property>(*this);
0745 }
0746 };
0747
0748
0749
0750
0751
0752
0753
0754
0755
0756
0757 template<typename Property>
0758 struct get_adj_list_pmap
0759 {
0760 template<typename Graph>
0761 struct apply
0762 {
0763 typedef Graph graph_type;
0764 typedef typename graph_type::process_group_type process_group_type;
0765 typedef typename graph_type::inherited base_graph_type;
0766 typedef typename property_map<base_graph_type, Property>::type
0767 local_pmap;
0768 typedef typename property_map<base_graph_type, Property>::const_type
0769 local_const_pmap;
0770
0771 typedef graph_traits<graph_type> traits;
0772 typedef typename graph_type::local_vertex_descriptor local_vertex;
0773 typedef typename property_traits<local_pmap>::key_type local_key_type;
0774
0775 typedef typename property_traits<local_pmap>::value_type value_type;
0776
0777 typedef typename property_map<Graph, vertex_global_t>::const_type
0778 vertex_global_map;
0779 typedef typename property_map<Graph, edge_global_t>::const_type
0780 edge_global_map;
0781
0782 typedef typename mpl::if_c<(is_same<local_key_type,
0783 local_vertex>::value),
0784 vertex_global_map, edge_global_map>::type
0785 global_map;
0786
0787 public:
0788 typedef ::boost::parallel::distributed_property_map<
0789 process_group_type, global_map, local_pmap> type;
0790
0791 typedef ::boost::parallel::distributed_property_map<
0792 process_group_type, global_map, local_const_pmap> const_type;
0793 };
0794 };
0795
0796
0797
0798
0799
0800 template<>
0801 struct get_adj_list_pmap<vertex_local_index_t>
0802 {
0803 template<typename Graph>
0804 struct apply
0805 : ::boost::property_map<typename Graph::inherited, vertex_index_t>
0806 { };
0807 };
0808
0809
0810
0811
0812
0813
0814
0815 template<>
0816 struct get_adj_list_pmap<vertex_index_t>
0817 {
0818 template<typename Graph>
0819 struct apply
0820 {
0821 private:
0822 typedef typename property_map<Graph, vertex_global_t>::const_type
0823 global_map;
0824
0825 typedef property_map<typename Graph::inherited, vertex_index_t> local;
0826
0827 public:
0828 typedef local_property_map<typename Graph::process_group_type,
0829 global_map,
0830 typename local::type> type;
0831 typedef local_property_map<typename Graph::process_group_type,
0832 global_map,
0833 typename local::const_type> const_type;
0834 };
0835 };
0836
0837
0838
0839
0840
0841 template<>
0842 struct get_adj_list_pmap<vertex_global_t>
0843 {
0844 template<typename Graph>
0845 struct apply
0846 {
0847 private:
0848 typedef typename Graph::local_vertex_descriptor
0849 local_vertex_descriptor;
0850 public:
0851 typedef global_descriptor_property_map<local_vertex_descriptor> type;
0852 typedef type const_type;
0853 };
0854 };
0855
0856
0857
0858
0859
0860 template<>
0861 struct get_adj_list_pmap<vertex_owner_t>
0862 {
0863 template<typename Graph>
0864 struct apply
0865 {
0866 private:
0867 typedef typename Graph::local_vertex_descriptor
0868 local_vertex_descriptor;
0869 public:
0870 typedef owner_property_map<local_vertex_descriptor> type;
0871 typedef type const_type;
0872 };
0873 };
0874
0875
0876
0877
0878
0879 template<>
0880 struct get_adj_list_pmap<vertex_local_t>
0881 {
0882 template<typename Graph>
0883 struct apply
0884 {
0885 private:
0886 typedef typename Graph::local_vertex_descriptor
0887 local_vertex_descriptor;
0888 public:
0889 typedef local_descriptor_property_map<local_vertex_descriptor> type;
0890 typedef type const_type;
0891 };
0892 };
0893
0894
0895
0896
0897
0898 template<>
0899 struct get_adj_list_pmap<edge_global_t>
0900 {
0901 template<typename Graph>
0902 struct apply
0903 {
0904 private:
0905 typedef typename Graph::local_edge_descriptor
0906 local_edge_descriptor;
0907 public:
0908 typedef edge_global_property_map<local_edge_descriptor> type;
0909 typedef type const_type;
0910 };
0911 };
0912
0913
0914
0915
0916
0917 template<>
0918 struct get_adj_list_pmap<edge_owner_t>
0919 {
0920 template<typename Graph>
0921 struct apply
0922 {
0923 private:
0924 typedef typename Graph::local_edge_descriptor
0925 local_edge_descriptor;
0926 public:
0927 typedef edge_owner_property_map<local_edge_descriptor> type;
0928 typedef type const_type;
0929 };
0930 };
0931
0932
0933
0934
0935
0936 template<>
0937 struct get_adj_list_pmap<edge_local_t>
0938 {
0939 template<typename Graph>
0940 struct apply
0941 {
0942 private:
0943 typedef typename Graph::local_edge_descriptor
0944 local_edge_descriptor;
0945 public:
0946 typedef edge_local_property_map<local_edge_descriptor> type;
0947 typedef type const_type;
0948 };
0949 };
0950
0951
0952
0953 template<typename Graph>
0954 inline void
0955 remove_in_edge(typename Graph::edge_descriptor, Graph&, directedS)
0956 { }
0957
0958
0959
0960 template<typename Graph>
0961 inline void
0962 remove_in_edge(typename Graph::edge_descriptor e, Graph& g, bidirectionalS)
0963 {
0964 typedef typename Graph::in_edge_list_type in_edge_list_type;
0965 in_edge_list_type& in_edges =
0966 get(vertex_in_edges, g.base())[target(e, g).local];
0967 typename in_edge_list_type::iterator i = in_edges.begin();
0968 while (i != in_edges.end()
0969 && !(i->source_processor == source(e, g).owner)
0970 && i->e == e.local)
0971 ++i;
0972
0973 BOOST_ASSERT(i != in_edges.end());
0974 in_edges.erase(i);
0975 }
0976
0977
0978 template<typename Graph>
0979 inline void
0980 remove_in_edge(typename Graph::edge_descriptor e, Graph& g, undirectedS)
0981 {
0982 typedef typename Graph::inherited base_type;
0983 typedef typename graph_traits<Graph>::vertex_descriptor vertex_descriptor;
0984
0985
0986
0987 base_type& bg = g.base();
0988 vertex_descriptor u = source(e, g);
0989 vertex_descriptor v = target(e, g);
0990 if (v.owner != process_id(g.process_group())) {
0991 using std::swap;
0992 swap(u, v);
0993 }
0994
0995 typename graph_traits<base_type>::out_edge_iterator ei, ei_end;
0996 for (boost::tie(ei, ei_end) = out_edges(v.local, bg); ei != ei_end; ++ei)
0997 {
0998 if (target(*ei, g.base()) == u.local
0999
1000 && get(edge_target_processor_id, bg, *ei) == u.owner) {
1001 remove_edge(ei, bg);
1002 return;
1003 }
1004 }
1005
1006 if (v.owner == process_id(g.process_group())) {
1007
1008 }
1009 }
1010
1011
1012
1013
1014
1015
1016
1017 template <class Graph, class Config, class Base>
1018 inline std::pair<typename Config::edge_descriptor, bool>
1019 add_local_edge(typename Config::vertex_descriptor u,
1020 typename Config::vertex_descriptor v,
1021 const typename Config::edge_property_type& p,
1022 vec_adj_list_impl<Graph, Config, Base>& g_)
1023 {
1024 adj_list_helper<Config, Base>& g = g_;
1025 return add_edge(u, v, p, g);
1026 }
1027
1028 template <class Graph, class Config, class Base>
1029 inline std::pair<typename Config::edge_descriptor, bool>
1030 add_local_edge(typename Config::vertex_descriptor u,
1031 typename Config::vertex_descriptor v,
1032 const typename Config::edge_property_type& p,
1033 boost::adj_list_impl<Graph, Config, Base>& g)
1034 {
1035 return add_edge(u, v, p, g);
1036 }
1037
1038 template <class EdgeProperty,class EdgeDescriptor>
1039 struct msg_nonlocal_edge_data
1040 : public detail::parallel::maybe_store_property<EdgeProperty>
1041 {
1042 typedef EdgeProperty edge_property_type;
1043 typedef EdgeDescriptor local_edge_descriptor;
1044 typedef detail::parallel::maybe_store_property<edge_property_type>
1045 inherited;
1046
1047 msg_nonlocal_edge_data() {}
1048 msg_nonlocal_edge_data(local_edge_descriptor e,
1049 const edge_property_type& p)
1050 : inherited(p), e(e) { }
1051
1052 local_edge_descriptor e;
1053
1054 template<typename Archiver>
1055 void serialize(Archiver& ar, const unsigned int )
1056 {
1057 ar & boost::serialization::base_object<inherited>(*this) & e;
1058 }
1059 };
1060
1061 template <class EdgeDescriptor>
1062 struct msg_remove_edge_data
1063 {
1064 typedef EdgeDescriptor edge_descriptor;
1065 msg_remove_edge_data() {}
1066 explicit msg_remove_edge_data(edge_descriptor e) : e(e) {}
1067
1068 edge_descriptor e;
1069
1070 template<typename Archiver>
1071 void serialize(Archiver& ar, const unsigned int )
1072 {
1073 ar & e;
1074 }
1075 };
1076
1077 } }
1078
1079
1080
1081
1082
1083
1084 template<typename OutEdgeListS, typename ProcessGroup,
1085 typename InVertexListS, typename InDistribution, typename DirectedS>
1086 struct adjacency_list_traits<OutEdgeListS,
1087 distributedS<ProcessGroup,
1088 InVertexListS,
1089 InDistribution>,
1090 DirectedS>
1091 {
1092 private:
1093 typedef typename mpl::if_<is_same<InVertexListS, defaultS>,
1094 vecS,
1095 InVertexListS>::type VertexListS;
1096
1097 typedef adjacency_list_traits<OutEdgeListS, VertexListS, directedS>
1098 base_type;
1099
1100 public:
1101 typedef typename base_type::vertex_descriptor local_vertex_descriptor;
1102 typedef typename base_type::edge_descriptor local_edge_descriptor;
1103
1104 typedef typename boost::mpl::if_<typename DirectedS::is_bidir_t,
1105 bidirectional_tag,
1106 typename boost::mpl::if_<typename DirectedS::is_directed_t,
1107 directed_tag, undirected_tag
1108 >::type
1109 >::type directed_category;
1110
1111 typedef typename parallel_edge_traits<OutEdgeListS>::type
1112 edge_parallel_category;
1113
1114 typedef detail::parallel::global_descriptor<local_vertex_descriptor>
1115 vertex_descriptor;
1116
1117 typedef detail::parallel::edge_descriptor<local_edge_descriptor>
1118 edge_descriptor;
1119 };
1120
1121 #define PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS \
1122 typename OutEdgeListS, typename ProcessGroup, typename InVertexListS, \
1123 typename InDistribution, typename DirectedS, typename VertexProperty, \
1124 typename EdgeProperty, typename GraphProperty, typename EdgeListS
1125
1126 #define PBGL_DISTRIB_ADJLIST_TYPE \
1127 adjacency_list<OutEdgeListS, \
1128 distributedS<ProcessGroup, InVertexListS, InDistribution>, \
1129 DirectedS, VertexProperty, EdgeProperty, GraphProperty, \
1130 EdgeListS>
1131
1132 #define PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS_CONFIG \
1133 typename OutEdgeListS, typename ProcessGroup, typename InVertexListS, \
1134 typename InDistribution, typename VertexProperty, \
1135 typename EdgeProperty, typename GraphProperty, typename EdgeListS
1136
1137 #define PBGL_DISTRIB_ADJLIST_TYPE_CONFIG(directed) \
1138 adjacency_list<OutEdgeListS, \
1139 distributedS<ProcessGroup, InVertexListS, InDistribution>, \
1140 directed, VertexProperty, EdgeProperty, GraphProperty, \
1141 EdgeListS>
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262 template<typename OutEdgeListS, typename ProcessGroup,
1263 typename InVertexListS, typename InDistribution, typename DirectedS,
1264 typename VertexProperty, typename EdgeProperty,
1265 typename GraphProperty, typename EdgeListS>
1266 class adjacency_list<OutEdgeListS,
1267 distributedS<ProcessGroup,
1268 InVertexListS,
1269 InDistribution>,
1270 DirectedS, VertexProperty,
1271 EdgeProperty, GraphProperty, EdgeListS>
1272 :
1273 public graph::distributed::maybe_named_graph<
1274 adjacency_list<OutEdgeListS,
1275 distributedS<ProcessGroup,
1276 InVertexListS,
1277 InDistribution>,
1278 DirectedS, VertexProperty,
1279 EdgeProperty, GraphProperty, EdgeListS>,
1280 typename adjacency_list_traits<OutEdgeListS,
1281 distributedS<ProcessGroup,
1282 InVertexListS,
1283 InDistribution>,
1284 DirectedS>::vertex_descriptor,
1285 typename adjacency_list_traits<OutEdgeListS,
1286 distributedS<ProcessGroup,
1287 InVertexListS,
1288 InDistribution>,
1289 DirectedS>::edge_descriptor,
1290 detail::parallel::adjacency_list_config<OutEdgeListS, ProcessGroup,
1291 InVertexListS, InDistribution,
1292 DirectedS, VertexProperty,
1293 EdgeProperty, GraphProperty,
1294 EdgeListS> >
1295 {
1296 typedef detail::parallel::adjacency_list_config<OutEdgeListS, ProcessGroup,
1297 InVertexListS, InDistribution,
1298 DirectedS, VertexProperty,
1299 EdgeProperty, GraphProperty,
1300 EdgeListS>
1301 config_type;
1302
1303 typedef adjacency_list_traits<OutEdgeListS,
1304 distributedS<ProcessGroup,
1305 InVertexListS,
1306 InDistribution>,
1307 DirectedS>
1308 traits_type;
1309
1310 typedef typename DirectedS::is_directed_t is_directed;
1311
1312 typedef EdgeListS edge_list_selector;
1313
1314 public:
1315
1316
1317 typedef typename config_type::in_edge_list_type in_edge_list_type;
1318
1319
1320
1321 typedef typename config_type::inherited inherited;
1322
1323
1324
1325
1326 typedef typename inherited::vertex_property_type
1327 base_vertex_property_type;
1328
1329
1330 typedef typename config_type::graph_type graph_type;
1331
1332
1333 typedef typename traits_type::local_vertex_descriptor
1334 local_vertex_descriptor;
1335 typedef typename traits_type::local_edge_descriptor
1336 local_edge_descriptor;
1337 typedef typename traits_type::vertex_descriptor vertex_descriptor;
1338 typedef typename traits_type::edge_descriptor edge_descriptor;
1339
1340 typedef typename traits_type::directed_category directed_category;
1341 typedef typename inherited::edge_parallel_category
1342 edge_parallel_category;
1343 typedef typename inherited::graph_tag graph_tag;
1344
1345
1346
1347
1348
1349 BOOST_STATIC_ASSERT((is_same<edge_parallel_category,
1350 allow_parallel_edge_tag>::value));
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362 typedef typename boost::mpl::if_<
1363 is_same<DirectedS, directedS>,
1364 directed_distributed_adj_list_tag,
1365 typename boost::mpl::if_<is_same<DirectedS, bidirectionalS>,
1366 bidirectional_distributed_adj_list_tag,
1367 undirected_distributed_adj_list_tag>::type>
1368 ::type traversal_category;
1369
1370 typedef typename inherited::degree_size_type degree_size_type;
1371 typedef typename inherited::vertices_size_type vertices_size_type;
1372 typedef typename inherited::edges_size_type edges_size_type;
1373 typedef VertexProperty vertex_property_type;
1374 typedef EdgeProperty edge_property_type;
1375 typedef typename inherited::graph_property_type graph_property_type;
1376 typedef typename inherited::vertex_bundled vertex_bundled;
1377 typedef typename inherited::edge_bundled edge_bundled;
1378 typedef typename inherited::graph_bundled graph_bundled;
1379
1380 typedef typename container_gen<edge_list_selector, edge_descriptor>::type
1381 local_edge_list_type;
1382
1383 private:
1384 typedef typename boost::mpl::if_<is_same<DirectedS, bidirectionalS>,
1385 typename in_edge_list_type::const_iterator,
1386 typename inherited::out_edge_iterator>::type
1387 base_in_edge_iterator;
1388
1389 typedef typename inherited::out_edge_iterator base_out_edge_iterator;
1390 typedef typename graph_traits<inherited>::edge_iterator
1391 base_edge_iterator;
1392 typedef typename inherited::edge_property_type base_edge_property_type;
1393
1394 typedef typename local_edge_list_type::const_iterator
1395 undirected_edge_iterator;
1396
1397 typedef InDistribution in_distribution_type;
1398
1399 typedef parallel::trigger_receive_context trigger_receive_context;
1400
1401 public:
1402
1403 typedef transform_iterator<typename vertex_descriptor::generator,
1404 typename inherited::vertex_iterator>
1405 vertex_iterator;
1406
1407
1408 typedef typename edge_descriptor::template out_generator<adjacency_list>
1409 out_edge_generator;
1410
1411
1412 typedef transform_iterator<out_edge_generator,
1413 typename inherited::out_edge_iterator>
1414 out_edge_iterator;
1415
1416
1417 typedef typename edge_descriptor::template in_generator<adjacency_list>
1418 in_edge_generator;
1419
1420
1421 typedef transform_iterator<in_edge_generator, base_in_edge_iterator>
1422 in_edge_iterator;
1423
1424
1425 typedef boost::adjacency_iterator<
1426 adjacency_list, vertex_descriptor, out_edge_iterator,
1427 typename std::iterator_traits<base_out_edge_iterator>
1428 ::difference_type>
1429 adjacency_iterator;
1430
1431
1432 typedef typename boost::mpl::if_<is_same<DirectedS, undirectedS>,
1433 undirected_edge_iterator,
1434 transform_iterator<out_edge_generator,
1435 base_edge_iterator>
1436 >::type
1437 edge_iterator;
1438
1439 public:
1440
1441 typedef graph::distributed::maybe_named_graph<graph_type,
1442 vertex_descriptor,
1443 edge_descriptor,
1444 config_type>
1445 named_graph_mixin;
1446
1447
1448 typedef ProcessGroup process_group_type;
1449
1450
1451 typedef typename process_group_type::process_id_type process_id_type;
1452
1453
1454 typedef DirectedS directed_selector;
1455
1456
1457 struct lazy_add_vertex_with_property;
1458 friend struct lazy_add_vertex_with_property;
1459
1460
1461 struct lazy_add_edge;
1462 friend struct lazy_add_edge;
1463
1464
1465 struct lazy_add_edge_with_property;
1466 friend struct lazy_add_edge_with_property;
1467
1468
1469
1470 typedef typename graph::distributed::select_distribution<
1471 InDistribution, VertexProperty, vertices_size_type,
1472 ProcessGroup>::default_type
1473 default_distribution_type;
1474
1475
1476
1477 typedef typename graph::distributed::select_distribution<
1478 InDistribution, VertexProperty, vertices_size_type,
1479 ProcessGroup>::type
1480 base_distribution_type;
1481
1482 typedef graph::distributed::shuffled_distribution<
1483 base_distribution_type> distribution_type;
1484
1485 private:
1486
1487
1488
1489 adjacency_list(const adjacency_list& other);
1490 adjacency_list& operator=(const adjacency_list& other);
1491
1492 public:
1493 adjacency_list(const ProcessGroup& pg = ProcessGroup())
1494 : named_graph_mixin(pg, default_distribution_type(pg, 0)),
1495 m_local_graph(GraphProperty()),
1496 process_group_(pg, boost::parallel::attach_distributed_object())
1497 {
1498 setup_triggers();
1499 }
1500
1501 adjacency_list(const ProcessGroup& pg,
1502 const base_distribution_type& distribution)
1503 : named_graph_mixin(pg, distribution),
1504 m_local_graph(GraphProperty()),
1505 process_group_(pg, boost::parallel::attach_distributed_object())
1506 {
1507 setup_triggers();
1508 }
1509
1510 adjacency_list(const GraphProperty& g,
1511 const ProcessGroup& pg = ProcessGroup())
1512 : named_graph_mixin(pg, default_distribution_type(pg, 0)),
1513 m_local_graph(g),
1514 process_group_(pg, boost::parallel::attach_distributed_object())
1515 {
1516 setup_triggers();
1517 }
1518
1519 adjacency_list(vertices_size_type n,
1520 const GraphProperty& p,
1521 const ProcessGroup& pg,
1522 const base_distribution_type& distribution)
1523 : named_graph_mixin(pg, distribution),
1524 m_local_graph(distribution.block_size(process_id(pg), n), p),
1525 process_group_(pg, boost::parallel::attach_distributed_object())
1526 {
1527 setup_triggers();
1528
1529 detail::parallel::maybe_initialize_vertex_indices(vertices(base()),
1530 get(vertex_index, base()));
1531 }
1532
1533 adjacency_list(vertices_size_type n,
1534 const ProcessGroup& pg,
1535 const base_distribution_type& distribution)
1536 : named_graph_mixin(pg, distribution),
1537 m_local_graph(distribution.block_size(process_id(pg), n), GraphProperty()),
1538 process_group_(pg, boost::parallel::attach_distributed_object())
1539 {
1540 setup_triggers();
1541
1542 detail::parallel::maybe_initialize_vertex_indices(vertices(base()),
1543 get(vertex_index, base()));
1544 }
1545
1546 adjacency_list(vertices_size_type n,
1547 const GraphProperty& p,
1548 const ProcessGroup& pg = ProcessGroup())
1549 : named_graph_mixin(pg, default_distribution_type(pg, n)),
1550 m_local_graph(this->distribution().block_size(process_id(pg), n), p),
1551 process_group_(pg, boost::parallel::attach_distributed_object())
1552 {
1553 setup_triggers();
1554
1555 detail::parallel::maybe_initialize_vertex_indices(vertices(base()),
1556 get(vertex_index, base()));
1557 }
1558
1559 adjacency_list(vertices_size_type n,
1560 const ProcessGroup& pg = ProcessGroup())
1561 : named_graph_mixin(pg, default_distribution_type(pg, n)),
1562 m_local_graph(this->distribution().block_size(process_id(pg), n),
1563 GraphProperty()),
1564 process_group_(pg, boost::parallel::attach_distributed_object())
1565 {
1566 setup_triggers();
1567
1568 detail::parallel::maybe_initialize_vertex_indices(vertices(base()),
1569 get(vertex_index, base()));
1570 }
1571
1572
1573
1574
1575
1576
1577
1578 template <class EdgeIterator>
1579 adjacency_list(EdgeIterator first, EdgeIterator last,
1580 vertices_size_type n,
1581 const ProcessGroup& pg = ProcessGroup(),
1582 const GraphProperty& p = GraphProperty())
1583 : named_graph_mixin(pg, default_distribution_type(pg, n)),
1584 m_local_graph(this->distribution().block_size(process_id(pg), n), p),
1585 process_group_(pg, boost::parallel::attach_distributed_object())
1586 {
1587 setup_triggers();
1588
1589 typedef typename config_type::VertexListS vertex_list_selector;
1590 initialize(first, last, n, this->distribution(), vertex_list_selector());
1591 detail::parallel::maybe_initialize_vertex_indices(vertices(base()),
1592 get(vertex_index, base()));
1593
1594 }
1595
1596 template <class EdgeIterator, class EdgePropertyIterator>
1597 adjacency_list(EdgeIterator first, EdgeIterator last,
1598 EdgePropertyIterator ep_iter,
1599 vertices_size_type n,
1600 const ProcessGroup& pg = ProcessGroup(),
1601 const GraphProperty& p = GraphProperty())
1602 : named_graph_mixin(pg, default_distribution_type(pg, n)),
1603 m_local_graph(this->distribution().block_size(process_id(pg), n), p),
1604 process_group_(pg, boost::parallel::attach_distributed_object())
1605 {
1606 setup_triggers();
1607
1608 typedef typename config_type::VertexListS vertex_list_selector;
1609 initialize(first, last, ep_iter, n, this->distribution(),
1610 vertex_list_selector());
1611 detail::parallel::maybe_initialize_vertex_indices(vertices(base()),
1612 get(vertex_index, base()));
1613
1614 }
1615
1616 template <class EdgeIterator>
1617 adjacency_list(EdgeIterator first, EdgeIterator last,
1618 vertices_size_type n,
1619 const ProcessGroup& pg,
1620 const base_distribution_type& distribution,
1621 const GraphProperty& p = GraphProperty())
1622 : named_graph_mixin(pg, distribution),
1623 m_local_graph(distribution.block_size(process_id(pg), n), p),
1624 process_group_(pg, boost::parallel::attach_distributed_object())
1625 {
1626 setup_triggers();
1627
1628 typedef typename config_type::VertexListS vertex_list_selector;
1629 initialize(first, last, n, this->distribution(), vertex_list_selector());
1630 detail::parallel::maybe_initialize_vertex_indices(vertices(base()),
1631 get(vertex_index, base()));
1632
1633 }
1634
1635 template <class EdgeIterator, class EdgePropertyIterator>
1636 adjacency_list(EdgeIterator first, EdgeIterator last,
1637 EdgePropertyIterator ep_iter,
1638 vertices_size_type n,
1639 const ProcessGroup& pg,
1640 const base_distribution_type& distribution,
1641 const GraphProperty& p = GraphProperty())
1642 : named_graph_mixin(pg, distribution),
1643 m_local_graph(this->distribution().block_size(process_id(pg), n), p),
1644 process_group_(pg, boost::parallel::attach_distributed_object())
1645 {
1646 setup_triggers();
1647
1648 typedef typename config_type::VertexListS vertex_list_selector;
1649 initialize(first, last, ep_iter, n, distribution,
1650 vertex_list_selector());
1651 detail::parallel::maybe_initialize_vertex_indices(vertices(base()),
1652 get(vertex_index, base()));
1653
1654 }
1655
1656 ~adjacency_list()
1657 {
1658 synchronize(process_group_);
1659 }
1660
1661 void clear()
1662 {
1663 base().clear();
1664 local_edges_.clear();
1665 named_graph_mixin::clearing_graph();
1666 }
1667
1668 void swap(adjacency_list& other)
1669 {
1670 using std::swap;
1671
1672 base().swap(other);
1673 swap(process_group_, other.process_group_);
1674 }
1675
1676 static vertex_descriptor null_vertex()
1677 {
1678 return vertex_descriptor(processor_id_type(0),
1679 inherited::null_vertex());
1680 }
1681
1682 inherited& base() { return m_local_graph; }
1683 const inherited& base() const { return m_local_graph; }
1684
1685 processor_id_type processor() const { return process_id(process_group_); }
1686 process_group_type process_group() const { return process_group_.base(); }
1687
1688 local_edge_list_type& local_edges() { return local_edges_; }
1689 const local_edge_list_type& local_edges() const { return local_edges_; }
1690
1691
1692
1693 template<typename VertexProcessorMap>
1694 void redistribute(VertexProcessorMap vertex_to_processor);
1695
1696
1697 vertex_bundled& operator[](vertex_descriptor v)
1698 {
1699 BOOST_ASSERT(v.owner == processor());
1700 return base()[v.local];
1701 }
1702
1703 const vertex_bundled& operator[](vertex_descriptor v) const
1704 {
1705 BOOST_ASSERT(v.owner == processor());
1706 return base()[v.local];
1707 }
1708
1709 edge_bundled& operator[](edge_descriptor e)
1710 {
1711 BOOST_ASSERT(e.owner() == processor());
1712 return base()[e.local];
1713 }
1714
1715 const edge_bundled& operator[](edge_descriptor e) const
1716 {
1717 BOOST_ASSERT(e.owner() == processor());
1718 return base()[e.local];
1719 }
1720
1721 graph_bundled& operator[](graph_bundle_t)
1722 { return get_property(*this); }
1723
1724 graph_bundled const& operator[](graph_bundle_t) const
1725 { return get_property(*this); }
1726
1727 template<typename OStreamConstructibleArchive>
1728 void save(std::string const& filename) const;
1729
1730 template<typename IStreamConstructibleArchive>
1731 void load(std::string const& filename);
1732
1733
1734 boost::function<void(vertex_descriptor, adjacency_list&)> on_add_vertex;
1735
1736
1737 boost::function<void(edge_descriptor, adjacency_list&)> on_add_edge;
1738
1739 private:
1740
1741 template<typename VertexProcessorMap>
1742 void
1743 request_in_neighbors(vertex_descriptor,
1744 VertexProcessorMap,
1745 directedS) { }
1746
1747
1748 template<typename VertexProcessorMap>
1749 void
1750 request_in_neighbors(vertex_descriptor,
1751 VertexProcessorMap,
1752 undirectedS) { }
1753
1754
1755 template<typename VertexProcessorMap>
1756 void
1757 request_in_neighbors(vertex_descriptor v,
1758 VertexProcessorMap vertex_to_processor,
1759 bidirectionalS);
1760
1761
1762 void clear_in_edges_local(vertex_descriptor v, directedS) {}
1763 void clear_in_edges_local(vertex_descriptor v, undirectedS) {}
1764
1765 void clear_in_edges_local(vertex_descriptor v, bidirectionalS)
1766 { get(vertex_in_edges, base())[v.local].clear(); }
1767
1768
1769 template<typename VertexProcessorMap>
1770 void
1771 remove_migrated_in_edges(vertex_descriptor,
1772 VertexProcessorMap,
1773 directedS) { }
1774
1775
1776 template<typename VertexProcessorMap>
1777 void
1778 remove_migrated_in_edges(vertex_descriptor,
1779 VertexProcessorMap,
1780 undirectedS) { }
1781
1782
1783 template<typename VertexProcessorMap>
1784 void
1785 remove_migrated_in_edges(vertex_descriptor v,
1786 VertexProcessorMap vertex_to_processor,
1787 bidirectionalS);
1788
1789
1790
1791
1792
1793 template<typename EdgeIterator>
1794 void
1795 initialize(EdgeIterator first, EdgeIterator last,
1796 vertices_size_type, const base_distribution_type& distribution,
1797 vecS);
1798
1799
1800
1801
1802
1803 template<typename EdgeIterator, typename EdgePropertyIterator>
1804 void
1805 initialize(EdgeIterator first, EdgeIterator last,
1806 EdgePropertyIterator ep_iter,
1807 vertices_size_type, const base_distribution_type& distribution,
1808 vecS);
1809
1810
1811
1812 template<typename EdgeIterator, typename EdgePropertyIterator,
1813 typename VertexListS>
1814 void
1815 initialize(EdgeIterator first, EdgeIterator last,
1816 EdgePropertyIterator ep_iter,
1817 vertices_size_type n,
1818 const base_distribution_type& distribution,
1819 VertexListS);
1820
1821
1822
1823
1824
1825
1826 template<typename EdgeIterator, typename VertexListS>
1827 void
1828 initialize(EdgeIterator first, EdgeIterator last,
1829 vertices_size_type n,
1830 const base_distribution_type& distribution,
1831 VertexListS);
1832
1833 public:
1834
1835
1836
1837
1838 base_vertex_property_type
1839 build_vertex_property(const vertex_property_type& p)
1840 { return build_vertex_property(p, directed_selector()); }
1841
1842 base_vertex_property_type
1843 build_vertex_property(const vertex_property_type& p, directedS)
1844 {
1845 return base_vertex_property_type(p);
1846 }
1847
1848 base_vertex_property_type
1849 build_vertex_property(const vertex_property_type& p, bidirectionalS)
1850 {
1851 return base_vertex_property_type(in_edge_list_type(), p);
1852 }
1853
1854 base_vertex_property_type
1855 build_vertex_property(const vertex_property_type& p, undirectedS)
1856 {
1857 return base_vertex_property_type(p);
1858 }
1859
1860
1861
1862
1863
1864
1865 base_edge_property_type build_edge_property(const edge_property_type& p)
1866 { return build_edge_property(p, directed_selector()); }
1867
1868 base_edge_property_type
1869 build_edge_property(const edge_property_type& p, directedS)
1870 {
1871 return base_edge_property_type(0, p);
1872 }
1873
1874 base_edge_property_type
1875 build_edge_property(const edge_property_type& p, bidirectionalS)
1876 {
1877 return base_edge_property_type(0, p);
1878 }
1879
1880 base_edge_property_type
1881 build_edge_property(const edge_property_type& p, undirectedS)
1882 {
1883 typedef typename base_edge_property_type::next_type
1884 edge_property_with_id;
1885 return base_edge_property_type(true, edge_property_with_id(0, p));
1886 }
1887
1888
1889
1890
1891 edge_property_type split_edge_property(const base_edge_property_type& p)
1892 { return split_edge_property(p, directed_selector()); }
1893
1894 edge_property_type
1895 split_edge_property(const base_edge_property_type& p, directedS)
1896 {
1897 return p.m_base;
1898 }
1899
1900 edge_property_type
1901 split_edge_property(const base_edge_property_type& p, bidirectionalS)
1902 {
1903 return p.m_base;
1904 }
1905
1906 edge_property_type
1907 split_edge_property(const base_edge_property_type& p, undirectedS)
1908 {
1909 return p.m_base.m_base;
1910 }
1911
1912
1913
1914
1915
1916
1917 enum {
1918
1919
1920
1921
1922
1923 msg_add_vertex_with_property = 0,
1924
1925
1926
1927
1928
1929
1930
1931 msg_add_vertex_with_property_and_reply,
1932
1933
1934
1935
1936
1937 msg_add_vertex_reply,
1938
1939
1940
1941
1942
1943 msg_add_edge,
1944
1945
1946
1947
1948
1949 msg_add_edge_with_property,
1950
1951
1952
1953
1954
1955
1956 msg_add_edge_with_reply,
1957
1958
1959
1960
1961
1962
1963 msg_add_edge_with_property_and_reply,
1964
1965
1966
1967
1968
1969
1970 msg_add_edge_reply,
1971
1972
1973
1974
1975
1976
1977
1978 msg_nonlocal_edge,
1979
1980
1981
1982
1983
1984
1985 msg_remove_edge,
1986
1987
1988
1989
1990
1991
1992
1993 msg_num_relocated
1994 };
1995
1996 typedef detail::parallel::msg_add_edge_data<vertex_descriptor,
1997 local_vertex_descriptor>
1998 msg_add_edge_data;
1999
2000 typedef detail::parallel::msg_add_edge_with_property_data
2001 <vertex_descriptor, local_vertex_descriptor,
2002 edge_property_type> msg_add_edge_with_property_data;
2003
2004 typedef boost::detail::parallel::msg_nonlocal_edge_data<
2005 edge_property_type,local_edge_descriptor> msg_nonlocal_edge_data;
2006
2007 typedef boost::detail::parallel::msg_remove_edge_data<edge_descriptor>
2008 msg_remove_edge_data;
2009
2010 void send_remove_edge_request(edge_descriptor e)
2011 {
2012 process_id_type dest = e.target_processor;
2013 if (e.target_processor == process_id(process_group_))
2014 dest = e.source_processor;
2015 send(process_group_, dest, msg_remove_edge, msg_remove_edge_data(e));
2016 }
2017
2018
2019 void setup_triggers();
2020
2021 void
2022 handle_add_vertex_with_property(int source, int tag,
2023 const vertex_property_type&,
2024 trigger_receive_context);
2025
2026 local_vertex_descriptor
2027 handle_add_vertex_with_property_and_reply(int source, int tag,
2028 const vertex_property_type&,
2029 trigger_receive_context);
2030
2031 void
2032 handle_add_edge(int source, int tag, const msg_add_edge_data& data,
2033 trigger_receive_context);
2034
2035 boost::parallel::detail::untracked_pair<edge_descriptor, bool>
2036 handle_add_edge_with_reply(int source, int tag,
2037 const msg_add_edge_data& data,
2038 trigger_receive_context);
2039
2040 void
2041 handle_add_edge_with_property(int source, int tag,
2042 const msg_add_edge_with_property_data&,
2043 trigger_receive_context);
2044
2045 boost::parallel::detail::untracked_pair<edge_descriptor, bool>
2046 handle_add_edge_with_property_and_reply
2047 (int source, int tag, const msg_add_edge_with_property_data&,
2048 trigger_receive_context);
2049
2050 void
2051 handle_nonlocal_edge(int source, int tag,
2052 const msg_nonlocal_edge_data& data,
2053 trigger_receive_context);
2054
2055 void
2056 handle_remove_edge(int source, int tag,
2057 const msg_remove_edge_data& data,
2058 trigger_receive_context);
2059
2060 protected:
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078 void
2079 add_remote_edge(const msg_nonlocal_edge_data&,
2080 processor_id_type, directedS)
2081 { }
2082
2083
2084
2085
2086
2087 void
2088 add_remote_edge(const msg_nonlocal_edge_data& data,
2089 processor_id_type other_proc, bidirectionalS)
2090 {
2091 typedef detail::parallel::stored_in_edge<local_edge_descriptor> stored_edge;
2092
2093 stored_edge edge(other_proc, data.e);
2094 local_vertex_descriptor v = target(data.e, base());
2095 boost::graph_detail::push(get(vertex_in_edges, base())[v], edge);
2096 }
2097
2098
2099
2100
2101 void
2102 add_remote_edge(const msg_nonlocal_edge_data& data,
2103 processor_id_type other_proc, undirectedS)
2104 {
2105 std::pair<local_edge_descriptor, bool> edge =
2106 detail::parallel::add_local_edge(target(data.e, base()),
2107 source(data.e, base()),
2108 build_edge_property(data.get_property()), base());
2109 BOOST_ASSERT(edge.second);
2110 put(edge_target_processor_id, base(), edge.first, other_proc);
2111
2112 if (edge.second && on_add_edge)
2113 on_add_edge(edge_descriptor(processor(), other_proc, false,
2114 edge.first),
2115 *this);
2116 }
2117
2118 void
2119 remove_local_edge(const msg_remove_edge_data&, processor_id_type,
2120 directedS)
2121 { }
2122
2123 void
2124 remove_local_edge(const msg_remove_edge_data& data,
2125 processor_id_type other_proc, bidirectionalS)
2126 {
2127
2128
2129
2130
2131 vertex_descriptor src = source(data.e, *this);
2132 vertex_descriptor tgt = target(data.e, *this);
2133
2134 if (src.owner == process_id(process_group_)) {
2135 base_out_edge_iterator ei, ei_end;
2136 for (boost::tie(ei, ei_end) = out_edges(src.local, base());
2137 ei != ei_end; ++ei) {
2138
2139
2140
2141 if (tgt.local == target(*ei, base())
2142 && get(edge_target_processor_id, base(), *ei) == other_proc)
2143 break;
2144 }
2145
2146 if (ei != ei_end) boost::remove_edge(ei, base());
2147
2148 remove_local_edge_from_list(src, tgt, undirectedS());
2149 } else {
2150 BOOST_ASSERT(tgt.owner == process_id(process_group_));
2151 in_edge_list_type& in_edges =
2152 get(vertex_in_edges, base())[tgt.local];
2153 typename in_edge_list_type::iterator ei;
2154 for (ei = in_edges.begin(); ei != in_edges.end(); ++ei) {
2155 if (src.local == source(ei->e, base())
2156 && src.owner == ei->source_processor)
2157 break;
2158 }
2159
2160 if (ei != in_edges.end()) in_edges.erase(ei);
2161 }
2162 }
2163
2164 void
2165 remove_local_edge(const msg_remove_edge_data& data,
2166 processor_id_type other_proc, undirectedS)
2167 {
2168 vertex_descriptor local_vertex = source(data.e, *this);
2169 vertex_descriptor remote_vertex = target(data.e, *this);
2170 if (remote_vertex.owner == process_id(process_group_)) {
2171 using std::swap;
2172 swap(local_vertex, remote_vertex);
2173 }
2174
2175
2176 {
2177 base_out_edge_iterator ei, ei_end;
2178 for (boost::tie(ei, ei_end) = out_edges(local_vertex.local, base());
2179 ei != ei_end; ++ei) {
2180
2181
2182
2183 if (remote_vertex.local == target(*ei, base())
2184 && get(edge_target_processor_id, base(), *ei) == other_proc)
2185 break;
2186 }
2187
2188 if (ei != ei_end) boost::remove_edge(ei, base());
2189 }
2190
2191 remove_local_edge_from_list(local_vertex, remote_vertex, undirectedS());
2192 }
2193
2194 public:
2195 void
2196 remove_local_edge_from_list(vertex_descriptor, vertex_descriptor,
2197 directedS)
2198 {
2199 }
2200
2201 void
2202 remove_local_edge_from_list(vertex_descriptor, vertex_descriptor,
2203 bidirectionalS)
2204 {
2205 }
2206
2207 void
2208 remove_local_edge_from_list(vertex_descriptor src, vertex_descriptor tgt,
2209 undirectedS)
2210 {
2211
2212
2213
2214 {
2215 typename local_edge_list_type::iterator ei;
2216 for (ei = local_edges_.begin(); ei != local_edges_.end(); ++ei) {
2217 if ((source(*ei, *this) == src
2218 && target(*ei, *this) == tgt)
2219 || (source(*ei, *this) == tgt
2220 && target(*ei, *this) == src))
2221 break;
2222 }
2223
2224 if (ei != local_edges_.end()) local_edges_.erase(ei);
2225 }
2226
2227 }
2228
2229 private:
2230
2231 inherited m_local_graph;
2232
2233
2234
2235 process_group_type process_group_;
2236
2237
2238
2239
2240 local_edge_list_type local_edges_;
2241 };
2242
2243
2244
2245 template<PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS>
2246 struct PBGL_DISTRIB_ADJLIST_TYPE::lazy_add_vertex_with_property
2247 {
2248
2249 lazy_add_vertex_with_property(adjacency_list& self,
2250 const vertex_property_type& property)
2251 : self(self), property(property), committed(false) { }
2252
2253
2254
2255
2256 lazy_add_vertex_with_property(const lazy_add_vertex_with_property& other)
2257 : self(other.self), property(other.property),
2258 committed(other.committed)
2259 {
2260 other.committed = true;
2261 }
2262
2263
2264
2265 ~lazy_add_vertex_with_property();
2266
2267
2268 operator vertex_descriptor() const { return commit(); }
2269
2270
2271
2272 vertex_descriptor commit() const;
2273
2274 protected:
2275 adjacency_list& self;
2276 vertex_property_type property;
2277 mutable bool committed;
2278
2279 private:
2280
2281 void operator=(lazy_add_vertex_with_property&);
2282 };
2283
2284 template<PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS>
2285 PBGL_DISTRIB_ADJLIST_TYPE::lazy_add_vertex_with_property::
2286 ~lazy_add_vertex_with_property()
2287 {
2288
2289
2290
2291 if (committed || boost::core::uncaught_exceptions() > 0)
2292 return;
2293
2294 committed = true;
2295
2296 process_id_type owner
2297 = static_cast<graph_type&>(self).owner_by_property(property);
2298 if (owner == self.processor()) {
2299
2300 vertex_descriptor v(owner,
2301 add_vertex(self.build_vertex_property(property),
2302 self.base()));
2303 if (self.on_add_vertex)
2304 self.on_add_vertex(v, self);
2305 }
2306 else
2307
2308
2309 send(self.process_group_, owner, msg_add_vertex_with_property,
2310 property);
2311 }
2312
2313 template<PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS>
2314 typename PBGL_DISTRIB_ADJLIST_TYPE::vertex_descriptor
2315 PBGL_DISTRIB_ADJLIST_TYPE::lazy_add_vertex_with_property::
2316 commit() const
2317 {
2318 BOOST_ASSERT(!this->committed);
2319 this->committed = true;
2320
2321 process_id_type owner
2322 = static_cast<graph_type&>(self).owner_by_property(property);
2323 local_vertex_descriptor local_v;
2324 if (owner == self.processor())
2325
2326 local_v = add_vertex(self.build_vertex_property(property),
2327 self.base());
2328 else {
2329
2330 send_oob_with_reply(self.process_group_, owner,
2331 msg_add_vertex_with_property_and_reply, property,
2332 local_v);
2333 }
2334
2335 vertex_descriptor v(owner, local_v);
2336 if (self.on_add_vertex)
2337 self.on_add_vertex(v, self);
2338
2339
2340 return v;
2341 }
2342
2343
2344
2345
2346
2347
2348
2349
2350 template<PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS>
2351 struct PBGL_DISTRIB_ADJLIST_TYPE::lazy_add_edge
2352 {
2353
2354 lazy_add_edge(adjacency_list& self,
2355 vertex_descriptor source, vertex_descriptor target)
2356 : self(self), source(source), target(target), committed(false) { }
2357
2358
2359
2360 lazy_add_edge(const lazy_add_edge& other)
2361 : self(other.self), source(other.source), target(other.target),
2362 committed(other.committed)
2363 {
2364 other.committed = true;
2365 }
2366
2367
2368
2369 ~lazy_add_edge();
2370
2371
2372 operator std::pair<edge_descriptor, bool>() const { return commit(); }
2373
2374
2375
2376 std::pair<edge_descriptor, bool> commit() const;
2377
2378 protected:
2379 std::pair<edge_descriptor, bool>
2380 add_local_edge(const edge_property_type& property, directedS) const;
2381
2382 std::pair<edge_descriptor, bool>
2383 add_local_edge(const edge_property_type& property, bidirectionalS) const;
2384
2385 std::pair<edge_descriptor, bool>
2386 add_local_edge(const edge_property_type& property, undirectedS) const;
2387
2388 adjacency_list& self;
2389 vertex_descriptor source;
2390 vertex_descriptor target;
2391 mutable bool committed;
2392
2393 private:
2394
2395 void operator=(lazy_add_edge&);
2396 };
2397
2398 template<PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS>
2399 PBGL_DISTRIB_ADJLIST_TYPE::lazy_add_edge::~lazy_add_edge()
2400 {
2401
2402
2403
2404 if (committed || boost::core::uncaught_exceptions() > 0)
2405 return;
2406
2407 committed = true;
2408
2409 if (source.owner == self.processor())
2410 this->add_local_edge(edge_property_type(), DirectedS());
2411 else
2412
2413
2414 send(self.process_group_, source.owner, msg_add_edge,
2415 msg_add_edge_data(source, target));
2416 }
2417
2418 template<PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS>
2419 std::pair<typename PBGL_DISTRIB_ADJLIST_TYPE::edge_descriptor, bool>
2420 PBGL_DISTRIB_ADJLIST_TYPE::lazy_add_edge::commit() const
2421 {
2422 BOOST_ASSERT(!committed);
2423 committed = true;
2424
2425 if (source.owner == self.processor())
2426 return this->add_local_edge(edge_property_type(), DirectedS());
2427 else {
2428
2429 boost::parallel::detail::untracked_pair<edge_descriptor, bool> result;
2430 send_oob_with_reply(self.process_group_, source.owner,
2431 msg_add_edge_with_reply,
2432 msg_add_edge_data(source, target), result);
2433 return result;
2434 }
2435 }
2436
2437
2438 template<PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS>
2439 std::pair<typename PBGL_DISTRIB_ADJLIST_TYPE::edge_descriptor, bool>
2440 PBGL_DISTRIB_ADJLIST_TYPE::lazy_add_edge::
2441 add_local_edge(const edge_property_type& property, directedS) const
2442 {
2443
2444 std::pair<local_edge_descriptor, bool> inserted =
2445 detail::parallel::add_local_edge(source.local, target.local,
2446 self.build_edge_property(property),
2447 self.base());
2448
2449 if (inserted.second)
2450
2451 put(edge_target_processor_id, self.base(), inserted.first,
2452 target.owner);
2453
2454
2455 edge_descriptor e(source.owner, target.owner, true, inserted.first);
2456
2457
2458 if (inserted.second && self.on_add_edge)
2459 self.on_add_edge(e, self);
2460
2461 return std::pair<edge_descriptor, bool>(e, inserted.second);
2462 }
2463
2464 template<PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS>
2465 std::pair<typename PBGL_DISTRIB_ADJLIST_TYPE::edge_descriptor, bool>
2466 PBGL_DISTRIB_ADJLIST_TYPE::lazy_add_edge::
2467 add_local_edge(const edge_property_type& property, bidirectionalS) const
2468 {
2469
2470 std::pair<edge_descriptor, bool> result
2471 = this->add_local_edge(property, directedS());
2472
2473 if (result.second) {
2474 if (target.owner == self.processor()) {
2475
2476 typedef detail::parallel::stored_in_edge<local_edge_descriptor>
2477 stored_edge;
2478
2479 stored_edge e(self.processor(), result.first.local);
2480 boost::graph_detail::push(get(vertex_in_edges,
2481 self.base())[target.local], e);
2482 }
2483 else {
2484
2485
2486 if (self.process_group_.trigger_context() == boost::parallel::trc_out_of_band)
2487 send_oob(self.process_group_, target.owner, msg_nonlocal_edge,
2488 msg_nonlocal_edge_data(result.first.local, property));
2489 else
2490 send(self.process_group_, target.owner, msg_nonlocal_edge,
2491 msg_nonlocal_edge_data(result.first.local, property));
2492 }
2493 }
2494
2495 return result;
2496 }
2497
2498 template<PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS>
2499 std::pair<typename PBGL_DISTRIB_ADJLIST_TYPE::edge_descriptor, bool>
2500 PBGL_DISTRIB_ADJLIST_TYPE::lazy_add_edge::
2501 add_local_edge(const edge_property_type& property, undirectedS) const
2502 {
2503
2504 std::pair<edge_descriptor, bool> result
2505 = this->add_local_edge(property, directedS());
2506
2507 if (result.second) {
2508 if (target.owner == self.processor()) {
2509
2510
2511
2512
2513
2514 local_edge_descriptor return_edge =
2515 detail::parallel::add_local_edge(target.local, source.local,
2516 self.build_edge_property(property),
2517 self.base()).first;
2518
2519 put(edge_target_processor_id, self.base(), return_edge,
2520 source.owner);
2521 }
2522 else {
2523
2524
2525 if (self.process_group_.trigger_context() == boost::parallel::trc_out_of_band)
2526 send_oob(self.process_group_, target.owner, msg_nonlocal_edge,
2527 msg_nonlocal_edge_data(result.first.local, property));
2528 else
2529 send(self.process_group_, target.owner, msg_nonlocal_edge,
2530 msg_nonlocal_edge_data(result.first.local, property));
2531
2532 }
2533
2534
2535 graph_detail::push(self.local_edges(), result.first);
2536 }
2537
2538 return result;
2539 }
2540
2541
2542
2543
2544
2545
2546
2547
2548 template<PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS>
2549 struct PBGL_DISTRIB_ADJLIST_TYPE::lazy_add_edge_with_property
2550 : lazy_add_edge
2551 {
2552
2553 lazy_add_edge_with_property(adjacency_list& self,
2554 vertex_descriptor source,
2555 vertex_descriptor target,
2556 const edge_property_type& property)
2557 : lazy_add_edge(self, source, target), property(property) { }
2558
2559
2560
2561 lazy_add_edge_with_property(const lazy_add_edge& other)
2562 : lazy_add_edge(other), property(other.property) { }
2563
2564
2565
2566 ~lazy_add_edge_with_property();
2567
2568
2569 operator std::pair<edge_descriptor, bool>() const { return commit(); }
2570
2571
2572
2573 std::pair<edge_descriptor, bool> commit() const;
2574
2575 private:
2576
2577 void operator=(lazy_add_edge_with_property&);
2578
2579 edge_property_type property;
2580 };
2581
2582 template<PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS>
2583 PBGL_DISTRIB_ADJLIST_TYPE::lazy_add_edge_with_property::
2584 ~lazy_add_edge_with_property()
2585 {
2586
2587
2588
2589 if (this->committed || boost::core::uncaught_exceptions() > 0)
2590 return;
2591
2592 this->committed = true;
2593
2594 if (this->source.owner == this->self.processor())
2595
2596 this->add_local_edge(property, DirectedS());
2597 else
2598
2599
2600 send(this->self.process_group_, this->source.owner,
2601 msg_add_edge_with_property,
2602 msg_add_edge_with_property_data(this->source, this->target,
2603 property));
2604 }
2605
2606 template<PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS>
2607 std::pair<typename PBGL_DISTRIB_ADJLIST_TYPE::edge_descriptor, bool>
2608 PBGL_DISTRIB_ADJLIST_TYPE::lazy_add_edge_with_property::
2609 commit() const
2610 {
2611 BOOST_ASSERT(!this->committed);
2612 this->committed = true;
2613
2614 if (this->source.owner == this->self.processor())
2615
2616 return this->add_local_edge(property, DirectedS());
2617 else {
2618
2619 boost::parallel::detail::untracked_pair<edge_descriptor, bool> result;
2620 send_oob_with_reply(this->self.process_group_, this->source.owner,
2621 msg_add_edge_with_property_and_reply,
2622 msg_add_edge_with_property_data(this->source,
2623 this->target,
2624 property),
2625 result);
2626 return result;
2627 }
2628 }
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638 template<PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS>
2639 std::pair<typename PBGL_DISTRIB_ADJLIST_TYPE
2640 ::vertex_iterator,
2641 typename PBGL_DISTRIB_ADJLIST_TYPE
2642 ::vertex_iterator>
2643 vertices(const PBGL_DISTRIB_ADJLIST_TYPE& g)
2644 {
2645 typedef typename PBGL_DISTRIB_ADJLIST_TYPE
2646 ::vertex_descriptor Vertex;
2647
2648 typedef typename Vertex::generator generator;
2649
2650 return std::make_pair(make_transform_iterator(vertices(g.base()).first,
2651 generator(g.processor())),
2652 make_transform_iterator(vertices(g.base()).second,
2653 generator(g.processor())));
2654 }
2655
2656
2657
2658
2659
2660
2661
2662
2663 template<PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS>
2664 typename PBGL_DISTRIB_ADJLIST_TYPE
2665 ::vertices_size_type
2666 num_vertices(const PBGL_DISTRIB_ADJLIST_TYPE& g)
2667 {
2668 return num_vertices(g.base());
2669 }
2670
2671
2672
2673
2674
2675
2676
2677 template<PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS, typename Edge>
2678 typename PBGL_DISTRIB_ADJLIST_TYPE::vertex_descriptor
2679 source(const detail::parallel::edge_descriptor<Edge>& e,
2680 const PBGL_DISTRIB_ADJLIST_TYPE& g)
2681 {
2682 typedef typename PBGL_DISTRIB_ADJLIST_TYPE
2683 ::vertex_descriptor Vertex;
2684 return Vertex(e.source_processor, source(e.local, g.base()));
2685 }
2686
2687
2688
2689
2690 template<PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS, typename Edge>
2691 typename PBGL_DISTRIB_ADJLIST_TYPE::vertex_descriptor
2692 target(const detail::parallel::edge_descriptor<Edge>& e,
2693 const PBGL_DISTRIB_ADJLIST_TYPE& g)
2694 {
2695 typedef typename PBGL_DISTRIB_ADJLIST_TYPE
2696 ::vertex_descriptor Vertex;
2697 return Vertex(e.target_processor, target(e.local, g.base()));
2698 }
2699
2700
2701
2702
2703
2704
2705 template<PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS>
2706 std::pair<typename PBGL_DISTRIB_ADJLIST_TYPE::out_edge_iterator,
2707 typename PBGL_DISTRIB_ADJLIST_TYPE::out_edge_iterator>
2708 out_edges(typename PBGL_DISTRIB_ADJLIST_TYPE::vertex_descriptor v,
2709 const PBGL_DISTRIB_ADJLIST_TYPE& g)
2710 {
2711 BOOST_ASSERT(v.owner == g.processor());
2712
2713 typedef PBGL_DISTRIB_ADJLIST_TYPE impl;
2714 typedef typename impl::out_edge_generator generator;
2715
2716 return std::make_pair(
2717 make_transform_iterator(out_edges(v.local, g.base()).first,
2718 generator(g)),
2719 make_transform_iterator(out_edges(v.local, g.base()).second,
2720 generator(g)));
2721 }
2722
2723
2724
2725
2726
2727
2728 template<PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS>
2729 typename PBGL_DISTRIB_ADJLIST_TYPE::degree_size_type
2730 out_degree(typename PBGL_DISTRIB_ADJLIST_TYPE::vertex_descriptor v,
2731 const PBGL_DISTRIB_ADJLIST_TYPE& g)
2732 {
2733 BOOST_ASSERT(v.owner == g.processor());
2734
2735 return out_degree(v.local, g.base());
2736 }
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746 template<PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS_CONFIG>
2747 std::pair<typename PBGL_DISTRIB_ADJLIST_TYPE_CONFIG(bidirectionalS)
2748 ::in_edge_iterator,
2749 typename PBGL_DISTRIB_ADJLIST_TYPE_CONFIG(bidirectionalS)
2750 ::in_edge_iterator>
2751 in_edges(typename PBGL_DISTRIB_ADJLIST_TYPE_CONFIG(bidirectionalS)
2752 ::vertex_descriptor v,
2753 const PBGL_DISTRIB_ADJLIST_TYPE_CONFIG(bidirectionalS)& g)
2754 {
2755 BOOST_ASSERT(v.owner == g.processor());
2756
2757 typedef PBGL_DISTRIB_ADJLIST_TYPE_CONFIG(bidirectionalS) impl;
2758 typedef typename impl::inherited base_graph_type;
2759 typedef typename impl::in_edge_generator generator;
2760
2761
2762 typename property_map<base_graph_type, vertex_in_edges_t>::const_type
2763 in_edges = get(vertex_in_edges, g.base());
2764
2765 return std::make_pair(make_transform_iterator(in_edges[v.local].begin(),
2766 generator(g)),
2767 make_transform_iterator(in_edges[v.local].end(),
2768 generator(g)));
2769 }
2770
2771
2772
2773
2774 template<PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS_CONFIG>
2775 std::pair<typename PBGL_DISTRIB_ADJLIST_TYPE_CONFIG(undirectedS)
2776 ::in_edge_iterator,
2777 typename PBGL_DISTRIB_ADJLIST_TYPE_CONFIG(undirectedS)
2778 ::in_edge_iterator>
2779 in_edges(typename PBGL_DISTRIB_ADJLIST_TYPE_CONFIG(undirectedS)
2780 ::vertex_descriptor v,
2781 const PBGL_DISTRIB_ADJLIST_TYPE_CONFIG(undirectedS)& g)
2782 {
2783 BOOST_ASSERT(v.owner == g.processor());
2784
2785 typedef PBGL_DISTRIB_ADJLIST_TYPE_CONFIG(undirectedS) impl;
2786 typedef typename impl::in_edge_generator generator;
2787
2788 return std::make_pair(
2789 make_transform_iterator(out_edges(v.local, g.base()).first,
2790 generator(g)),
2791 make_transform_iterator(out_edges(v.local, g.base()).second,
2792 generator(g)));
2793 }
2794
2795
2796
2797
2798
2799
2800 template<PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS_CONFIG>
2801 typename PBGL_DISTRIB_ADJLIST_TYPE_CONFIG(bidirectionalS)::degree_size_type
2802 in_degree(typename PBGL_DISTRIB_ADJLIST_TYPE_CONFIG(bidirectionalS)
2803 ::vertex_descriptor v,
2804 const PBGL_DISTRIB_ADJLIST_TYPE_CONFIG(bidirectionalS)& g)
2805 {
2806 BOOST_ASSERT(v.owner == g.processor());
2807
2808 return get(vertex_in_edges, g.base())[v.local].size();
2809 }
2810
2811
2812
2813
2814 template<PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS_CONFIG>
2815 typename PBGL_DISTRIB_ADJLIST_TYPE_CONFIG(undirectedS)::degree_size_type
2816 in_degree(typename PBGL_DISTRIB_ADJLIST_TYPE_CONFIG(undirectedS)
2817 ::vertex_descriptor v,
2818 const PBGL_DISTRIB_ADJLIST_TYPE_CONFIG(undirectedS)& g)
2819 {
2820 BOOST_ASSERT(v.owner == g.processor());
2821
2822 return out_degree(v.local, g.base());
2823 }
2824
2825
2826
2827
2828
2829
2830 template<PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS_CONFIG>
2831 typename PBGL_DISTRIB_ADJLIST_TYPE_CONFIG(undirectedS)
2832 ::degree_size_type
2833 degree(typename PBGL_DISTRIB_ADJLIST_TYPE_CONFIG(undirectedS)
2834 ::vertex_descriptor v,
2835 const PBGL_DISTRIB_ADJLIST_TYPE_CONFIG(undirectedS)& g)
2836 {
2837 BOOST_ASSERT(v.owner == g.processor());
2838 return out_degree(v.local, g.base());
2839 }
2840
2841
2842
2843
2844 template<PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS_CONFIG>
2845 typename PBGL_DISTRIB_ADJLIST_TYPE_CONFIG(bidirectionalS)
2846 ::degree_size_type
2847 degree(typename PBGL_DISTRIB_ADJLIST_TYPE_CONFIG(bidirectionalS)
2848 ::vertex_descriptor v,
2849 const PBGL_DISTRIB_ADJLIST_TYPE_CONFIG(bidirectionalS)& g)
2850 {
2851 BOOST_ASSERT(v.owner == g.processor());
2852 return out_degree(v, g) + in_degree(v, g);
2853 }
2854
2855 template<PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS>
2856 typename PBGL_DISTRIB_ADJLIST_TYPE::edges_size_type
2857 num_edges(const PBGL_DISTRIB_ADJLIST_TYPE& g)
2858 {
2859 return num_edges(g.base());
2860 }
2861
2862 template<PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS_CONFIG>
2863 typename PBGL_DISTRIB_ADJLIST_TYPE_CONFIG(undirectedS)::edges_size_type
2864 num_edges(const PBGL_DISTRIB_ADJLIST_TYPE_CONFIG(undirectedS)& g)
2865 {
2866 return g.local_edges().size();
2867 }
2868
2869 template<PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS>
2870 std::pair<
2871 typename PBGL_DISTRIB_ADJLIST_TYPE::edge_iterator,
2872 typename PBGL_DISTRIB_ADJLIST_TYPE::edge_iterator>
2873 edges(const PBGL_DISTRIB_ADJLIST_TYPE& g)
2874 {
2875 typedef PBGL_DISTRIB_ADJLIST_TYPE impl;
2876 typedef typename impl::out_edge_generator generator;
2877
2878 return std::make_pair(make_transform_iterator(edges(g.base()).first,
2879 generator(g)),
2880 make_transform_iterator(edges(g.base()).second,
2881 generator(g)));
2882 }
2883
2884 template<PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS_CONFIG>
2885 std::pair<
2886 typename PBGL_DISTRIB_ADJLIST_TYPE_CONFIG(undirectedS)::edge_iterator,
2887 typename PBGL_DISTRIB_ADJLIST_TYPE_CONFIG(undirectedS)::edge_iterator>
2888 edges(const PBGL_DISTRIB_ADJLIST_TYPE_CONFIG(undirectedS)& g)
2889 {
2890 return std::make_pair(g.local_edges().begin(), g.local_edges().end());
2891 }
2892
2893 template<PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS>
2894 inline
2895 typename PBGL_DISTRIB_ADJLIST_TYPE::vertex_descriptor
2896 vertex(typename PBGL_DISTRIB_ADJLIST_TYPE::vertices_size_type n,
2897 const PBGL_DISTRIB_ADJLIST_TYPE& g)
2898 {
2899 typedef typename PBGL_DISTRIB_ADJLIST_TYPE::vertex_descriptor
2900 vertex_descriptor;
2901
2902 return vertex_descriptor(g.distribution()(n), g.distribution().local(n));
2903 }
2904
2905
2906
2907
2908 template<PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS_CONFIG>
2909 std::pair<
2910 typename PBGL_DISTRIB_ADJLIST_TYPE_CONFIG(directedS)::edge_descriptor,
2911 bool
2912 >
2913 edge(typename PBGL_DISTRIB_ADJLIST_TYPE_CONFIG(directedS)::vertex_descriptor u,
2914 typename PBGL_DISTRIB_ADJLIST_TYPE_CONFIG(directedS)::vertex_descriptor v,
2915 const PBGL_DISTRIB_ADJLIST_TYPE_CONFIG(directedS)& g)
2916 {
2917 typedef typename PBGL_DISTRIB_ADJLIST_TYPE_CONFIG(directedS)
2918 ::edge_descriptor edge_descriptor;
2919
2920
2921 BOOST_ASSERT(u.owner == process_id(g.process_group()));
2922
2923 typename PBGL_DISTRIB_ADJLIST_TYPE_CONFIG(directedS)
2924 ::out_edge_iterator ei, ei_end;
2925 for (boost::tie(ei, ei_end) = out_edges(u, g); ei != ei_end; ++ei) {
2926 if (target(*ei, g) == v) return std::make_pair(*ei, true);
2927 }
2928 return std::make_pair(edge_descriptor(), false);
2929 }
2930
2931 template<PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS>
2932 std::pair<
2933 typename PBGL_DISTRIB_ADJLIST_TYPE::edge_descriptor,
2934 bool
2935 >
2936 edge(typename PBGL_DISTRIB_ADJLIST_TYPE::vertex_descriptor u,
2937 typename PBGL_DISTRIB_ADJLIST_TYPE::vertex_descriptor v,
2938 const PBGL_DISTRIB_ADJLIST_TYPE& g)
2939 {
2940 typedef typename PBGL_DISTRIB_ADJLIST_TYPE
2941 ::edge_descriptor edge_descriptor;
2942
2943
2944
2945 if (u.owner == process_id(g.process_group())) {
2946 typename PBGL_DISTRIB_ADJLIST_TYPE::out_edge_iterator ei, ei_end;
2947 for (boost::tie(ei, ei_end) = out_edges(u, g); ei != ei_end; ++ei) {
2948 if (target(*ei, g) == v) return std::make_pair(*ei, true);
2949 }
2950 return std::make_pair(edge_descriptor(), false);
2951 } else if (v.owner == process_id(g.process_group())) {
2952 typename PBGL_DISTRIB_ADJLIST_TYPE::in_edge_iterator ei, ei_end;
2953 for (boost::tie(ei, ei_end) = in_edges(v, g); ei != ei_end; ++ei) {
2954 if (source(*ei, g) == u) return std::make_pair(*ei, true);
2955 }
2956 return std::make_pair(edge_descriptor(), false);
2957 } else {
2958 BOOST_ASSERT(false);
2959 abort();
2960 }
2961 }
2962
2963 #if 0
2964
2965 std::pair<out_edge_iterator, out_edge_iterator>
2966 edge_range(vertex_descriptor u, vertex_descriptor v,
2967 const adjacency_list& g);
2968 #endif
2969
2970
2971
2972
2973 template<PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS>
2974 std::pair<typename PBGL_DISTRIB_ADJLIST_TYPE::adjacency_iterator,
2975 typename PBGL_DISTRIB_ADJLIST_TYPE::adjacency_iterator>
2976 adjacent_vertices(typename PBGL_DISTRIB_ADJLIST_TYPE::vertex_descriptor v,
2977 const PBGL_DISTRIB_ADJLIST_TYPE& g)
2978 {
2979 typedef typename PBGL_DISTRIB_ADJLIST_TYPE::adjacency_iterator iter;
2980 return std::make_pair(iter(out_edges(v, g).first, &g),
2981 iter(out_edges(v, g).second, &g));
2982 }
2983
2984
2985
2986
2987
2988
2989
2990
2991 template<PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS>
2992 typename PBGL_DISTRIB_ADJLIST_TYPE::lazy_add_edge
2993 add_edge(typename PBGL_DISTRIB_ADJLIST_TYPE::vertex_descriptor u,
2994 typename PBGL_DISTRIB_ADJLIST_TYPE::vertex_descriptor v,
2995 PBGL_DISTRIB_ADJLIST_TYPE& g)
2996 {
2997 typedef typename PBGL_DISTRIB_ADJLIST_TYPE::lazy_add_edge lazy_add_edge;
2998
2999 return lazy_add_edge(g, u, v);
3000 }
3001
3002 template<PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS>
3003 typename PBGL_DISTRIB_ADJLIST_TYPE
3004 ::lazy_add_edge_with_property
3005 add_edge(typename PBGL_DISTRIB_ADJLIST_TYPE::vertex_descriptor u,
3006 typename PBGL_DISTRIB_ADJLIST_TYPE::vertex_descriptor v,
3007 typename PBGL_DISTRIB_ADJLIST_TYPE::edge_property_type const& p,
3008 PBGL_DISTRIB_ADJLIST_TYPE& g)
3009 {
3010 typedef typename PBGL_DISTRIB_ADJLIST_TYPE
3011 ::lazy_add_edge_with_property lazy_add_edge_with_property;
3012 return lazy_add_edge_with_property(g, u, v, p);
3013 }
3014
3015
3016
3017
3018
3019
3020 template<PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS>
3021 void
3022 remove_edge(typename PBGL_DISTRIB_ADJLIST_TYPE::edge_descriptor e,
3023 PBGL_DISTRIB_ADJLIST_TYPE& g)
3024 {
3025 BOOST_ASSERT(source(e, g).owner == g.processor()
3026 || target(e, g).owner == g.processor());
3027
3028 if (target(e, g).owner == g.processor())
3029 detail::parallel::remove_in_edge(e, g, DirectedS());
3030 if (source(e, g).owner == g.processor())
3031 remove_edge(e.local, g.base());
3032
3033 g.remove_local_edge_from_list(source(e, g), target(e, g), DirectedS());
3034
3035 if (source(e, g).owner != g.processor()
3036 || (target(e, g).owner != g.processor()
3037 && !(is_same<DirectedS, directedS>::value))) {
3038 g.send_remove_edge_request(e);
3039 }
3040 }
3041
3042 template<PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS>
3043 void
3044 remove_edge(typename PBGL_DISTRIB_ADJLIST_TYPE::vertex_descriptor u,
3045 typename PBGL_DISTRIB_ADJLIST_TYPE::vertex_descriptor v,
3046 PBGL_DISTRIB_ADJLIST_TYPE& g)
3047 {
3048 typedef typename PBGL_DISTRIB_ADJLIST_TYPE
3049 ::edge_descriptor edge_descriptor;
3050 std::pair<edge_descriptor, bool> the_edge = edge(u, v, g);
3051 if (the_edge.second) remove_edge(the_edge.first, g);
3052 }
3053
3054 template<PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS>
3055 inline void
3056 remove_edge(typename PBGL_DISTRIB_ADJLIST_TYPE::out_edge_iterator ei,
3057 PBGL_DISTRIB_ADJLIST_TYPE& g)
3058 {
3059 remove_edge(*ei, g);
3060 }
3061
3062 template<PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS_CONFIG>
3063 inline void
3064 remove_edge(typename PBGL_DISTRIB_ADJLIST_TYPE_CONFIG(directedS)
3065 ::out_edge_iterator ei,
3066 PBGL_DISTRIB_ADJLIST_TYPE_CONFIG(directedS)& g)
3067 {
3068 BOOST_ASSERT(source(*ei, g).owner == g.processor());
3069 remove_edge(ei->local, g.base());
3070 }
3071
3072
3073
3074
3075
3076
3077 namespace parallel { namespace detail {
3078
3079
3080
3081
3082
3083
3084
3085 template<typename Graph, typename Predicate>
3086 struct remove_out_edge_predicate
3087 {
3088 typedef typename graph_traits<Graph>::edge_descriptor edge_descriptor;
3089 typedef typename Graph::local_edge_descriptor argument_type;
3090 typedef typename Graph::directed_selector directed_selector;
3091 typedef bool result_type;
3092
3093 remove_out_edge_predicate(Graph& g, Predicate& predicate)
3094 : g(g), predicate(predicate) { }
3095
3096 bool operator()(const argument_type& le)
3097 {
3098 typedef typename edge_descriptor::template out_generator<Graph>
3099 generator;
3100
3101 edge_descriptor e = generator(g)(le);
3102
3103 if (predicate(e)) {
3104 if (source(e, g).owner != target(e, g).owner
3105 && !(is_same<directed_selector, directedS>::value))
3106 g.send_remove_edge_request(e);
3107 else
3108 ::boost::detail::parallel::remove_in_edge(e, g,
3109 directed_selector());
3110
3111 g.remove_local_edge_from_list(source(e, g), target(e, g),
3112 directed_selector());
3113 return true;
3114 } else return false;
3115 }
3116
3117 private:
3118 Graph& g;
3119 Predicate predicate;
3120 };
3121 } }
3122
3123 template<PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS, typename Predicate>
3124 inline void
3125 remove_out_edge_if
3126 (typename PBGL_DISTRIB_ADJLIST_TYPE::vertex_descriptor u,
3127 Predicate predicate,
3128 PBGL_DISTRIB_ADJLIST_TYPE& g)
3129 {
3130 typedef PBGL_DISTRIB_ADJLIST_TYPE Graph;
3131 typedef parallel::detail::remove_out_edge_predicate<Graph, Predicate>
3132 Pred;
3133
3134 BOOST_ASSERT(u.owner == g.processor());
3135 remove_out_edge_if(u.local, Pred(g, predicate), g.base());
3136 }
3137
3138
3139
3140
3141
3142
3143 namespace parallel { namespace detail {
3144
3145
3146
3147
3148
3149
3150
3151 template<typename Graph, typename Predicate>
3152 struct remove_in_edge_predicate
3153 {
3154 typedef typename graph_traits<Graph>::edge_descriptor edge_descriptor;
3155 typedef bool result_type;
3156
3157 remove_in_edge_predicate(Graph& g, const Predicate& predicate)
3158 : g(g), predicate(predicate) { }
3159
3160 template<typename StoredEdge>
3161 bool operator()(const StoredEdge& le)
3162 {
3163 typedef typename edge_descriptor::template in_generator<Graph>
3164 generator;
3165
3166 edge_descriptor e = generator(g)(le);
3167
3168 if (predicate(e)) {
3169 if (source(e, g).owner != target(e, g).owner)
3170 g.send_remove_edge_request(e);
3171 else
3172 remove_edge(source(e, g).local, target(e, g).local, g.base());
3173 return true;
3174 } else return false;
3175 }
3176
3177 private:
3178 Graph& g;
3179 Predicate predicate;
3180 };
3181 } }
3182
3183 template<PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS_CONFIG, typename Predicate>
3184 inline void
3185 remove_in_edge_if
3186 (typename PBGL_DISTRIB_ADJLIST_TYPE_CONFIG(bidirectionalS)
3187 ::vertex_descriptor u,
3188 Predicate predicate,
3189 PBGL_DISTRIB_ADJLIST_TYPE_CONFIG(bidirectionalS)& g)
3190 {
3191 typedef PBGL_DISTRIB_ADJLIST_TYPE_CONFIG(bidirectionalS) Graph;
3192 typedef parallel::detail::remove_in_edge_predicate<Graph, Predicate>
3193 Pred;
3194
3195 BOOST_ASSERT(u.owner == g.processor());
3196 graph_detail::erase_if(get(vertex_in_edges, g.base())[u.local],
3197 Pred(g, predicate));
3198 }
3199
3200 template<PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS_CONFIG, typename Predicate>
3201 inline void
3202 remove_in_edge_if
3203 (typename PBGL_DISTRIB_ADJLIST_TYPE_CONFIG(undirectedS)
3204 ::vertex_descriptor u,
3205 Predicate predicate,
3206 PBGL_DISTRIB_ADJLIST_TYPE_CONFIG(undirectedS)& g)
3207 {
3208 remove_out_edge_if(u, predicate, g);
3209 }
3210
3211
3212
3213
3214
3215
3216 namespace parallel { namespace detail {
3217
3218
3219
3220
3221
3222 template<typename Graph, typename Predicate>
3223 struct remove_directed_edge_predicate
3224 {
3225 typedef typename Graph::local_edge_descriptor argument_type;
3226 typedef typename graph_traits<Graph>::edge_descriptor edge_descriptor;
3227 typedef bool result_type;
3228
3229 remove_directed_edge_predicate(Graph& g, const Predicate& predicate)
3230 : g(g), predicate(predicate) { }
3231
3232 bool operator()(const argument_type& le)
3233 {
3234 typedef typename edge_descriptor::template out_generator<Graph>
3235 generator;
3236
3237 edge_descriptor e = generator(g)(le);
3238 return predicate(e);
3239 }
3240
3241 private:
3242 Graph& g;
3243 Predicate predicate;
3244 };
3245 } }
3246
3247 template<PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS_CONFIG, typename Predicate>
3248 inline void
3249 remove_edge_if(Predicate predicate,
3250 PBGL_DISTRIB_ADJLIST_TYPE_CONFIG(directedS)& g)
3251 {
3252 typedef PBGL_DISTRIB_ADJLIST_TYPE_CONFIG(directedS) Graph;
3253 typedef parallel::detail::remove_directed_edge_predicate<Graph,
3254 Predicate> Pred;
3255 remove_edge_if(Pred(g, predicate), g.base());
3256 }
3257
3258 template<PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS_CONFIG, typename Predicate>
3259 inline void
3260 remove_edge_if(Predicate predicate,
3261 PBGL_DISTRIB_ADJLIST_TYPE_CONFIG(bidirectionalS)& g)
3262 {
3263 typedef PBGL_DISTRIB_ADJLIST_TYPE_CONFIG(bidirectionalS) Graph;
3264 typedef parallel::detail::remove_out_edge_predicate<Graph,
3265 Predicate> Pred;
3266 remove_edge_if(Pred(g, predicate), g.base());
3267 }
3268
3269 namespace parallel { namespace detail {
3270
3271
3272
3273
3274
3275
3276
3277 template<typename Graph, typename Predicate>
3278 struct remove_undirected_edge_predicate
3279 {
3280 typedef typename graph_traits<Graph>::edge_descriptor argument_type;
3281 typedef bool result_type;
3282
3283 remove_undirected_edge_predicate(Graph& g, Predicate& predicate)
3284 : g(g), predicate(predicate) { }
3285
3286 bool operator()(const argument_type& e)
3287 {
3288 if (predicate(e)) {
3289 if (source(e, g).owner != target(e, g).owner)
3290 g.send_remove_edge_request(e);
3291 if (target(e, g).owner == g.processor())
3292 ::boost::detail::parallel::remove_in_edge(e, g, undirectedS());
3293 if (source(e, g).owner == g.processor())
3294 remove_edge(e.local, g.base());
3295 return true;
3296 } else return false;
3297 }
3298
3299 private:
3300 Graph& g;
3301 Predicate predicate;
3302 };
3303 } }
3304
3305 template<PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS_CONFIG, typename Predicate>
3306 inline void
3307 remove_edge_if(Predicate predicate,
3308 PBGL_DISTRIB_ADJLIST_TYPE_CONFIG(undirectedS)& g)
3309 {
3310 typedef PBGL_DISTRIB_ADJLIST_TYPE_CONFIG(undirectedS) Graph;
3311 typedef parallel::detail::remove_undirected_edge_predicate<Graph,
3312 Predicate> Pred;
3313 graph_detail::erase_if(g.local_edges(), Pred(g, predicate));
3314 }
3315
3316
3317
3318
3319
3320
3321 namespace parallel { namespace detail {
3322 struct always_true
3323 {
3324 typedef bool result_type;
3325
3326 template<typename T> bool operator()(const T&) const { return true; }
3327 };
3328 } }
3329
3330 template<PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS_CONFIG>
3331 void
3332 clear_vertex
3333 (typename PBGL_DISTRIB_ADJLIST_TYPE_CONFIG(bidirectionalS)
3334 ::vertex_descriptor u,
3335 PBGL_DISTRIB_ADJLIST_TYPE_CONFIG(bidirectionalS)& g)
3336 {
3337 clear_out_edges(u, g);
3338 clear_in_edges(u, g);
3339 }
3340
3341 template<PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS_CONFIG>
3342 void
3343 clear_vertex
3344 (typename PBGL_DISTRIB_ADJLIST_TYPE_CONFIG(undirectedS)
3345 ::vertex_descriptor u,
3346 PBGL_DISTRIB_ADJLIST_TYPE_CONFIG(undirectedS)& g)
3347 {
3348 remove_out_edge_if(u, parallel::detail::always_true(), g);
3349 }
3350
3351
3352
3353
3354
3355
3356 template<PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS_CONFIG>
3357 void
3358 clear_out_edges
3359 (typename PBGL_DISTRIB_ADJLIST_TYPE_CONFIG(directedS)::vertex_descriptor u,
3360 PBGL_DISTRIB_ADJLIST_TYPE_CONFIG(directedS)& g)
3361 {
3362 BOOST_ASSERT(u.owner == g.processor());
3363 clear_out_edges(u.local, g.base());
3364 }
3365
3366 template<PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS_CONFIG>
3367 void
3368 clear_out_edges
3369 (typename PBGL_DISTRIB_ADJLIST_TYPE_CONFIG(bidirectionalS)
3370 ::vertex_descriptor u,
3371 PBGL_DISTRIB_ADJLIST_TYPE_CONFIG(bidirectionalS)& g)
3372 {
3373 remove_out_edge_if(u, parallel::detail::always_true(), g);
3374 }
3375
3376
3377
3378
3379
3380
3381 template<PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS_CONFIG>
3382 void
3383 clear_in_edges
3384 (typename PBGL_DISTRIB_ADJLIST_TYPE_CONFIG(bidirectionalS)
3385 ::vertex_descriptor u,
3386 PBGL_DISTRIB_ADJLIST_TYPE_CONFIG(bidirectionalS)& g)
3387 {
3388 remove_in_edge_if(u, parallel::detail::always_true(), g);
3389 }
3390
3391
3392
3393
3394
3395
3396 template<PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS>
3397 typename PBGL_DISTRIB_ADJLIST_TYPE::vertex_descriptor
3398 add_vertex(PBGL_DISTRIB_ADJLIST_TYPE& g)
3399 {
3400 typedef PBGL_DISTRIB_ADJLIST_TYPE graph_type;
3401 typename graph_type::vertex_property_type p;
3402 return add_vertex(p, g);
3403 }
3404
3405 template<PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS>
3406 typename PBGL_DISTRIB_ADJLIST_TYPE::lazy_add_vertex_with_property
3407 add_vertex(typename PBGL_DISTRIB_ADJLIST_TYPE::vertex_property_type const& p,
3408 PBGL_DISTRIB_ADJLIST_TYPE& g)
3409 {
3410 typedef typename PBGL_DISTRIB_ADJLIST_TYPE
3411 ::lazy_add_vertex_with_property lazy_add_vertex;
3412 return lazy_add_vertex(g, p);
3413 }
3414
3415
3416
3417
3418
3419
3420 template<PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS>
3421 void
3422 remove_vertex(typename PBGL_DISTRIB_ADJLIST_TYPE::vertex_descriptor u,
3423 PBGL_DISTRIB_ADJLIST_TYPE& g)
3424 {
3425 typedef typename PBGL_DISTRIB_ADJLIST_TYPE::graph_type graph_type;
3426 typedef typename graph_type::named_graph_mixin named_graph_mixin;
3427 BOOST_ASSERT(u.owner == g.processor());
3428 static_cast<named_graph_mixin&>(static_cast<graph_type&>(g))
3429 .removing_vertex(u, boost::graph_detail::iterator_stability(g.base().m_vertices));
3430 g.distribution().clear();
3431 remove_vertex(u.local, g.base());
3432 }
3433
3434
3435
3436
3437 template<PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS, typename Property>
3438 struct property_map<PBGL_DISTRIB_ADJLIST_TYPE, Property>
3439 : detail::parallel::get_adj_list_pmap<Property>
3440 ::template apply<PBGL_DISTRIB_ADJLIST_TYPE>
3441 { };
3442
3443 template<PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS, typename Property>
3444 struct property_map<PBGL_DISTRIB_ADJLIST_TYPE const, Property>
3445 : boost::detail::parallel::get_adj_list_pmap<Property>
3446
3447 ::template apply<PBGL_DISTRIB_ADJLIST_TYPE const>
3448 { };
3449
3450 template<typename Property, PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS>
3451 typename property_map<PBGL_DISTRIB_ADJLIST_TYPE, Property>::type
3452 get(Property p, PBGL_DISTRIB_ADJLIST_TYPE& g)
3453 {
3454 typedef PBGL_DISTRIB_ADJLIST_TYPE Graph;
3455 typedef typename property_map<Graph, Property>::type result_type;
3456 typedef typename property_traits<result_type>::value_type value_type;
3457 typedef typename property_reduce<Property>::template apply<value_type>
3458 reduce;
3459
3460 typedef typename property_traits<result_type>::key_type descriptor;
3461 typedef typename graph_traits<Graph>::vertex_descriptor vertex_descriptor;
3462 typedef typename mpl::if_<is_same<descriptor, vertex_descriptor>,
3463 vertex_global_t, edge_global_t>::type
3464 global_map_t;
3465
3466 return result_type(g.process_group(), get(global_map_t(), g),
3467 get(p, g.base()), reduce());
3468 }
3469
3470 template<typename Property, PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS>
3471 typename property_map<PBGL_DISTRIB_ADJLIST_TYPE, Property>::const_type
3472 get(Property p, const PBGL_DISTRIB_ADJLIST_TYPE& g)
3473 {
3474 typedef PBGL_DISTRIB_ADJLIST_TYPE Graph;
3475 typedef typename property_map<Graph, Property>::const_type result_type;
3476 typedef typename property_traits<result_type>::value_type value_type;
3477 typedef typename property_reduce<Property>::template apply<value_type>
3478 reduce;
3479
3480 typedef typename property_traits<result_type>::key_type descriptor;
3481 typedef typename graph_traits<Graph>::vertex_descriptor vertex_descriptor;
3482 typedef typename mpl::if_<is_same<descriptor, vertex_descriptor>,
3483 vertex_global_t, edge_global_t>::type
3484 global_map_t;
3485
3486 return result_type(g.process_group(), get(global_map_t(), g),
3487 get(p, g.base()), reduce());
3488 }
3489
3490 template<PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS>
3491 typename property_map<PBGL_DISTRIB_ADJLIST_TYPE, vertex_local_index_t>::type
3492 get(vertex_local_index_t, PBGL_DISTRIB_ADJLIST_TYPE& g)
3493 {
3494 return get(vertex_local_index, g.base());
3495 }
3496
3497 template<PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS>
3498 typename property_map<PBGL_DISTRIB_ADJLIST_TYPE,
3499 vertex_local_index_t>::const_type
3500 get(vertex_local_index_t, const PBGL_DISTRIB_ADJLIST_TYPE& g)
3501 {
3502 return get(vertex_local_index, g.base());
3503 }
3504
3505 template<PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS>
3506 typename property_map<PBGL_DISTRIB_ADJLIST_TYPE, vertex_global_t>::const_type
3507 get(vertex_global_t, const PBGL_DISTRIB_ADJLIST_TYPE& g)
3508 {
3509 typedef typename property_map<
3510 PBGL_DISTRIB_ADJLIST_TYPE,
3511 vertex_global_t>::const_type result_type;
3512 return result_type();
3513 }
3514
3515 template<PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS>
3516 typename property_map<PBGL_DISTRIB_ADJLIST_TYPE, vertex_global_t>::const_type
3517 get(vertex_global_t, PBGL_DISTRIB_ADJLIST_TYPE& g)
3518 {
3519 typedef typename property_map<
3520 PBGL_DISTRIB_ADJLIST_TYPE,
3521 vertex_global_t>::const_type result_type;
3522 return result_type();
3523 }
3524
3525
3526
3527 template<PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS>
3528 typename property_map<PBGL_DISTRIB_ADJLIST_TYPE, vertex_owner_t>::type
3529 get(vertex_owner_t, PBGL_DISTRIB_ADJLIST_TYPE& g)
3530 {
3531 typedef typename property_map<
3532 PBGL_DISTRIB_ADJLIST_TYPE,
3533 vertex_owner_t>::type result_type;
3534 return result_type();
3535 }
3536
3537
3538
3539 template<PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS>
3540 typename property_map<PBGL_DISTRIB_ADJLIST_TYPE, vertex_owner_t>::const_type
3541 get(vertex_owner_t, const PBGL_DISTRIB_ADJLIST_TYPE& g)
3542 {
3543 typedef typename property_map<
3544 PBGL_DISTRIB_ADJLIST_TYPE,
3545 vertex_owner_t>::const_type result_type;
3546 return result_type();
3547 }
3548
3549
3550 template<PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS>
3551 inline processor_id_type
3552 get(vertex_owner_t, PBGL_DISTRIB_ADJLIST_TYPE&,
3553 typename PBGL_DISTRIB_ADJLIST_TYPE::vertex_descriptor v)
3554 {
3555 return v.owner;
3556 }
3557
3558
3559 template<PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS>
3560 inline processor_id_type
3561 get(vertex_owner_t, const PBGL_DISTRIB_ADJLIST_TYPE&,
3562 typename PBGL_DISTRIB_ADJLIST_TYPE::vertex_descriptor v)
3563 {
3564 return v.owner;
3565 }
3566
3567
3568
3569 template<PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS>
3570 typename property_map<PBGL_DISTRIB_ADJLIST_TYPE, vertex_local_t>::type
3571 get(vertex_local_t, PBGL_DISTRIB_ADJLIST_TYPE& g)
3572 {
3573 typedef typename property_map<
3574 PBGL_DISTRIB_ADJLIST_TYPE,
3575 vertex_local_t>::type result_type;
3576 return result_type();
3577 }
3578
3579
3580
3581 template<PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS>
3582 typename property_map<PBGL_DISTRIB_ADJLIST_TYPE, vertex_local_t>::const_type
3583 get(vertex_local_t, const PBGL_DISTRIB_ADJLIST_TYPE& g)
3584 {
3585 typedef typename property_map<
3586 PBGL_DISTRIB_ADJLIST_TYPE,
3587 vertex_local_t>::const_type result_type;
3588 return result_type();
3589 }
3590
3591
3592 template<PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS>
3593 inline typename PBGL_DISTRIB_ADJLIST_TYPE::local_vertex_descriptor
3594 get(vertex_local_t, PBGL_DISTRIB_ADJLIST_TYPE&,
3595 typename PBGL_DISTRIB_ADJLIST_TYPE::vertex_descriptor v)
3596 {
3597 return v.local;
3598 }
3599
3600
3601 template<PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS>
3602 inline typename PBGL_DISTRIB_ADJLIST_TYPE::local_vertex_descriptor
3603 get(vertex_local_t, const PBGL_DISTRIB_ADJLIST_TYPE&,
3604 typename PBGL_DISTRIB_ADJLIST_TYPE::vertex_descriptor v)
3605 {
3606 return v.local;
3607 }
3608
3609
3610 template<PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS>
3611 typename property_map<PBGL_DISTRIB_ADJLIST_TYPE, edge_global_t>::const_type
3612 get(edge_global_t, const PBGL_DISTRIB_ADJLIST_TYPE& g)
3613 {
3614 typedef typename property_map<
3615 PBGL_DISTRIB_ADJLIST_TYPE,
3616 edge_global_t>::const_type result_type;
3617 return result_type();
3618 }
3619
3620 template<PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS>
3621 typename property_map<PBGL_DISTRIB_ADJLIST_TYPE, edge_global_t>::const_type
3622 get(edge_global_t, PBGL_DISTRIB_ADJLIST_TYPE& g)
3623 {
3624 typedef typename property_map<
3625 PBGL_DISTRIB_ADJLIST_TYPE,
3626 edge_global_t>::const_type result_type;
3627 return result_type();
3628 }
3629
3630 template<PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS>
3631 typename property_map<PBGL_DISTRIB_ADJLIST_TYPE, edge_owner_t>::type
3632 get(edge_owner_t, PBGL_DISTRIB_ADJLIST_TYPE& g)
3633 {
3634 typedef typename property_map<
3635 PBGL_DISTRIB_ADJLIST_TYPE,
3636 edge_owner_t>::type result_type;
3637 return result_type();
3638 }
3639
3640 template<PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS>
3641 typename property_map<PBGL_DISTRIB_ADJLIST_TYPE, edge_owner_t>::const_type
3642 get(edge_owner_t, const PBGL_DISTRIB_ADJLIST_TYPE& g)
3643 {
3644 typedef typename property_map<
3645 PBGL_DISTRIB_ADJLIST_TYPE,
3646 edge_owner_t>::const_type result_type;
3647 return result_type();
3648 }
3649
3650 template<PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS>
3651 typename property_map<PBGL_DISTRIB_ADJLIST_TYPE, edge_local_t>::type
3652 get(edge_local_t, PBGL_DISTRIB_ADJLIST_TYPE& g)
3653 {
3654 typedef typename property_map<
3655 PBGL_DISTRIB_ADJLIST_TYPE,
3656 edge_local_t>::type result_type;
3657 return result_type();
3658 }
3659
3660 template<PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS>
3661 typename property_map<PBGL_DISTRIB_ADJLIST_TYPE, edge_local_t>::const_type
3662 get(edge_local_t, const PBGL_DISTRIB_ADJLIST_TYPE& g)
3663 {
3664 typedef typename property_map<
3665 PBGL_DISTRIB_ADJLIST_TYPE,
3666 edge_local_t>::const_type result_type;
3667 return result_type();
3668 }
3669
3670 template<typename Property, PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS,
3671 typename Key>
3672 inline
3673 typename property_traits<typename property_map<
3674 PBGL_DISTRIB_ADJLIST_TYPE, Property>::const_type
3675 >::value_type
3676 get(Property p, const PBGL_DISTRIB_ADJLIST_TYPE& g, const Key& key)
3677 {
3678 if (owner(key) == process_id(g.process_group()))
3679 return get(p, g.base(), local(key));
3680 else
3681 BOOST_ASSERT(false);
3682 }
3683
3684 template<typename Property, PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS,
3685 typename Key, typename Value>
3686 void
3687 put(Property p, PBGL_DISTRIB_ADJLIST_TYPE& g, const Key& key, const Value& v)
3688 {
3689 if (owner(key) == process_id(g.process_group()))
3690 put(p, g.base(), local(key), v);
3691 else
3692 BOOST_ASSERT(false);
3693 }
3694
3695 template<PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS>
3696 typename property_map<PBGL_DISTRIB_ADJLIST_TYPE, vertex_index_t>::type
3697 get(vertex_index_t vi, PBGL_DISTRIB_ADJLIST_TYPE& g)
3698 {
3699 typedef PBGL_DISTRIB_ADJLIST_TYPE graph_type;
3700 typedef typename property_map<graph_type, vertex_index_t>::type
3701 result_type;
3702 return result_type(g.process_group(), get(vertex_global, g),
3703 get(vi, g.base()));
3704 }
3705
3706 template<PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS>
3707 typename property_map<PBGL_DISTRIB_ADJLIST_TYPE, vertex_index_t>::const_type
3708 get(vertex_index_t vi, const PBGL_DISTRIB_ADJLIST_TYPE& g)
3709 {
3710 typedef PBGL_DISTRIB_ADJLIST_TYPE graph_type;
3711 typedef typename property_map<graph_type, vertex_index_t>::const_type
3712 result_type;
3713 return result_type(g.process_group(), get(vertex_global, g),
3714 get(vi, g.base()));
3715 }
3716
3717
3718
3719
3720 template<PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS, typename T, typename Bundle>
3721 struct property_map<PBGL_DISTRIB_ADJLIST_TYPE, T Bundle::*>
3722 : detail::parallel::get_adj_list_pmap<T Bundle::*>
3723 ::template apply<PBGL_DISTRIB_ADJLIST_TYPE>
3724 { };
3725
3726 template<PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS, typename T, typename Bundle>
3727 struct property_map<PBGL_DISTRIB_ADJLIST_TYPE const, T Bundle::*>
3728 : detail::parallel::get_adj_list_pmap<T Bundle::*>
3729 ::template apply<PBGL_DISTRIB_ADJLIST_TYPE const>
3730 { };
3731
3732 template<PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS, typename T, typename Bundle>
3733 typename property_map<PBGL_DISTRIB_ADJLIST_TYPE, T Bundle::*>::type
3734 get(T Bundle::* p, PBGL_DISTRIB_ADJLIST_TYPE& g)
3735 {
3736 typedef PBGL_DISTRIB_ADJLIST_TYPE Graph;
3737 typedef typename property_map<Graph, T Bundle::*>::type result_type;
3738 typedef typename property_traits<result_type>::value_type value_type;
3739 typedef typename property_reduce<T Bundle::*>::template apply<value_type>
3740 reduce;
3741
3742 typedef typename property_traits<result_type>::key_type descriptor;
3743 typedef typename graph_traits<Graph>::vertex_descriptor vertex_descriptor;
3744 typedef typename mpl::if_<is_same<descriptor, vertex_descriptor>,
3745 vertex_global_t, edge_global_t>::type
3746 global_map_t;
3747
3748 return result_type(g.process_group(), get(global_map_t(), g),
3749 get(p, g.base()), reduce());
3750 }
3751
3752 template<PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS, typename T, typename Bundle>
3753 typename property_map<PBGL_DISTRIB_ADJLIST_TYPE, T Bundle::*>::const_type
3754 get(T Bundle::* p, const PBGL_DISTRIB_ADJLIST_TYPE& g)
3755 {
3756 typedef PBGL_DISTRIB_ADJLIST_TYPE Graph;
3757 typedef typename property_map<Graph, T Bundle::*>::const_type result_type;
3758 typedef typename property_traits<result_type>::value_type value_type;
3759 typedef typename property_reduce<T Bundle::*>::template apply<value_type>
3760 reduce;
3761
3762 typedef typename property_traits<result_type>::key_type descriptor;
3763 typedef typename graph_traits<Graph>::vertex_descriptor vertex_descriptor;
3764 typedef typename mpl::if_<is_same<descriptor, vertex_descriptor>,
3765 vertex_global_t, edge_global_t>::type
3766 global_map_t;
3767
3768 return result_type(g.process_group(), get(global_map_t(), g),
3769 get(p, g.base()), reduce());
3770 }
3771
3772
3773
3774
3775 template<PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS>
3776 void synchronize(const PBGL_DISTRIB_ADJLIST_TYPE& g)
3777 {
3778 synchronize(g.process_group());
3779 }
3780
3781 template<PBGL_DISTRIB_ADJLIST_TEMPLATE_PARMS>
3782 ProcessGroup
3783 process_group(const PBGL_DISTRIB_ADJLIST_TYPE& g)
3784 { return g.process_group(); }
3785
3786
3787
3788
3789 namespace mpi {
3790 template<typename Directed, typename Vertex>
3791 struct is_mpi_datatype<boost::detail::edge_base<Directed, Vertex> >
3792 : is_mpi_datatype<Vertex> { };
3793
3794 template<typename Directed, typename Vertex>
3795 struct is_mpi_datatype<boost::detail::edge_desc_impl<Directed, Vertex> >
3796 : is_mpi_datatype<boost::detail::edge_base<Directed, Vertex> > { };
3797
3798 template<typename LocalDescriptor>
3799 struct is_mpi_datatype<boost::detail::parallel::global_descriptor<LocalDescriptor> >
3800 : is_mpi_datatype<LocalDescriptor> { };
3801
3802 template<typename Edge>
3803 struct is_mpi_datatype<boost::detail::parallel::edge_descriptor<Edge> >
3804 : is_mpi_datatype<Edge> { };
3805
3806 template<typename Vertex, typename LocalVertex>
3807 struct is_mpi_datatype<boost::detail::parallel::
3808 msg_add_edge_data<Vertex, LocalVertex> >
3809 : is_mpi_datatype<Vertex> { };
3810
3811 template<typename Vertex, typename LocalVertex, typename EdgeProperty>
3812 struct is_mpi_datatype<boost::detail::parallel::
3813 msg_add_edge_with_property_data<Vertex,
3814 LocalVertex,
3815 EdgeProperty> >
3816 : mpl::and_<is_mpi_datatype<Vertex>, is_mpi_datatype<EdgeProperty> > { };
3817
3818
3819 template<typename EdgeProperty, typename EdgeDescriptor>
3820 struct is_mpi_datatype<boost::detail::parallel::msg_nonlocal_edge_data<
3821 EdgeProperty,EdgeDescriptor> >
3822 : mpl::and_<
3823 is_mpi_datatype<boost::detail::parallel::maybe_store_property<
3824 EdgeProperty> >,
3825 is_mpi_datatype<EdgeDescriptor> >
3826 {};
3827
3828 template<typename EdgeDescriptor>
3829 struct is_mpi_datatype<
3830 boost::detail::parallel::msg_remove_edge_data<EdgeDescriptor> >
3831 : is_mpi_datatype<EdgeDescriptor> {};
3832 }
3833
3834
3835
3836
3837 namespace serialization {
3838 template<typename Directed, typename Vertex>
3839 struct is_bitwise_serializable<boost::detail::edge_base<Directed, Vertex> >
3840 : is_bitwise_serializable<Vertex> { };
3841
3842 template<typename Directed, typename Vertex>
3843 struct is_bitwise_serializable<boost::detail::edge_desc_impl<Directed, Vertex> >
3844 : is_bitwise_serializable<boost::detail::edge_base<Directed, Vertex> > { };
3845
3846 template<typename LocalDescriptor>
3847 struct is_bitwise_serializable<boost::detail::parallel::global_descriptor<LocalDescriptor> >
3848 : is_bitwise_serializable<LocalDescriptor> { };
3849
3850 template<typename Edge>
3851 struct is_bitwise_serializable<boost::detail::parallel::edge_descriptor<Edge> >
3852 : is_bitwise_serializable<Edge> { };
3853
3854 template<typename Vertex, typename LocalVertex>
3855 struct is_bitwise_serializable<boost::detail::parallel::
3856 msg_add_edge_data<Vertex, LocalVertex> >
3857 : is_bitwise_serializable<Vertex> { };
3858
3859 template<typename Vertex, typename LocalVertex, typename EdgeProperty>
3860 struct is_bitwise_serializable<boost::detail::parallel::
3861 msg_add_edge_with_property_data<Vertex,
3862 LocalVertex,
3863 EdgeProperty> >
3864 : mpl::and_<is_bitwise_serializable<Vertex>,
3865 is_bitwise_serializable<EdgeProperty> > { };
3866
3867 template<typename EdgeProperty, typename EdgeDescriptor>
3868 struct is_bitwise_serializable<boost::detail::parallel::msg_nonlocal_edge_data<
3869 EdgeProperty,EdgeDescriptor> >
3870 : mpl::and_<
3871 is_bitwise_serializable<
3872 boost::detail::parallel::maybe_store_property<EdgeProperty> >,
3873 is_bitwise_serializable<EdgeDescriptor> >
3874 {};
3875
3876 template<typename EdgeDescriptor>
3877 struct is_bitwise_serializable<
3878 boost::detail::parallel::msg_remove_edge_data<EdgeDescriptor> >
3879 : is_bitwise_serializable<EdgeDescriptor> {};
3880
3881 template<typename Directed, typename Vertex>
3882 struct implementation_level<boost::detail::edge_base<Directed, Vertex> >
3883 : mpl::int_<object_serializable> {};
3884
3885 template<typename Directed, typename Vertex>
3886 struct implementation_level<boost::detail::edge_desc_impl<Directed, Vertex> >
3887 : mpl::int_<object_serializable> {};
3888
3889 template<typename LocalDescriptor>
3890 struct implementation_level<boost::detail::parallel::global_descriptor<LocalDescriptor> >
3891 : mpl::int_<object_serializable> {};
3892
3893 template<typename Edge>
3894 struct implementation_level<boost::detail::parallel::edge_descriptor<Edge> >
3895 : mpl::int_<object_serializable> {};
3896
3897 template<typename Vertex, typename LocalVertex>
3898 struct implementation_level<boost::detail::parallel::
3899 msg_add_edge_data<Vertex, LocalVertex> >
3900 : mpl::int_<object_serializable> {};
3901
3902 template<typename Vertex, typename LocalVertex, typename EdgeProperty>
3903 struct implementation_level<boost::detail::parallel::
3904 msg_add_edge_with_property_data<Vertex,
3905 LocalVertex,
3906 EdgeProperty> >
3907 : mpl::int_<object_serializable> {};
3908
3909 template<typename EdgeProperty, typename EdgeDescriptor>
3910 struct implementation_level<boost::detail::parallel::msg_nonlocal_edge_data<
3911 EdgeProperty,EdgeDescriptor> >
3912 : mpl::int_<object_serializable> {};
3913
3914 template<typename EdgeDescriptor>
3915 struct implementation_level<
3916 boost::detail::parallel::msg_remove_edge_data<EdgeDescriptor> >
3917 : mpl::int_<object_serializable> {};
3918
3919 template<typename Directed, typename Vertex>
3920 struct tracking_level<boost::detail::edge_base<Directed, Vertex> >
3921 : mpl::int_<track_never> {};
3922
3923 template<typename Directed, typename Vertex>
3924 struct tracking_level<boost::detail::edge_desc_impl<Directed, Vertex> >
3925 : mpl::int_<track_never> {};
3926
3927 template<typename LocalDescriptor>
3928 struct tracking_level<boost::detail::parallel::global_descriptor<LocalDescriptor> >
3929 : mpl::int_<track_never> {};
3930
3931 template<typename Edge>
3932 struct tracking_level<boost::detail::parallel::edge_descriptor<Edge> >
3933 : mpl::int_<track_never> {};
3934
3935 template<typename Vertex, typename LocalVertex>
3936 struct tracking_level<boost::detail::parallel::
3937 msg_add_edge_data<Vertex, LocalVertex> >
3938 : mpl::int_<track_never> {};
3939
3940 template<typename Vertex, typename LocalVertex, typename EdgeProperty>
3941 struct tracking_level<boost::detail::parallel::
3942 msg_add_edge_with_property_data<Vertex,
3943 LocalVertex,
3944 EdgeProperty> >
3945 : mpl::int_<track_never> {};
3946
3947 template<typename EdgeProperty, typename EdgeDescriptor>
3948 struct tracking_level<boost::detail::parallel::msg_nonlocal_edge_data<
3949 EdgeProperty,EdgeDescriptor> >
3950 : mpl::int_<track_never> {};
3951
3952 template<typename EdgeDescriptor>
3953 struct tracking_level<
3954 boost::detail::parallel::msg_remove_edge_data<EdgeDescriptor> >
3955 : mpl::int_<track_never> {};
3956 }
3957
3958
3959 template<typename LocalDescriptor>
3960 struct hash<detail::parallel::global_descriptor<LocalDescriptor> >
3961 {
3962 typedef detail::parallel::global_descriptor<LocalDescriptor> argument_type;
3963 std::size_t operator()(argument_type const& x) const
3964 {
3965 std::size_t hash = hash_value(x.owner);
3966 hash_combine(hash, x.local);
3967 return hash;
3968 }
3969 };
3970
3971
3972 template<typename Edge>
3973 struct hash<detail::parallel::edge_descriptor<Edge> >
3974 {
3975 typedef detail::parallel::edge_descriptor<Edge> argument_type;
3976
3977 std::size_t operator()(argument_type const& x) const
3978 {
3979 std::size_t hash = hash_value(x.owner());
3980 hash_combine(hash, x.local);
3981 return hash;
3982 }
3983 };
3984
3985 }
3986
3987 #include <boost/graph/distributed/adjlist/handlers.hpp>
3988 #include <boost/graph/distributed/adjlist/initialize.hpp>
3989 #include <boost/graph/distributed/adjlist/redistribute.hpp>
3990 #include <boost/graph/distributed/adjlist/serialization.hpp>
3991
3992 #endif