Loading...
Searching...
No Matches
mpi_scatter_begin.h
Go to the documentation of this file.
#ifndef _RHEO_MPI_SCATTER_BEGIN_H
#define _RHEO_MPI_SCATTER_BEGIN_H
# include "rheolef/msg_right_permutation_apply.h"
# include "rheolef/msg_both_permutation_apply.h"
namespace rheolef {
/*F:
NAME: mpi_scatter_begin -- gather/scatter initialize (@PACKAGE@ @VERSION@)
DESCRIPTION:
Begin communication
for distributed to sequential scatter context.
COMPLEXITY:
IMPLEMENTATION:
Even though the next routines are written with distributed
vectors, either x or y (but not both) may be sequential
vectors, one for each processor.
from indices indicate where arriving stuff is stashed
to indices indicate where departing stuff came from.
the naming can be a little confusing.
Reverse scatter is obtained by swapping (to,from)
in calls to scatter_begin and scatter_end.
Reverse scatter is useful for transpose matrix-vector multiply.
Scatter general operation is handled by a template "SetOp" type.
The special case "SetOp=set_op" of an affectation is treated
separatly, tacking care of local scatter affectation.
Thus, the "mpi_scatter_begin" routine is split into
"msg_scatter_begin_global" and "msg_scatter_begin_local"
parts.
AUTHORS:
LMC-IMAG, 38041 Grenoble cedex 9, France
| Pierre.Saramito@imag.fr
DATE: 23 march 1999
END:
*/
//<mpi_scatter_begin:
template <
class InputIterator,
class Message,
class Tag,
class Comm>
void
mpi_scatter_begin_global (
InputIterator x,
Message& from,
Message& to,
Tag tag,
Comm comm)
{
typedef typename Message::size_type size_type;
// ----------------------------------------------------------
// 1) post receives
// ----------------------------------------------------------
from.requests.clear();
{
size_type n_receive = from.starts().size() - 1;
size_type i_start = 0;
for (size_type i = 0; i < n_receive; i++) {
size_type i_size = from.starts() [i+1] - from.starts() [i];
mpi::request i_req = comm.irecv(
from.procs() [i],
tag,
from.values().begin().operator->() + i_start,
i_size);
i_start += i_size;
from.requests.push_back (std::make_pair(i, i_req));
}
} // end block
// ----------------------------------------------------------
// 2) apply right permutation
// ----------------------------------------------------------
to.load_values (x);
// ----------------------------------------------------------
// 3) do sends
// ----------------------------------------------------------
to.requests.clear();
{
size_type n_send = to.starts().size() - 1;
size_type i_start = 0;
for (size_type i = 0; i < n_send; i++) {
size_type i_size = to.starts() [i+1] - to.starts() [i];
mpi::request i_req = comm.isend(
to.procs() [i],
tag,
to.values().begin().operator->() + i_start,
i_size);
i_start += i_size;
to.requests.push_back (std::make_pair(i, i_req));
}
} // end block
}
template <
class InputIterator,
class OutputIterator,
class SetOp,
class Message>
void
mpi_scatter_begin_local (
InputIterator x,
OutputIterator y,
Message& from,
Message& to,
SetOp op)
{
#ifdef TO_CLEAN
msg_both_permutation_apply (
to.local_slots.begin(),
to.local_slots.end(),
x,
op,
from.local_slots.begin(),
y);
#endif // TO_CLEAN
}
// take care of local insert: template specialisation
template <
class InputIterator,
class OutputIterator,
class Message>
void
mpi_scatter_begin_local (
InputIterator x,
OutputIterator y,
Message& from,
Message& to,
details::generic_set_op op)
{
#ifdef TO_CLEAN
// used when x & y have distinct pointer types (multi-valued)
if (y == x && ! to.local_nonmatching_computed) {
// scatter_local_optimize(to,from);
fatal_macro ("y == x: adress matches in scatter: not yet -- sorry");
}
if (to.local_is_copy) {
std::copy(x + to.local_copy_start,
x + to.local_copy_start + to.local_copy_length,
y + from.local_copy_start);
} else if (y != x || ! to.local_nonmatching_computed) {
msg_both_permutation_apply (
to.local_slots.begin(),
to.local_slots.end(),
x,
op,
from.local_slots.begin(),
y);
} else { // !to.local_is_copy && y == x && to.local_nonmatching_computed
msg_both_permutation_apply (
to.local_slots_nonmatching.begin(),
to.local_slots_nonmatching.end(),
x,
op,
from.local_slots_nonmatching.begin(),
y);
}
#endif // TO_CLEAN
}
template <
class InputIterator,
class OutputIterator,
class Message,
class SetOp,
class Tag,
class Comm>
inline
void
mpi_scatter_begin(
InputIterator x,
OutputIterator y,
Message& from,
Message& to,
SetOp op,
Tag tag,
Comm comm)
{
mpi_scatter_begin_global (x, from, to, tag, comm);
if (to.n_local() == 0) {
return;
}
error_macro ("local messages: no more supported");
mpi_scatter_begin_local (x, y, from, to, op);
}
//>mpi_scatter_begin:
} // namespace rheolef
#endif // _RHEO_MPI_SCATTER_BEGIN_H
error_macro
#define error_macro(message)
Definition dis_macros.h:49
fatal_macro
#define fatal_macro(message)
Definition dis_macros.h:33
rheolef
This file is part of Rheolef.
Definition compiler_eigen.h:39
rheolef::mpi_scatter_begin_local
void mpi_scatter_begin_local(InputIterator x, OutputIterator y, Message &from, Message &to, SetOp op)
Definition mpi_scatter_begin.h:123
rheolef::msg_both_permutation_apply
void msg_both_permutation_apply(InputIterator1 px, InputIterator1 last_px, InputRandomIterator x, SetOp set_op, InputIterator2 py, OutputRandomIterator y)
Definition msg_both_permutation_apply.h:58
rheolef::mpi_scatter_begin
void mpi_scatter_begin(InputIterator x, OutputIterator y, Message &from, Message &to, SetOp op, Tag tag, Comm comm)
Definition mpi_scatter_begin.h:196
rheolef::mpi_scatter_begin_global
void mpi_scatter_begin_global(InputIterator x, Message &from, Message &to, Tag tag, Comm comm)
Definition mpi_scatter_begin.h:67