Loading...
Searching...
No Matches
mpi_assembly_end.h
Go to the documentation of this file.
#ifndef _RHEO_MPI_ASSEMBLY_END_H
#define _RHEO_MPI_ASSEMBLY_END_H
#include "rheolef/msg_util.h"
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Weffc++"
#pragma GCC diagnostic ignored "-Wparentheses"
#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
#include <boost/functional.hpp>
#include <boost/iterator/transform_iterator.hpp>
#pragma GCC diagnostic pop
namespace rheolef {
/*F:
NAME: msg_assembly_end -- array or matrix assembly (@PACKAGE@ @VERSION@)
DESCRIPTION:
Finish a dense array or sparse matrix assembly.
COMPLEXITY:
**TO DO**
AUTHORS:
LMC-IMAG, 38041 Grenoble cedex 9, France
| Pierre.Saramito@imag.fr
DATE: 23 march 1999
END:
*/
//<mpi_assembly_end:
template <
class Container,
class Message,
class Size>
Size
mpi_assembly_end (
// input:
Message& receive,
Message& send,
Size receive_max_size,
// output:
Container x)
{
typedef Size size_type;
typedef typename Container::data_type data_type;
// -----------------------------------------------------------------
// 1) receive data and store it in container
// -----------------------------------------------------------------
// note: for wait_any, build an iterator adapter that scan the pair.second in [index,request]
// and then get an iterator in the pair using iter.base(): retrive the corresponding index
// for computing the position in the receive.data buffer
typedef boost::transform_iterator<select2nd<size_type,mpi::request>,
typename std::list<std::pair<size_type,mpi::request> >::iterator>
request_iterator;
while (receive.waits.size() != 0) {
request_iterator iter_r_waits (receive.waits.begin(), select2nd<size_type,mpi::request>()),
last_r_waits (receive.waits.end(), select2nd<size_type,mpi::request>());
// waits on any receive...
std::pair<mpi::status,request_iterator> pair_status = mpi::wait_any (iter_r_waits, last_r_waits);
// check status
boost::optional<int> i_msg_size_opt = pair_status.first.template count<data_type>();
check_macro (i_msg_size_opt, "receive wait failed");
int iproc = pair_status.first.source();
check_macro (iproc >= 0, "receive: source iproc = "<<iproc<<" < 0 !");
// get size of receive and number in data
size_type i_msg_size = (size_type)i_msg_size_opt.get();
typename std::list<std::pair<size_type,mpi::request> >::iterator i_pair_ptr = pair_status.second.base();
size_type i_receive = (*i_pair_ptr).first;
size_type i_start = i_receive*receive_max_size;
for (size_type j = i_start; j < i_start + i_msg_size; j++) {
x (receive.data[j]);
}
receive.waits.erase (i_pair_ptr);
}
// -----------------------------------------------------------------
// 2) wait on sends
// -----------------------------------------------------------------
Size send_nproc = send.waits.size();
std::vector<mpi::status> send_status (send_nproc);
if (send.waits.size() != 0) {
request_iterator iter_s_waits (send.waits.begin(), select2nd<size_type,mpi::request>()),
last_s_waits (send.waits.end(), select2nd<size_type,mpi::request>());
mpi::wait_all (iter_s_waits, last_s_waits, send_status.begin());
}
// -----------------------------------------------------------------
// 3) clear send & receive messages [waits,data]
// -----------------------------------------------------------------
send.waits.clear();
send.data.clear();
receive.waits.clear();
receive.data.clear();
return x.n_new_entry();
}
//>mpi_assembly_end:
} // namespace rheolef
#endif //_RHEO_MPI_ASSEMBLY_END_H
size_type
field::size_type size_type
Definition branch.cc:430
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
This file is part of Rheolef.
Definition compiler_eigen.h:39
rheolef::mpi_assembly_end
Size mpi_assembly_end(Message &receive, Message &send, Size receive_max_size, Container x)
Definition mpi_assembly_end.h:55
rheolef::select2nd
Definition msg_util.h:40