Rheolef  7.2
an efficient C++ finite element environment
 
Loading...
Searching...
No Matches
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
34namespace rheolef {
35
36/*F:
37NAME: msg_assembly_end -- array or matrix assembly (@PACKAGE@ @VERSION@)
38DESCRIPTION:
39 Finish a dense array or sparse matrix assembly.
40COMPLEXITY:
41 **TO DO**
42AUTHORS:
43 LMC-IMAG, 38041 Grenoble cedex 9, France
44 | Pierre.Saramito@imag.fr
45DATE: 23 march 1999
46END:
47*/
48
49//<mpi_assembly_end:
50template <
51 class Container,
52 class Message,
53 class Size>
54Size
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
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)