Rheolef  7.2
an efficient C++ finite element environment
mpi_scatter_end.h
Go to the documentation of this file.
1 #ifndef _RHEO_MPI_SCATTER_END_H
2 #define _RHEO_MPI_SCATTER_END_H
23 
24 #include "rheolef/scatter_message.h"
25 #include "rheolef/msg_left_permutation_apply.h"
26 
27 #include "rheolef/msg_util.h"
28 
29 #pragma GCC diagnostic push
30 #pragma GCC diagnostic ignored "-Weffc++"
31 #pragma GCC diagnostic ignored "-Wparentheses"
32 #pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
33 #include <boost/functional.hpp>
34 #include <boost/iterator/transform_iterator.hpp>
35 #pragma GCC diagnostic pop
36 
37 namespace rheolef {
38 
39 /*F:
40 NAME: mpi_scatter_end -- gather/scatter finalize (@PACKAGE@ @VERSION@)
41 DESCRIPTION:
42  Finishes communication
43  for distributed to sequential scatter context.
44 AUTHORS:
45  LMC-IMAG, 38041 Grenoble cedex 9, France
46  | Pierre.Saramito@imag.fr
47 DATE: 23 march 1999
48 END:
49 */
50 
51 //<mpi_scatter_end:
52 template <
53  class InputIterator,
54  class OutputIterator,
55  class Message,
56  class SetOp,
57  class Tag,
58  class Comm>
59 void
61  InputIterator x,
62  OutputIterator y,
63  Message& from,
64  Message& to,
65  SetOp op,
66  Tag tag,
67  Comm comm)
68 {
69  typedef typename Message::base_value_type data_type; // the data type to be received by mpi
70  typedef boost::transform_iterator<select2nd<size_t,mpi::request>, std::list<std::pair<size_t,mpi::request> >::iterator>
71  request_iterator;
72 
73  // -----------------------------------------------------------
74  // 1) wait on receives and unpack receives into local space
75  // -----------------------------------------------------------
76  while (from.requests.size() != 0) {
77  request_iterator iter_r_waits (from.requests.begin(), select2nd<size_t,mpi::request>()),
78  last_r_waits (from.requests.end(), select2nd<size_t,mpi::request>());
79  // waits on any receive...
80  std::pair<mpi::status,request_iterator> pair_status = mpi::wait_any (iter_r_waits, last_r_waits);
81  // check status
82  boost::optional<int> i_msg_size_opt = pair_status.first.count<data_type>();
83  check_macro (i_msg_size_opt, "receive wait failed");
84  int iproc = pair_status.first.source();
85  check_macro (iproc >= 0, "receive: source iproc = "<<iproc<<" < 0 !");
86  // get size of receive and number in data
87  size_t i_msg_size = (size_t)i_msg_size_opt.get();
88  std::list<std::pair<size_t,mpi::request> >::iterator i_pair_ptr = pair_status.second.base();
89  size_t i_receive = (*i_pair_ptr).first;
90  check_macro (i_msg_size == from.starts()[i_receive+1] - from.starts()[i_receive], "unexpected size");
91 
92  // unpack receives into our local space
93  from.store_values (y, i_receive, op);
94  from.requests.erase (i_pair_ptr);
95  }
96  // -----------------------------------------------------------
97  // 2) wait on sends
98  // -----------------------------------------------------------
99  if (to.requests.size() != 0) {
100  request_iterator iter_s_waits (to.requests.begin(), select2nd<size_t,mpi::request>()),
101  last_s_waits (to.requests.end(), select2nd<size_t,mpi::request>());
102  mpi::wait_all (iter_s_waits, last_s_waits);
103  }
104 }
105 //>mpi_scatter_end:
106 } // namespace rheolef
107 #endif // _RHEO_MPI_SCATTER_END_H
check_macro(expr1.have_homogeneous_space(Xh1), "dual(expr1,expr2); expr1 should have homogeneous space. HINT: use dual(interpolate(Xh, expr1),expr2)")
This file is part of Rheolef.
void mpi_scatter_end(InputIterator x, OutputIterator y, Message &from, Message &to, SetOp op, Tag tag, Comm comm)