Rheolef  7.2
an efficient C++ finite element environment
mpi_assembly_end.h
Go to the documentation of this file.
1 #ifndef _RHEO_MPI_ASSEMBLY_END_H
2 #define _RHEO_MPI_ASSEMBLY_END_H
23 
24 #include "rheolef/msg_util.h"
25 
26 #pragma GCC diagnostic push
27 #pragma GCC diagnostic ignored "-Weffc++"
28 #pragma GCC diagnostic ignored "-Wparentheses"
29 #pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
30 #include <boost/functional.hpp>
31 #include <boost/iterator/transform_iterator.hpp>
32 #pragma GCC diagnostic pop
33 
34 namespace rheolef {
35 
36 /*F:
37 NAME: msg_assembly_end -- array or matrix assembly (@PACKAGE@ @VERSION@)
38 DESCRIPTION:
39  Finish a dense array or sparse matrix assembly.
40 COMPLEXITY:
41  **TO DO**
42 AUTHORS:
43  LMC-IMAG, 38041 Grenoble cedex 9, France
44  | Pierre.Saramito@imag.fr
45 DATE: 23 march 1999
46 END:
47 */
48 
49 //<mpi_assembly_end:
50 template <
51  class Container,
52  class Message,
53  class Size>
54 Size
56 // input:
57  Message& receive,
58  Message& send,
59  Size receive_max_size,
60 // output:
61  Container x)
62 {
63  typedef Size size_type;
64  typedef typename Container::data_type data_type;
65  // -----------------------------------------------------------------
66  // 1) receive data and store it in container
67  // -----------------------------------------------------------------
68 
69  // note: for wait_any, build an iterator adapter that scan the pair.second in [index,request]
70  // and then get an iterator in the pair using iter.base(): retrive the corresponding index
71  // for computing the position in the receive.data buffer
72  typedef boost::transform_iterator<select2nd<size_type,mpi::request>,
73  typename std::list<std::pair<size_type,mpi::request> >::iterator>
74  request_iterator;
75 
76  while (receive.waits.size() != 0) {
77  request_iterator iter_r_waits (receive.waits.begin(), select2nd<size_type,mpi::request>()),
78  last_r_waits (receive.waits.end(), select2nd<size_type,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.template 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_type i_msg_size = (size_type)i_msg_size_opt.get();
88  typename std::list<std::pair<size_type,mpi::request> >::iterator i_pair_ptr = pair_status.second.base();
89  size_type i_receive = (*i_pair_ptr).first;
90  size_type i_start = i_receive*receive_max_size;
91  for (size_type j = i_start; j < i_start + i_msg_size; j++) {
92  x (receive.data[j]);
93  }
94  receive.waits.erase (i_pair_ptr);
95  }
96  // -----------------------------------------------------------------
97  // 2) wait on sends
98  // -----------------------------------------------------------------
99  Size send_nproc = send.waits.size();
100  std::vector<mpi::status> send_status (send_nproc);
101  if (send.waits.size() != 0) {
102  request_iterator iter_s_waits (send.waits.begin(), select2nd<size_type,mpi::request>()),
103  last_s_waits (send.waits.end(), select2nd<size_type,mpi::request>());
104  mpi::wait_all (iter_s_waits, last_s_waits, send_status.begin());
105  }
106  // -----------------------------------------------------------------
107  // 3) clear send & receive messages [waits,data]
108  // -----------------------------------------------------------------
109  send.waits.clear();
110  send.data.clear();
111  receive.waits.clear();
112  receive.data.clear();
113  return x.n_new_entry();
114 }
115 //>mpi_assembly_end:
116 } // namespace rheolef
117 #endif //_RHEO_MPI_ASSEMBLY_END_H
field::size_type size_type
Definition: branch.cc:430
size_t size_type
Definition: basis_get.cc:76
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.
Size mpi_assembly_end(Message &receive, Message &send, Size receive_max_size, Container x)