Rheolef  7.2
an efficient C++ finite element environment
 
Loading...
Searching...
No Matches
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
37namespace rheolef {
38
39/*F:
40NAME: mpi_scatter_end -- gather/scatter finalize (@PACKAGE@ @VERSION@)
41DESCRIPTION:
42 Finishes communication
43 for distributed to sequential scatter context.
44AUTHORS:
45 LMC-IMAG, 38041 Grenoble cedex 9, France
46 | Pierre.Saramito@imag.fr
47DATE: 23 march 1999
48END:
49*/
50
51//<mpi_scatter_end:
52template <
53 class InputIterator,
54 class OutputIterator,
55 class Message,
56 class SetOp,
57 class Tag,
58 class Comm>
59void
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)