File indexing completed on 2025-01-18 09:37:18
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef BOOST_GRAPH_DISTRIBUTED_NAMED_GRAPH_HPP
0011 #define BOOST_GRAPH_DISTRIBUTED_NAMED_GRAPH_HPP
0012
0013 #ifndef BOOST_GRAPH_USE_MPI
0014 #error "Parallel BGL files should not be included unless <boost/graph/use_mpi.hpp> has been included"
0015 #endif
0016
0017 #include <boost/assert.hpp>
0018 #include <boost/core/uncaught_exceptions.hpp>
0019 #include <boost/graph/named_graph.hpp>
0020 #include <boost/functional/hash.hpp>
0021 #include <boost/variant.hpp>
0022 #include <boost/graph/parallel/simple_trigger.hpp>
0023 #include <boost/graph/parallel/process_group.hpp>
0024 #include <boost/graph/parallel/detail/property_holders.hpp>
0025
0026 namespace boost { namespace graph { namespace distributed {
0027
0028 using boost::parallel::trigger_receive_context;
0029 using boost::detail::parallel::pair_with_property;
0030
0031
0032
0033
0034
0035 template<typename T>
0036 struct hashed_distribution
0037 {
0038 template<typename ProcessGroup>
0039 hashed_distribution(const ProcessGroup& pg, std::size_t = 0)
0040 : n(num_processes(pg)) { }
0041
0042 int operator()(const T& value) const
0043 {
0044 return hasher(value) % n;
0045 }
0046
0047 std::size_t n;
0048 hash<T> hasher;
0049 };
0050
0051
0052 template <typename InDistribution, typename VertexProperty, typename VertexSize,
0053 typename ProcessGroup,
0054 typename ExtractName
0055 = typename internal_vertex_name<VertexProperty>::type>
0056 struct select_distribution
0057 {
0058 private:
0059
0060 typedef typename remove_cv<
0061 typename remove_reference<
0062 typename ExtractName::result_type>::type>::type
0063 vertex_name_type;
0064
0065 public:
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075 typedef typename mpl::if_<is_same<InDistribution, defaultS>,
0076 hashed_distribution<vertex_name_type>,
0077 InDistribution>::type
0078 type;
0079
0080
0081
0082 typedef type default_type;
0083 };
0084
0085
0086 template <typename InDistribution, typename VertexProperty, typename VertexSize,
0087 typename ProcessGroup>
0088 struct select_distribution<InDistribution, VertexProperty, VertexSize,
0089 ProcessGroup, void>
0090 {
0091
0092
0093 typedef typename mpl::if_<is_same<InDistribution, defaultS>,
0094 boost::parallel::variant_distribution<ProcessGroup,
0095 VertexSize>,
0096 InDistribution>::type type;
0097
0098
0099
0100 typedef typename mpl::if_<is_same<InDistribution, defaultS>,
0101 boost::parallel::block, type>::type
0102 default_type;
0103 };
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129 template<typename Graph, typename Vertex, typename Edge, typename Config>
0130 class named_graph
0131 {
0132 public:
0133
0134 enum message_kind {
0135
0136
0137
0138
0139 msg_add_vertex_name,
0140
0141
0142
0143
0144
0145
0146
0147 msg_add_vertex_name_with_reply,
0148
0149
0150
0151
0152
0153
0154 msg_find_vertex,
0155
0156
0157
0158
0159
0160
0161
0162
0163 msg_add_edge_name_name,
0164 msg_add_edge_vertex_name,
0165 msg_add_edge_name_vertex,
0166
0167
0168
0169
0170
0171
0172 msg_add_edge_name_name_with_reply,
0173 msg_add_edge_vertex_name_with_reply,
0174 msg_add_edge_name_vertex_with_reply,
0175
0176
0177
0178
0179
0180
0181
0182
0183
0184 msg_add_edge_name_name_with_property,
0185 msg_add_edge_vertex_name_with_property,
0186 msg_add_edge_name_vertex_with_property,
0187
0188
0189
0190
0191
0192
0193 msg_add_edge_name_name_with_reply_and_property,
0194 msg_add_edge_vertex_name_with_reply_and_property,
0195 msg_add_edge_name_vertex_with_reply_and_property
0196 };
0197
0198
0199 typedef Vertex vertex_descriptor;
0200
0201
0202 typedef Edge edge_descriptor;
0203
0204
0205 typedef typename Config::vertex_property_type vertex_property_type;
0206
0207
0208 typedef typename Config::edge_property_type edge_property_type;
0209
0210
0211 typedef typename internal_vertex_name<vertex_property_type>::type
0212 extract_name_type;
0213
0214
0215 typedef typename remove_cv<
0216 typename remove_reference<
0217 typename extract_name_type::result_type>::type>::type
0218 vertex_name_type;
0219
0220
0221 typedef typename Config::distribution_type distribution_type;
0222 typedef typename Config::base_distribution_type base_distribution_type;
0223
0224
0225 typedef typename Config::process_group_type process_group_type;
0226
0227
0228 typedef typename process_group_type::process_id_type process_id_type;
0229
0230
0231
0232 typedef named_graph named_graph_type;
0233
0234
0235 struct lazy_add_vertex;
0236 friend struct lazy_add_vertex;
0237
0238
0239 struct lazy_add_edge;
0240 friend struct lazy_add_edge;
0241
0242
0243 struct lazy_add_edge_with_property;
0244 friend struct lazy_add_edge_with_property;
0245
0246 explicit named_graph(const process_group_type& pg);
0247
0248 named_graph(const process_group_type& pg, const base_distribution_type& distribution);
0249
0250
0251 void setup_triggers();
0252
0253
0254 Graph& derived() { return static_cast<Graph&>(*this); }
0255 const Graph& derived() const { return static_cast<const Graph&>(*this); }
0256
0257
0258 process_group_type& process_group() { return process_group_; }
0259 const process_group_type& process_group() const { return process_group_; }
0260
0261
0262 distribution_type& named_distribution() { return distribution_; }
0263 const distribution_type& named_distribution() const { return distribution_; }
0264
0265
0266
0267 void added_vertex(Vertex) { }
0268
0269
0270
0271 template <typename VertexIterStability>
0272 void removing_vertex(Vertex, VertexIterStability) { }
0273
0274
0275 void clearing_graph() { }
0276
0277
0278
0279
0280 process_id_type owner_by_property(const vertex_property_type&);
0281
0282 protected:
0283 void
0284 handle_add_vertex_name(int source, int tag, const vertex_name_type& msg,
0285 trigger_receive_context);
0286
0287 vertex_descriptor
0288 handle_add_vertex_name_with_reply(int source, int tag,
0289 const vertex_name_type& msg,
0290 trigger_receive_context);
0291
0292 boost::parallel::detail::untracked_pair<vertex_descriptor, bool>
0293 handle_find_vertex(int source, int tag, const vertex_name_type& msg,
0294 trigger_receive_context);
0295
0296 template<typename U, typename V>
0297 void handle_add_edge(int source, int tag, const boost::parallel::detail::untracked_pair<U, V>& msg,
0298 trigger_receive_context);
0299
0300 template<typename U, typename V>
0301 boost::parallel::detail::untracked_pair<edge_descriptor, bool>
0302 handle_add_edge_with_reply(int source, int tag, const boost::parallel::detail::untracked_pair<U, V>& msg,
0303 trigger_receive_context);
0304
0305 template<typename U, typename V>
0306 void
0307 handle_add_edge_with_property
0308 (int source, int tag,
0309 const pair_with_property<U, V, edge_property_type>& msg,
0310 trigger_receive_context);
0311
0312 template<typename U, typename V>
0313 boost::parallel::detail::untracked_pair<edge_descriptor, bool>
0314 handle_add_edge_with_reply_and_property
0315 (int source, int tag,
0316 const pair_with_property<U, V, edge_property_type>& msg,
0317 trigger_receive_context);
0318
0319
0320 process_group_type process_group_;
0321
0322
0323 distribution_type distribution_;
0324 };
0325
0326
0327 #define BGL_NAMED_GRAPH_PARAMS \
0328 typename Graph, typename Vertex, typename Edge, typename Config
0329
0330 #define BGL_NAMED_GRAPH \
0331 named_graph<Graph, Vertex, Edge, Config>
0332
0333
0334
0335
0336
0337
0338 template<BGL_NAMED_GRAPH_PARAMS>
0339 struct BGL_NAMED_GRAPH::lazy_add_vertex
0340 {
0341
0342 lazy_add_vertex(named_graph& self, const vertex_name_type& name)
0343 : self(self), name(name), committed(false) { }
0344
0345
0346
0347 lazy_add_vertex(const lazy_add_vertex& other)
0348 : self(other.self), name(other.name), committed(other.committed)
0349 {
0350 other.committed = true;
0351 }
0352
0353
0354 ~lazy_add_vertex();
0355
0356
0357
0358
0359 operator vertex_descriptor() const { return commit(); }
0360
0361
0362
0363
0364 vertex_descriptor commit() const;
0365
0366 protected:
0367 named_graph& self;
0368 vertex_name_type name;
0369 mutable bool committed;
0370 };
0371
0372 template<BGL_NAMED_GRAPH_PARAMS>
0373 BGL_NAMED_GRAPH::lazy_add_vertex::~lazy_add_vertex()
0374 {
0375 typedef typename BGL_NAMED_GRAPH::process_id_type process_id_type;
0376
0377
0378
0379
0380 if (committed || boost::core::uncaught_exceptions() > 0)
0381 return;
0382
0383 committed = true;
0384
0385 process_id_type owner = self.named_distribution()(name);
0386 if (owner == process_id(self.process_group()))
0387
0388 add_vertex(self.derived().base().vertex_constructor(name), self.derived());
0389 else
0390
0391 send(self.process_group(), owner, msg_add_vertex_name, name);
0392 }
0393
0394 template<BGL_NAMED_GRAPH_PARAMS>
0395 typename BGL_NAMED_GRAPH::vertex_descriptor
0396 BGL_NAMED_GRAPH::lazy_add_vertex::commit() const
0397 {
0398 typedef typename BGL_NAMED_GRAPH::process_id_type process_id_type;
0399 BOOST_ASSERT (!committed);
0400 committed = true;
0401
0402 process_id_type owner = self.named_distribution()(name);
0403 if (owner == process_id(self.process_group()))
0404
0405 return add_vertex(self.derived().base().vertex_constructor(name),
0406 self.derived());
0407 else {
0408
0409 vertex_descriptor result;
0410 send_oob_with_reply(self.process_group(), owner,
0411 msg_add_vertex_name_with_reply, name, result);
0412 return result;
0413 }
0414 }
0415
0416
0417
0418
0419
0420
0421
0422 template<BGL_NAMED_GRAPH_PARAMS>
0423 struct BGL_NAMED_GRAPH::lazy_add_edge
0424 {
0425
0426 typedef typename graph_traits<Graph>::edge_descriptor edge_descriptor;
0427
0428
0429 lazy_add_edge(BGL_NAMED_GRAPH& self,
0430 const vertex_name_type& u_name,
0431 const vertex_name_type& v_name)
0432 : self(self), u(u_name), v(v_name), committed(false) { }
0433
0434
0435 lazy_add_edge(BGL_NAMED_GRAPH& self,
0436 vertex_descriptor u,
0437 const vertex_name_type& v_name)
0438 : self(self), u(u), v(v_name), committed(false) { }
0439
0440
0441 lazy_add_edge(BGL_NAMED_GRAPH& self,
0442 const vertex_name_type& u_name,
0443 vertex_descriptor v)
0444 : self(self), u(u_name), v(v), committed(false) { }
0445
0446
0447 lazy_add_edge(BGL_NAMED_GRAPH& self,
0448 vertex_descriptor u,
0449 vertex_descriptor v)
0450 : self(self), u(u), v(v), committed(false) { }
0451
0452
0453
0454 lazy_add_edge(const lazy_add_edge& other)
0455 : self(other.self), u(other.u), v(other.v), committed(other.committed)
0456 {
0457 other.committed = true;
0458 }
0459
0460
0461
0462 ~lazy_add_edge();
0463
0464
0465 operator std::pair<edge_descriptor, bool>() const { return commit(); }
0466
0467
0468
0469 std::pair<edge_descriptor, bool> commit() const;
0470
0471 protected:
0472 BGL_NAMED_GRAPH& self;
0473 mutable variant<vertex_descriptor, vertex_name_type> u;
0474 mutable variant<vertex_descriptor, vertex_name_type> v;
0475 mutable bool committed;
0476
0477 private:
0478
0479 void operator=(lazy_add_edge&);
0480 };
0481
0482 template<BGL_NAMED_GRAPH_PARAMS>
0483 BGL_NAMED_GRAPH::lazy_add_edge::~lazy_add_edge()
0484 {
0485 using boost::parallel::detail::make_untracked_pair;
0486
0487
0488
0489
0490 if (committed || boost::core::uncaught_exceptions() > 0)
0491 return;
0492
0493 committed = true;
0494
0495 if (vertex_name_type* v_name = boost::get<vertex_name_type>(&v)) {
0496
0497
0498
0499
0500
0501 if (vertex_name_type* u_name = boost::get<vertex_name_type>(&u))
0502 send(self.process_group(), self.distribution_(*v_name),
0503 BGL_NAMED_GRAPH::msg_add_edge_name_name,
0504 make_untracked_pair(*u_name, *v_name));
0505 else
0506 send(self.process_group(), self.distribution_(*v_name),
0507 BGL_NAMED_GRAPH::msg_add_edge_vertex_name,
0508 make_untracked_pair(boost::get<vertex_descriptor>(u), *v_name));
0509 } else {
0510 if (vertex_name_type* u_name = boost::get<vertex_name_type>(&u))
0511
0512
0513
0514 send(self.process_group(), self.distribution_(*u_name),
0515 BGL_NAMED_GRAPH::msg_add_edge_name_vertex,
0516 make_untracked_pair(*u_name, boost::get<vertex_descriptor>(v)));
0517 else
0518
0519
0520
0521 add_edge(boost::get<vertex_descriptor>(u),
0522 boost::get<vertex_descriptor>(v),
0523 self.derived());
0524 }
0525 }
0526
0527 template<BGL_NAMED_GRAPH_PARAMS>
0528 std::pair<typename graph_traits<Graph>::edge_descriptor, bool>
0529 BGL_NAMED_GRAPH::lazy_add_edge::commit() const
0530 {
0531 typedef typename BGL_NAMED_GRAPH::process_id_type process_id_type;
0532 using boost::parallel::detail::make_untracked_pair;
0533
0534 BOOST_ASSERT(!committed);
0535 committed = true;
0536
0537
0538
0539 boost::parallel::detail::untracked_pair<edge_descriptor, bool> result;
0540
0541
0542 process_id_type u_owner;
0543
0544 process_id_type rank = process_id(self.process_group());
0545 if (const vertex_name_type* u_name = boost::get<vertex_name_type>(&u)) {
0546
0547
0548 u_owner = self.named_distribution()(*u_name);
0549
0550
0551
0552
0553 if (const vertex_name_type* v_name = boost::get<vertex_name_type>(&v))
0554 send_oob_with_reply(self.process_group(), u_owner,
0555 BGL_NAMED_GRAPH::msg_add_edge_name_name_with_reply,
0556 make_untracked_pair(*u_name, *v_name), result);
0557 else
0558 send_oob_with_reply(self.process_group(), u_owner,
0559 BGL_NAMED_GRAPH::msg_add_edge_name_vertex_with_reply,
0560 make_untracked_pair(*u_name,
0561 boost::get<vertex_descriptor>(v)),
0562 result);
0563 } else {
0564
0565
0566 u_owner
0567 = get(vertex_owner, self.derived(),
0568 boost::get<vertex_descriptor>(u));
0569 if (u_owner == rank) {
0570
0571 if (const vertex_name_type* v_name = boost::get<vertex_name_type>(&v))
0572 v = add_vertex(*v_name, self.derived());
0573
0574
0575 return add_edge(boost::get<vertex_descriptor>(u),
0576 boost::get<vertex_descriptor>(v),
0577 self.derived());
0578 } else {
0579
0580
0581
0582 if (const vertex_name_type* v_name = boost::get<vertex_name_type>(&v))
0583 send_oob_with_reply
0584 (self.process_group(), u_owner,
0585 BGL_NAMED_GRAPH::msg_add_edge_vertex_name_with_reply,
0586 make_untracked_pair(boost::get<vertex_descriptor>(u), *v_name),
0587 result);
0588 else
0589 return add_edge(boost::get<vertex_descriptor>(u),
0590 boost::get<vertex_descriptor>(v),
0591 self.derived());
0592 }
0593 }
0594
0595
0596
0597 return result;
0598 }
0599
0600
0601
0602
0603
0604
0605
0606 template<BGL_NAMED_GRAPH_PARAMS>
0607 struct BGL_NAMED_GRAPH::lazy_add_edge_with_property
0608 {
0609
0610 typedef typename graph_traits<Graph>::edge_descriptor edge_descriptor;
0611
0612
0613 typedef typename Config::edge_property_type edge_property_type;
0614
0615
0616 lazy_add_edge_with_property(BGL_NAMED_GRAPH& self,
0617 const vertex_name_type& u_name,
0618 const vertex_name_type& v_name,
0619 const edge_property_type& property)
0620 : self(self), u(u_name), v(v_name), property(property), committed(false)
0621 {
0622 }
0623
0624
0625 lazy_add_edge_with_property(BGL_NAMED_GRAPH& self,
0626 vertex_descriptor u,
0627 const vertex_name_type& v_name,
0628 const edge_property_type& property)
0629 : self(self), u(u), v(v_name), property(property), committed(false) { }
0630
0631
0632 lazy_add_edge_with_property(BGL_NAMED_GRAPH& self,
0633 const vertex_name_type& u_name,
0634 vertex_descriptor v,
0635 const edge_property_type& property)
0636 : self(self), u(u_name), v(v), property(property), committed(false) { }
0637
0638
0639 lazy_add_edge_with_property(BGL_NAMED_GRAPH& self,
0640 vertex_descriptor u,
0641 vertex_descriptor v,
0642 const edge_property_type& property)
0643 : self(self), u(u), v(v), property(property), committed(false) { }
0644
0645
0646
0647
0648 lazy_add_edge_with_property(const lazy_add_edge_with_property& other)
0649 : self(other.self), u(other.u), v(other.v), property(other.property),
0650 committed(other.committed)
0651 {
0652 other.committed = true;
0653 }
0654
0655
0656
0657 ~lazy_add_edge_with_property();
0658
0659
0660 operator std::pair<edge_descriptor, bool>() const { return commit(); }
0661
0662
0663
0664 std::pair<edge_descriptor, bool> commit() const;
0665
0666 protected:
0667 BGL_NAMED_GRAPH& self;
0668 mutable variant<vertex_descriptor, vertex_name_type> u;
0669 mutable variant<vertex_descriptor, vertex_name_type> v;
0670 edge_property_type property;
0671 mutable bool committed;
0672
0673 private:
0674
0675 void operator=(lazy_add_edge_with_property&);
0676 };
0677
0678 template<BGL_NAMED_GRAPH_PARAMS>
0679 BGL_NAMED_GRAPH::lazy_add_edge_with_property::~lazy_add_edge_with_property()
0680 {
0681 using boost::detail::parallel::make_pair_with_property;
0682
0683
0684
0685
0686 if (committed || boost::core::uncaught_exceptions() > 0)
0687 return;
0688
0689 committed = true;
0690
0691 if (vertex_name_type* v_name = boost::get<vertex_name_type>(&v)) {
0692
0693
0694
0695
0696
0697 if (vertex_name_type* u_name = boost::get<vertex_name_type>(&u))
0698 send(self.process_group(), self.distribution_(*v_name),
0699 BGL_NAMED_GRAPH::msg_add_edge_name_name_with_property,
0700 make_pair_with_property(*u_name, *v_name, property));
0701 else
0702 send(self.process_group(), self.distribution_(*v_name),
0703 BGL_NAMED_GRAPH::msg_add_edge_vertex_name_with_property,
0704 make_pair_with_property(boost::get<vertex_descriptor>(u), *v_name,
0705 property));
0706 } else {
0707 if (vertex_name_type* u_name = boost::get<vertex_name_type>(&u))
0708
0709
0710
0711 send(self.process_group(), self.distribution_(*u_name),
0712 BGL_NAMED_GRAPH::msg_add_edge_name_vertex_with_property,
0713 make_pair_with_property(*u_name, boost::get<vertex_descriptor>(v),
0714 property));
0715 else
0716
0717
0718
0719 add_edge(boost::get<vertex_descriptor>(u),
0720 boost::get<vertex_descriptor>(v),
0721 property,
0722 self.derived());
0723 }
0724 }
0725
0726 template<BGL_NAMED_GRAPH_PARAMS>
0727 std::pair<typename graph_traits<Graph>::edge_descriptor, bool>
0728 BGL_NAMED_GRAPH::lazy_add_edge_with_property::commit() const
0729 {
0730 using boost::detail::parallel::make_pair_with_property;
0731 typedef typename BGL_NAMED_GRAPH::process_id_type process_id_type;
0732 BOOST_ASSERT(!committed);
0733 committed = true;
0734
0735
0736
0737 boost::parallel::detail::untracked_pair<edge_descriptor, bool> result;
0738
0739
0740 process_id_type u_owner;
0741
0742 process_id_type rank = process_id(self.process_group());
0743 if (const vertex_name_type* u_name = boost::get<vertex_name_type>(&u)) {
0744
0745
0746 u_owner = self.named_distribution()(*u_name);
0747
0748
0749
0750
0751 if (const vertex_name_type* v_name = boost::get<vertex_name_type>(&v))
0752 send_oob_with_reply
0753 (self.process_group(), u_owner,
0754 BGL_NAMED_GRAPH::msg_add_edge_name_name_with_reply_and_property,
0755 make_pair_with_property(*u_name, *v_name, property),
0756 result);
0757 else
0758 send_oob_with_reply
0759 (self.process_group(), u_owner,
0760 BGL_NAMED_GRAPH::msg_add_edge_name_vertex_with_reply_and_property,
0761 make_pair_with_property(*u_name,
0762 boost::get<vertex_descriptor>(v),
0763 property),
0764 result);
0765 } else {
0766
0767
0768 u_owner
0769 = get(vertex_owner, self.derived(),
0770 boost::get<vertex_descriptor>(u));
0771 if (u_owner == rank) {
0772
0773 if (const vertex_name_type* v_name = boost::get<vertex_name_type>(&v))
0774 v = add_vertex(*v_name, self.derived());
0775
0776
0777 return add_edge(boost::get<vertex_descriptor>(u),
0778 boost::get<vertex_descriptor>(v),
0779 property,
0780 self.derived());
0781 } else {
0782
0783
0784
0785 if (const vertex_name_type* v_name = boost::get<vertex_name_type>(&v))
0786 send_oob_with_reply
0787 (self.process_group(), u_owner,
0788 BGL_NAMED_GRAPH::msg_add_edge_vertex_name_with_reply_and_property,
0789 make_pair_with_property(boost::get<vertex_descriptor>(u), *v_name,
0790 property),
0791 result);
0792 else
0793 return add_edge(boost::get<vertex_descriptor>(u),
0794 boost::get<vertex_descriptor>(v),
0795 property,
0796 self.derived());
0797 }
0798 }
0799
0800
0801
0802 return result;
0803 }
0804
0805
0806 template<BGL_NAMED_GRAPH_PARAMS>
0807 BGL_NAMED_GRAPH::named_graph(const process_group_type& pg)
0808 : process_group_(pg, boost::parallel::attach_distributed_object()),
0809 distribution_(pg)
0810 {
0811 setup_triggers();
0812 }
0813
0814
0815
0816 template<BGL_NAMED_GRAPH_PARAMS>
0817 BGL_NAMED_GRAPH::named_graph(const process_group_type& pg,
0818 const base_distribution_type& distribution)
0819 : process_group_(pg, boost::parallel::attach_distributed_object()),
0820 distribution_(pg, distribution)
0821 {
0822 setup_triggers();
0823 }
0824
0825 template<BGL_NAMED_GRAPH_PARAMS>
0826 void
0827 BGL_NAMED_GRAPH::setup_triggers()
0828 {
0829 using boost::graph::parallel::simple_trigger;
0830
0831 simple_trigger(process_group_, msg_add_vertex_name, this,
0832 &named_graph::handle_add_vertex_name);
0833 simple_trigger(process_group_, msg_add_vertex_name_with_reply, this,
0834 &named_graph::handle_add_vertex_name_with_reply);
0835 simple_trigger(process_group_, msg_find_vertex, this,
0836 &named_graph::handle_find_vertex);
0837 simple_trigger(process_group_, msg_add_edge_name_name, this,
0838 &named_graph::template handle_add_edge<vertex_name_type,
0839 vertex_name_type>);
0840 simple_trigger(process_group_, msg_add_edge_name_name_with_reply, this,
0841 &named_graph::template handle_add_edge_with_reply
0842 <vertex_name_type, vertex_name_type>);
0843 simple_trigger(process_group_, msg_add_edge_name_vertex, this,
0844 &named_graph::template handle_add_edge<vertex_name_type,
0845 vertex_descriptor>);
0846 simple_trigger(process_group_, msg_add_edge_name_vertex_with_reply, this,
0847 &named_graph::template handle_add_edge_with_reply
0848 <vertex_name_type, vertex_descriptor>);
0849 simple_trigger(process_group_, msg_add_edge_vertex_name, this,
0850 &named_graph::template handle_add_edge<vertex_descriptor,
0851 vertex_name_type>);
0852 simple_trigger(process_group_, msg_add_edge_vertex_name_with_reply, this,
0853 &named_graph::template handle_add_edge_with_reply
0854 <vertex_descriptor, vertex_name_type>);
0855 simple_trigger(process_group_, msg_add_edge_name_name_with_property, this,
0856 &named_graph::
0857 template handle_add_edge_with_property<vertex_name_type,
0858 vertex_name_type>);
0859 simple_trigger(process_group_,
0860 msg_add_edge_name_name_with_reply_and_property, this,
0861 &named_graph::template handle_add_edge_with_reply_and_property
0862 <vertex_name_type, vertex_name_type>);
0863 simple_trigger(process_group_, msg_add_edge_name_vertex_with_property, this,
0864 &named_graph::
0865 template handle_add_edge_with_property<vertex_name_type,
0866 vertex_descriptor>);
0867 simple_trigger(process_group_,
0868 msg_add_edge_name_vertex_with_reply_and_property, this,
0869 &named_graph::template handle_add_edge_with_reply_and_property
0870 <vertex_name_type, vertex_descriptor>);
0871 simple_trigger(process_group_, msg_add_edge_vertex_name_with_property, this,
0872 &named_graph::
0873 template handle_add_edge_with_property<vertex_descriptor,
0874 vertex_name_type>);
0875 simple_trigger(process_group_,
0876 msg_add_edge_vertex_name_with_reply_and_property, this,
0877 &named_graph::template handle_add_edge_with_reply_and_property
0878 <vertex_descriptor, vertex_name_type>);
0879 }
0880
0881
0882 template<BGL_NAMED_GRAPH_PARAMS>
0883 optional<Vertex>
0884 find_vertex(typename BGL_NAMED_GRAPH::vertex_name_type const& name,
0885 const BGL_NAMED_GRAPH& g)
0886 {
0887 typedef typename Graph::local_vertex_descriptor local_vertex_descriptor;
0888 typedef typename graph_traits<Graph>::vertex_descriptor vertex_descriptor;
0889
0890
0891 typename BGL_NAMED_GRAPH::process_id_type owner
0892 = g.named_distribution()(name);
0893
0894 if (owner == process_id(g.process_group())) {
0895
0896 optional<local_vertex_descriptor> result
0897 = find_vertex(name, g.derived().base());
0898 if (result)
0899 return Vertex(owner, *result);
0900 else
0901 return optional<Vertex>();
0902 }
0903 else {
0904
0905 boost::parallel::detail::untracked_pair<vertex_descriptor, bool> result;
0906 send_oob_with_reply(g.process_group(), owner,
0907 BGL_NAMED_GRAPH::msg_find_vertex, name, result);
0908 if (result.second)
0909 return result.first;
0910 else
0911 return optional<Vertex>();
0912 }
0913 }
0914
0915
0916
0917 template<typename VertexProperty>
0918 struct not_is_named_graph
0919 : is_same<typename internal_vertex_name<VertexProperty>::type, void>
0920 {};
0921
0922
0923 template<typename Graph>
0924 typename Graph::named_graph_type::lazy_add_vertex
0925 add_vertex(typename Graph::vertex_name_type const& name,
0926 Graph& g,
0927 typename disable_if<
0928 not_is_named_graph<typename Graph::vertex_property_type>,
0929 void*>::type = 0)
0930 {
0931 return typename Graph::named_graph_type::lazy_add_vertex(g, name);
0932 }
0933
0934
0935 template<BGL_NAMED_GRAPH_PARAMS>
0936 typename BGL_NAMED_GRAPH::lazy_add_edge
0937 add_edge(typename BGL_NAMED_GRAPH::vertex_name_type const& u_name,
0938 typename BGL_NAMED_GRAPH::vertex_name_type const& v_name,
0939 BGL_NAMED_GRAPH& g)
0940 {
0941 typedef typename BGL_NAMED_GRAPH::lazy_add_edge lazy_add_edge;
0942 typedef typename BGL_NAMED_GRAPH::process_id_type process_id_type;
0943
0944 process_id_type rank = process_id(g.process_group());
0945 process_id_type u_owner = g.named_distribution()(u_name);
0946 process_id_type v_owner = g.named_distribution()(v_name);
0947
0948
0949
0950 if (u_owner == rank && v_owner == rank)
0951 return lazy_add_edge(g, add_vertex(u_name, g), add_vertex(v_name, g));
0952 else if (u_owner == rank && v_owner != rank)
0953 return lazy_add_edge(g, add_vertex(u_name, g), v_name);
0954 else if (u_owner != rank && v_owner == rank)
0955 return lazy_add_edge(g, u_name, add_vertex(v_name, g));
0956 else
0957 return lazy_add_edge(g, u_name, v_name);
0958 }
0959
0960 template<BGL_NAMED_GRAPH_PARAMS>
0961 typename BGL_NAMED_GRAPH::lazy_add_edge
0962 add_edge(typename BGL_NAMED_GRAPH::vertex_name_type const& u_name,
0963 typename BGL_NAMED_GRAPH::vertex_descriptor const& v,
0964 BGL_NAMED_GRAPH& g)
0965 {
0966
0967
0968 typedef typename BGL_NAMED_GRAPH::lazy_add_edge lazy_add_edge;
0969 if (g.named_distribution()(u_name) == process_id(g.process_group()))
0970 return lazy_add_edge(g, add_vertex(u_name, g), v);
0971 else
0972 return lazy_add_edge(g, u_name, v);
0973 }
0974
0975 template<BGL_NAMED_GRAPH_PARAMS>
0976 typename BGL_NAMED_GRAPH::lazy_add_edge
0977 add_edge(typename BGL_NAMED_GRAPH::vertex_descriptor const& u,
0978 typename BGL_NAMED_GRAPH::vertex_name_type const& v_name,
0979 BGL_NAMED_GRAPH& g)
0980 {
0981
0982
0983 typedef typename BGL_NAMED_GRAPH::lazy_add_edge lazy_add_edge;
0984 if (g.named_distribution()(v_name) == process_id(g.process_group()))
0985 return lazy_add_edge(g, u, add_vertex(v_name, g));
0986 else
0987 return lazy_add_edge(g, u, v_name);
0988 }
0989
0990
0991 template<BGL_NAMED_GRAPH_PARAMS>
0992 typename BGL_NAMED_GRAPH::lazy_add_edge_with_property
0993 add_edge(typename BGL_NAMED_GRAPH::vertex_name_type const& u_name,
0994 typename BGL_NAMED_GRAPH::vertex_name_type const& v_name,
0995 typename Graph::edge_property_type const& property,
0996 BGL_NAMED_GRAPH& g)
0997 {
0998 typedef typename BGL_NAMED_GRAPH::lazy_add_edge_with_property lazy_add_edge;
0999 typedef typename BGL_NAMED_GRAPH::process_id_type process_id_type;
1000
1001 process_id_type rank = process_id(g.process_group());
1002 process_id_type u_owner = g.named_distribution()(u_name);
1003 process_id_type v_owner = g.named_distribution()(v_name);
1004
1005
1006
1007 if (u_owner == rank && v_owner == rank)
1008 return lazy_add_edge(g, add_vertex(u_name, g), add_vertex(v_name, g),
1009 property);
1010 else if (u_owner == rank && v_owner != rank)
1011 return lazy_add_edge(g, add_vertex(u_name, g), v_name, property);
1012 else if (u_owner != rank && v_owner == rank)
1013 return lazy_add_edge(g, u_name, add_vertex(v_name, g), property);
1014 else
1015 return lazy_add_edge(g, u_name, v_name, property);
1016 }
1017
1018 template<BGL_NAMED_GRAPH_PARAMS>
1019 typename BGL_NAMED_GRAPH::lazy_add_edge_with_property
1020 add_edge(typename BGL_NAMED_GRAPH::vertex_name_type const& u_name,
1021 typename BGL_NAMED_GRAPH::vertex_descriptor const& v,
1022 typename Graph::edge_property_type const& property,
1023 BGL_NAMED_GRAPH& g)
1024 {
1025
1026
1027 typedef typename BGL_NAMED_GRAPH::lazy_add_edge_with_property lazy_add_edge;
1028 if (g.named_distribution()(u_name) == process_id(g.process_group()))
1029 return lazy_add_edge(g, add_vertex(u_name, g), v, property);
1030 else
1031 return lazy_add_edge(g, u_name, v, property);
1032 }
1033
1034 template<BGL_NAMED_GRAPH_PARAMS>
1035 typename BGL_NAMED_GRAPH::lazy_add_edge_with_property
1036 add_edge(typename BGL_NAMED_GRAPH::vertex_descriptor const& u,
1037 typename BGL_NAMED_GRAPH::vertex_name_type const& v_name,
1038 typename Graph::edge_property_type const& property,
1039 BGL_NAMED_GRAPH& g)
1040 {
1041
1042
1043 typedef typename BGL_NAMED_GRAPH::lazy_add_edge_with_property lazy_add_edge;
1044 if (g.named_distribution()(v_name) == process_id(g.process_group()))
1045 return lazy_add_edge(g, u, add_vertex(v_name, g), property);
1046 else
1047 return lazy_add_edge(g, u, v_name, property);
1048 }
1049
1050 template<BGL_NAMED_GRAPH_PARAMS>
1051 typename BGL_NAMED_GRAPH::process_id_type
1052 BGL_NAMED_GRAPH::owner_by_property(const vertex_property_type& property)
1053 {
1054 return distribution_(derived().base().extract_name(property));
1055 }
1056
1057
1058
1059
1060
1061
1062 template<BGL_NAMED_GRAPH_PARAMS>
1063 void
1064 BGL_NAMED_GRAPH::
1065 handle_add_vertex_name(int , int ,
1066 const vertex_name_type& msg, trigger_receive_context)
1067 {
1068 add_vertex(msg, derived());
1069 }
1070
1071 template<BGL_NAMED_GRAPH_PARAMS>
1072 typename BGL_NAMED_GRAPH::vertex_descriptor
1073 BGL_NAMED_GRAPH::
1074 handle_add_vertex_name_with_reply(int source, int ,
1075 const vertex_name_type& msg,
1076 trigger_receive_context)
1077 {
1078 return add_vertex(msg, derived());
1079 }
1080
1081 template<BGL_NAMED_GRAPH_PARAMS>
1082 boost::parallel::detail::untracked_pair<typename BGL_NAMED_GRAPH::vertex_descriptor, bool>
1083 BGL_NAMED_GRAPH::
1084 handle_find_vertex(int source, int , const vertex_name_type& msg,
1085 trigger_receive_context)
1086 {
1087 using boost::parallel::detail::make_untracked_pair;
1088
1089 optional<vertex_descriptor> v = find_vertex(msg, derived());
1090 if (v)
1091 return make_untracked_pair(*v, true);
1092 else
1093 return make_untracked_pair(graph_traits<Graph>::null_vertex(), false);
1094 }
1095
1096 template<BGL_NAMED_GRAPH_PARAMS>
1097 template<typename U, typename V>
1098 void
1099 BGL_NAMED_GRAPH::
1100 handle_add_edge(int source, int , const boost::parallel::detail::untracked_pair<U, V>& msg,
1101 trigger_receive_context)
1102 {
1103 add_edge(msg.first, msg.second, derived());
1104 }
1105
1106 template<BGL_NAMED_GRAPH_PARAMS>
1107 template<typename U, typename V>
1108 boost::parallel::detail::untracked_pair<typename BGL_NAMED_GRAPH::edge_descriptor, bool>
1109 BGL_NAMED_GRAPH::
1110 handle_add_edge_with_reply(int source, int , const boost::parallel::detail::untracked_pair<U, V>& msg,
1111 trigger_receive_context)
1112 {
1113 std::pair<typename BGL_NAMED_GRAPH::edge_descriptor, bool> p =
1114 add_edge(msg.first, msg.second, derived());
1115 return p;
1116 }
1117
1118 template<BGL_NAMED_GRAPH_PARAMS>
1119 template<typename U, typename V>
1120 void
1121 BGL_NAMED_GRAPH::
1122 handle_add_edge_with_property
1123 (int source, int tag,
1124 const pair_with_property<U, V, edge_property_type>& msg,
1125 trigger_receive_context)
1126 {
1127 add_edge(msg.first, msg.second, msg.get_property(), derived());
1128 }
1129
1130 template<BGL_NAMED_GRAPH_PARAMS>
1131 template<typename U, typename V>
1132 boost::parallel::detail::untracked_pair<typename BGL_NAMED_GRAPH::edge_descriptor, bool>
1133 BGL_NAMED_GRAPH::
1134 handle_add_edge_with_reply_and_property
1135 (int source, int tag,
1136 const pair_with_property<U, V, edge_property_type>& msg,
1137 trigger_receive_context)
1138 {
1139 std:: pair<typename BGL_NAMED_GRAPH::edge_descriptor, bool> p =
1140 add_edge(msg.first, msg.second, msg.get_property(), derived());
1141 return p;
1142 }
1143
1144 #undef BGL_NAMED_GRAPH
1145 #undef BGL_NAMED_GRAPH_PARAMS
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156 template<typename Graph, typename Vertex, typename Edge, typename Config,
1157 typename ExtractName
1158 = typename internal_vertex_name<typename Config::vertex_property_type>::type>
1159 struct maybe_named_graph
1160 : public named_graph<Graph, Vertex, Edge, Config>
1161 {
1162 private:
1163 typedef named_graph<Graph, Vertex, Edge, Config> inherited;
1164 typedef typename Config::process_group_type process_group_type;
1165
1166 public:
1167
1168 typedef typename Config::distribution_type distribution_type;
1169 typedef typename Config::base_distribution_type base_distribution_type;
1170
1171 explicit maybe_named_graph(const process_group_type& pg) : inherited(pg) { }
1172
1173 maybe_named_graph(const process_group_type& pg,
1174 const base_distribution_type& distribution)
1175 : inherited(pg, distribution) { }
1176
1177 distribution_type& distribution() { return this->distribution_; }
1178 const distribution_type& distribution() const { return this->distribution_; }
1179 };
1180
1181
1182
1183
1184
1185
1186
1187 template<typename Graph, typename Vertex, typename Edge, typename Config>
1188 struct maybe_named_graph<Graph, Vertex, Edge, Config, void>
1189 {
1190 private:
1191 typedef typename Config::process_group_type process_group_type;
1192 typedef typename Config::vertex_property_type vertex_property_type;
1193
1194 public:
1195 typedef typename process_group_type::process_id_type process_id_type;
1196
1197
1198 typedef typename Config::distribution_type distribution_type;
1199 typedef typename Config::base_distribution_type base_distribution_type;
1200
1201 explicit maybe_named_graph(const process_group_type&) { }
1202
1203 maybe_named_graph(const process_group_type& pg,
1204 const base_distribution_type& distribution)
1205 : distribution_(pg, distribution) { }
1206
1207
1208
1209 void added_vertex(Vertex) { }
1210
1211
1212
1213 template <typename VertexIterStability>
1214 void removing_vertex(Vertex, VertexIterStability) { }
1215
1216
1217 void clearing_graph() { }
1218
1219
1220
1221
1222 process_id_type owner_by_property(const vertex_property_type&)
1223 {
1224 return process_id(pg);
1225 }
1226
1227 distribution_type& distribution() { return distribution_; }
1228 const distribution_type& distribution() const { return distribution_; }
1229
1230 protected:
1231
1232 process_group_type pg;
1233
1234
1235 distribution_type distribution_;
1236 };
1237
1238 } } }
1239
1240 #endif