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