Loading...
Searching...
No Matches
disarray_mpi.icc
Go to the documentation of this file.
# include "rheolef/config.h"
# ifdef _RHEOLEF_HAVE_MPI
# include "rheolef/disarray.h"
# include "rheolef/mpi_assembly_begin.h"
# include "rheolef/mpi_assembly_end.h"
# include "rheolef/mpi_scatter_init.h"
# include "rheolef/mpi_scatter_begin.h"
# include "rheolef/mpi_scatter_end.h"
# include "rheolef/load_chunk.h"
# include "rheolef/disarray_store.h"
# include "rheolef/rheostream.h"
namespace rheolef {
// ----------------------------------------------------------------------------
// allocators
// ----------------------------------------------------------------------------
template <class T, class A>
disarray_rep<T,distributed,A>::disarray_rep (const disarray_rep<T,distributed,A>& x)
: base(x),
_stash(),
_send(),
_receive(),
_receive_max_size(0),
_ext_x(x._ext_x)
{
assert_macro(x._stash.size() == 0 &&
x._send.data.size() == 0 &&
x._receive.data.size() == 0,
"copy during assembly phase: should not be done");
}
template <class T, class A>
disarray_rep<T,distributed,A>::disarray_rep (
const distributor& ownership,
const T& init_val,
const A& alloc)
: base(ownership, init_val,alloc),
_stash(),
_send(),
_receive(),
_receive_max_size(0),
_ext_x()
{
}
template <class T, class A>
void
disarray_rep<T,distributed,A>::resize (
const distributor& ownership,
const T& init_val)
{
base::resize(ownership, init_val);
_stash.clear();
_send.waits.clear();
_send.data.clear();
_receive.waits.clear();
_receive.data.clear();
_receive_max_size = 0;
}
// ===============================================================
// set_dis_entry aka operator=
// ===============================================================
namespace details {
// insert a "U value" for simple, or variable-sized one, as index_set or pair_set types
template <class Map, class SetOp>
inline
void
stash_set (Map& stash, typename Map::size_type dis_i, const typename Map::mapped_type& val, const SetOp& set_op, std::false_type)
{
using size_type = typename Map::size_type;
using T = typename Map::mapped_type;
std::pair<typename Map::iterator,bool> status = stash.insert (std::pair<const size_type,T>(dis_i,T()));
set_op ((*(status.first)).second, val);
}
// disarray<std::set<double>> : more complex op= += -=
template <class MultiMap, class U>
void
stash_set (MultiMap& stash, typename MultiMap::size_type dis_i, const U& val, const details::generic_set_op&, std::true_type)
{
// check if a multi-value for dis_i exists and delete it; then insert the new multi-value
using size_type = typename MultiMap::size_type;
using W = typename MultiMap::mapped_type;
using iterator = typename MultiMap::iterator;
std::pair<iterator, iterator> range_dis_i = stash.equal_range (dis_i);
stash.erase (range_dis_i.first, range_dis_i.second); // TODO: SetOp=generic_set_op ==> extend to others set_op
for (typename U::const_iterator iter = val.begin(), last = val.end(); iter != last; iter++) {
stash.insert (std::pair<const size_type,W>(dis_i,*iter));
}
}
// insert a "U value" in multi-map when U has fixed size
template <class MultiMap, class U>
inline
void
stash_set_plus_multi (MultiMap& stash, typename MultiMap::size_type dis_i, const U& val, const details::generic_set_plus_op& set_op, std::false_type)
{
typedef typename MultiMap::size_type size_type;
typedef typename MultiMap::mapped_type W;
stash.insert (std::pair<const size_type,W>(dis_i,val)); // TODO: SetOp=details::generic_set_plus_op --> more general
}
// insert a "U value" in multi-map when U has variable size
template <class MultiMap, class U>
void
stash_set_plus_multi (MultiMap& stash, typename MultiMap::size_type dis_i, const U& val, const details::generic_set_plus_op& set_op, std::true_type)
{
typedef typename MultiMap::size_type size_type;
typedef typename MultiMap::mapped_type W;
for (typename U::const_iterator iter = val.begin(), last = val.end(); iter != last; iter++) {
stash.insert (std::pair<const size_type,W>(dis_i,*iter)); // TODO: SetOp=details::generic_set_plus_op --> more general
}
}
template <class MultiMap, class U>
inline
void
stash_set (MultiMap& stash, typename MultiMap::size_type dis_i, const U& val, const details::generic_set_plus_op& set_op, std::true_type)
{
stash_set_plus_multi (stash, dis_i, val, set_op, typename details::is_container<U>::type());
}
} // namespace details
// set_dis_entry aka =
template <class T, class A>
template<class U, class SetOp>
void
disarray_rep<T,distributed,A>::set_dis_entry (size_type dis_i, const U& value, const SetOp& set_op)
{
size_type first_i = ownership().first_index();
size_type last_i = ownership().last_index();
if (dis_i >= first_i && dis_i < last_i) {
trace_macro ("set_dis_entry: local ["<<dis_i - first_i<<"] op= " << value<<" with op="<<typename_macro(SetOp));
set_op (disarray_rep<T,distributed,A>::operator[] (dis_i - first_i),
value);
} else {
trace_macro ("set_dis_entry: non-local");
assert_macro (dis_i < ownership().dis_size(),
"index "<<dis_i << " is out of range [0:" << ownership().dis_size() << "[");
details::stash_set (_stash, dis_i, value, set_op, is_container());
// value will be immediadly available via x.dis_at(dis_i)
// => update _ext_x when dis_i is present
typename scatter_map_type::iterator iter = _ext_x.find (dis_i);
if (iter != _ext_x.end()) {
set_op ((*iter).second, value);
}
}
}
#ifdef TO_CLEAN
// set_plus_dis_entry aka +=
template <class T, class A>
template<class U, class SetOp>
void
disarray_rep<T,distributed,A>::set_plus_dis_entry (size_type dis_i, const U& value, const SetOp& set_op)
{
size_type start = ownership().first_index();
size_type last = ownership().last_index();
if (dis_i >= start && dis_i < last) {
set_op (base::operator[](dis_i - start), value);
} else {
assert_macro (dis_i < ownership().dis_size(),
"index "<<dis_i<<" is out of range [0:"<<ownership().dis_size() << "[");
details::stash_set (_stash, dis_i, value, set_op, is_container());
// value will be immediadly available via x.dis_at(dis_i)
// => update _ext_x when dis_i is present
typename scatter_map_type::iterator iter = _ext_x.find (dis_i);
if (iter != _ext_x.end()) {
set_op ((*iter).second, value);
}
}
}
// set_minus_dis_entry aka -=
template <class T, class A>
template<class U, class SetOp>
void
disarray_rep<T,distributed,A>::set_minus_dis_entry (size_type dis_i, const U& value, const SetOp& set_op)
{
size_type start = ownership().first_index();
size_type last = ownership().last_index();
if (dis_i >= start && dis_i < last) {
set_op (base::operator[](dis_i - start), value);
} else {
assert_macro (dis_i < ownership().dis_size(),
"index "<<dis_i<<" is out of range [0:"<<ownership().dis_size() << "[");
details::stash_set_minus (_stash, dis_i, value, set_op, is_container());
// value will be immediadly available via x.dis_at(dis_i)
// => update _ext_x when dis_i is present
typename scatter_map_type::iterator iter = _ext_x.find (dis_i);
if (iter != _ext_x.end()) {
set_op ((*iter).second, value);
}
}
}
#endif // TO_CLEAN
// ===============================================================
// assembly
// ===============================================================
template <class T, class A>
template <class SetOp>
void
disarray_rep<T,distributed,A>::dis_entry_assembly_begin (SetOp my_set_op)
{
_receive_max_size = mpi_assembly_begin (
_stash,
make_apply_iterator(_stash.begin(), first_op<typename stash_map_type::value_type>()),
make_apply_iterator(_stash.end(), first_op<typename stash_map_type::value_type>()),
ownership(),
_receive,
_send);
_stash.clear();
}
template <class T, class A>
template <class SetOp>
void
disarray_rep<T,distributed,A>::dis_entry_assembly_end(SetOp my_set_op)
{
mpi_assembly_end (
_receive,
_send,
_receive_max_size,
disarray_make_store(
begin() - ownership().first_index(),
my_set_op,
size_type(0),
is_container()));
_send.waits.clear();
_send.data.clear();
_receive.waits.clear();
_receive.data.clear();
_receive_max_size = 0;
}
// ===============================================================
// repartition
// ===============================================================
template <class T, class A>
template <class A2>
void
disarray_rep<T,distributed,A>::repartition ( // old_numbering for *this
const disarray_rep<size_type,distributed,A2>& partition, // old_ownership
disarray_rep<T,distributed,A>& new_disarray, // new_ownership
disarray_rep<size_type,distributed,A2>& old_numbering, // new_ownership
disarray_rep<size_type,distributed,A2>& new_numbering) const // old_ownership
{
using namespace std;
communicator_type comm = ownership().comm();
size_type nproc = comm.size();
size_type my_proc = comm.rank();
vector<size_type> send_local_elt_size (nproc, 0);
typename disarray_rep<size_type,distributed,A2>::const_iterator iter_part = partition.begin();
for (size_type ie = 0; ie < partition.size(); ie++, iter_part++) {
send_local_elt_size [*iter_part]++;
}
vector<size_type> recv_local_elt_size (nproc, 0);
all_to_all (comm, send_local_elt_size, recv_local_elt_size);
vector<size_type> recv_local_elt_start (nproc+1);
recv_local_elt_start [0] = 0;
for (size_type iproc = 0; iproc < nproc; iproc++) {
recv_local_elt_start [iproc+1] = recv_local_elt_start [iproc] + recv_local_elt_size[iproc];
}
vector<size_type> send_local_elt_start (nproc);
all_to_all (comm, recv_local_elt_start.begin().operator->(), send_local_elt_start.begin().operator->());
size_type new_local_n_elt = recv_local_elt_start [nproc];
size_type global_n_elt = dis_size();
// re-distribute data:
distributor new_elt_ownership (global_n_elt, comm, new_local_n_elt);
new_disarray.resize (new_elt_ownership);
old_numbering.resize (new_elt_ownership, numeric_limits<size_type>::max());
new_numbering.resize (ownership(), numeric_limits<size_type>::max());
iter_part = partition.begin();
const_iterator iter_elt = begin();
typename disarray_rep<size_type,distributed,A2>::iterator iter_new_num_elt = new_numbering.begin();
for (size_type ie = 0, ne = partition.size(); ie < ne; ie++, iter_part++, iter_elt++, iter_new_num_elt++) {
size_type iproc = *iter_part;
const T& x = *iter_elt;
size_type new_global_ie = new_elt_ownership[iproc] + send_local_elt_start[iproc];
new_disarray.dis_entry (new_global_ie) = x;
*iter_new_num_elt = new_global_ie;
size_type old_global_ie = ownership()[my_proc] + ie;
old_numbering.dis_entry (new_global_ie) = old_global_ie;
send_local_elt_start[iproc]++;
}
new_disarray.template dis_entry_assembly<typename details::default_set_op_traits<T>::type>();
old_numbering.template dis_entry_assembly<typename details::default_set_op_traits<size_type>::type>();
}
template <class T, class A>
template <class A2>
void
disarray_rep<T,distributed,A>::reverse_permutation ( // old_ownership for *this=iold2dis_inew
disarray_rep<size_type,distributed,A2>& inew2dis_iold) const // new_ownership
{
check_macro (inew2dis_iold.dis_size() == dis_size(), "reverse permutation[0:"<<inew2dis_iold.dis_size()
<<"[ has incompatible dis_range with oriinal permutation[0:"<<dis_size()<<"[");
size_type first_dis_iold = ownership().first_index();
for (size_type iold = 0; iold < size(); iold++) {
size_type dis_iold = first_dis_iold + iold;
size_type dis_inew = base::operator[] (iold);
inew2dis_iold.dis_entry (dis_inew) = dis_iold;
}
inew2dis_iold.template dis_entry_assembly<typename details::default_set_op_traits<T>::type>();
}
template <class T, class A>
template <class A2>
void
disarray_rep<T,distributed,A>::permutation_apply ( // old_numbering for *this
const disarray_rep<size_type,distributed,A2>& new_numbering, // old_ownership
disarray_rep<T,distributed,A>& new_disarray) const // new_ownership
{
check_macro (size() == new_numbering.size(),
"permutation_apply: incompatible disarray("<<size()<<") and permutation("<<new_numbering.size()<<") sizes");
check_macro (dis_size() == new_disarray.dis_size(),
"permutation_apply: incompatible disarray("<<dis_size()<<") and permutation("<<new_disarray.dis_size()<<") dis_sizes");
typename disarray_rep<size_type,distributed,A2>::const_iterator iter_dis_new_ie = new_numbering.begin();
for (const_iterator iter = begin(), last = end(); iter != last; iter++, iter_dis_new_ie++) {
size_type dis_new_ie = *iter_dis_new_ie;
new_disarray.dis_entry (dis_new_ie) = *iter;
}
new_disarray.template dis_entry_assembly<typename details::default_set_op_traits<T>::type>();
}
template <class T, class A>
template <class Set, class Map>
void
disarray_rep<T,distributed,A>::append_dis_entry (const Set& ext_idx_set, Map& ext_idx_map, std::false_type) const
{
// 0) declare the local context
scatter_message<std::vector<T,A> > from;
scatter_message<std::vector<T,A> > to;
// 1) convert set to vector, for direct acess:
std::vector<size_type> ext_idx (ext_idx_set.size());
std::copy (ext_idx_set.begin(), ext_idx_set.end(), ext_idx.begin());
// 2) declare id[i]=i for scatter
std::vector<size_type> id (ext_idx.size());
for (size_type i = 0; i < id.size(); i++) id[i] = i;
// 3) init scatter
distributor::tag_type tag_init = distributor::get_new_tag();
mpi_scatter_init(
ext_idx.size(),
ext_idx.begin().operator->(),
id.size(),
id.begin().operator->(),
ownership().dis_size(),
ownership().begin().operator->(),
tag_init,
ownership().comm(),
from,
to);
// 4) begin scatter: send local data to others and get ask for missing data
std::vector<T,A> buffer (ext_idx.size());
distributor::tag_type tag = distributor::get_new_tag();
mpi_scatter_begin (
begin().operator->(),
buffer.begin().operator->(),
from,
to,
details::generic_set_op(),
tag,
ownership().comm());
// 5) end scatter: receive missing data
mpi_scatter_end (
begin().operator->(),
buffer.begin(),
from,
to,
details::generic_set_op(),
tag,
ownership().comm());
// 6) build the associative container: pair (ext_idx ; data)
for (size_type i = 0; i < buffer.size(); i++) {
ext_idx_map.insert (std::make_pair (ext_idx[i], buffer[i]));
}
}
template <class T, class A>
void
disarray_rep<T,distributed,A>::reset_dis_indexes() const
{
std::set<size_type> ext_idx_set;
for (typename scatter_map_type::const_iterator iter = _ext_x.begin(), last = _ext_x.end(); iter != last; iter++) {
ext_idx_set.insert ((*iter).first);
}
set_dis_indexes (ext_idx_set);
}
template <class T, class A>
template <class Set, class Map>
void
disarray_rep<T,distributed,A>::append_dis_entry (const Set& ext_idx_set, Map& ext_idx_map, std::true_type) const
{
typedef typename T::value_type S; // S is supposed to be MPI-simple, i.e. with fixed size
// 0) declare the local context
typedef scatter_message<std::vector<T>, true> message_type; // TODO: vector<T,A> for heap_alloc
message_type from;
message_type to;
// 1) convert set to vector, for direct acess:
std::vector<size_type> ext_idx (ext_idx_set.size());
std::copy (ext_idx_set.begin(), ext_idx_set.end(), ext_idx.begin());
// 2) declare id[i]=i for scatter
std::vector<size_type> id (ext_idx.size());
for (size_type i = 0; i < id.size(); i++) id[i] = i;
// 3) init scatter
distributor::tag_type tag_init = distributor::get_new_tag();
mpi_scatter_init(
ext_idx.size(),
ext_idx.begin().operator->(),
id.size(),
id.begin().operator->(),
ownership().dis_size(),
ownership().begin().operator->(),
tag_init,
ownership().comm(),
from.get_base(),
to.get_base());
// 4) copy size of multi-valued objects into a tmp
std::vector<size_type> data_sizes (size());
for (size_type i = 0, n = size(); i < n; i++) {
data_sizes[i] = base::operator[](i).size();
}
// 5) begin scatter: send local data to others and get ask for missing data
std::vector<size_type> buffer (ext_idx.size());
distributor::tag_type tag = distributor::get_new_tag();
mpi_scatter_begin (
data_sizes.begin().operator->(),
buffer.begin().operator->(),
from.get_base(),
to.get_base(),
details::generic_set_op(),
tag,
ownership().comm());
// 6) end scatter: receive missing data
mpi_scatter_end (
data_sizes.begin().operator->(),
buffer.begin(),
from.get_base(),
to.get_base(),
details::generic_set_op(),
tag,
ownership().comm());
// 7) initialize multi-valued scatter
from.multi_init();
to.multi_init();
// 8) begin multi-valued scatter
std::vector<T> multi_buffer (ext_idx.size()); // TODO: vector<T,A> for heap_alloc
distributor::tag_type multi_tag = distributor::get_new_tag();
mpi_scatter_begin (
begin().operator->(),
multi_buffer.begin().operator->(),
from,
to,
details::generic_set_op(),
multi_tag,
ownership().comm());
// 9) end scatter: receive missing data
mpi_scatter_end (
begin().operator->(),
multi_buffer.begin(),
from,
to,
details::generic_set_op(),
multi_tag,
ownership().comm());
// 10) build the associative container: pair (ext_idx ; data)
for (size_type i = 0; i < multi_buffer.size(); i++) {
ext_idx_map.insert (std::make_pair (ext_idx[i], multi_buffer[i]));
}
}
template <class T, class A>
template <class Set, class Map>
inline
void
disarray_rep<T,distributed,A>::append_dis_entry (const Set& ext_idx_set, Map& ext_idx_map) const
{
append_dis_entry (ext_idx_set, ext_idx_map, is_container());
}
template <class T, class A>
typename disarray_rep<T,distributed,A>::const_reference
disarray_rep<T,distributed,A>::dis_at (const size_type dis_i) const
{
if (dis_i >= ownership().first_index() && dis_i < ownership().last_index()) {
size_type i = dis_i - ownership().first_index();
return base::operator[](i);
}
typename scatter_map_type::const_iterator iter = _ext_x.find (dis_i);
check_macro (iter != _ext_x.end(), "unexpected external index="<<dis_i);
return (*iter).second;
}
template <class T, class A>
void
disarray_rep<T,distributed,A>::get_dis_indexes (std::set<size_type>& ext_idx_set) const
{
ext_idx_set.clear();
for (auto x: _ext_x) {
ext_idx_set.insert (x.first);
}
}
// ===============================================================
// put & get
// ===============================================================
template <class T, class A>
template <class PutFunction>
odiststream&
disarray_rep<T,distributed,A>::put_values (odiststream& ops, PutFunction put_element) const
{
distributor::tag_type tag = distributor::get_new_tag();
std::ostream& s = ops.os();
// determine maximum message to arrive
size_type max_size = 0;
mpi::reduce(comm(), size(), max_size, mpi::maximum<size_type>(), 0);
size_type io_proc = odiststream::io_proc();
if (ownership().process() == io_proc) {
for (size_type i = 0; i < size(); i++) {
put_element (s, base::operator[](i));
s << std::endl;
}
// receive and print messages
std::vector<T,A> values (max_size);
for (size_type iproc = 0; iproc < ownership().n_process(); iproc++) {
if (iproc == io_proc) continue;
size_type loc_sz_i = ownership().size(iproc);
if (loc_sz_i == 0) continue;
mpi::status status = comm().recv(iproc, tag, values.begin().operator->(), max_size);
boost::optional<int> n_data_opt = status.count<T>();
check_macro (n_data_opt, "receive failed");
size_type n_data = n_data_opt.get();
for (size_type i = 0; i < n_data; i++) {
put_element (s, values[i]);
s << std::endl;
}
}
s << std::flush;
} else {
if (size() != 0) {
comm().send(io_proc, tag, begin().operator->(), size());
}
}
return ops;
}
template <class T, class A>
odiststream&
disarray_rep<T,distributed,A>::put_values (odiststream& ops) const
{
return put_values (ops, _disarray_put_element_type<T>());
}
template <class T, class A>
odiststream&
disarray_rep<T,distributed,A>::put_matlab (odiststream& ops) const
{
ops << "[";
put_values (ops, _disarray_put_matlab_type<T>());
return ops << "];";
}
template <class T, class A>
template <class PutFunction, class A2>
odiststream&
disarray_rep<T,distributed,A>::permuted_put_values (
odiststream& ops,
const disarray_rep<size_type,distributed,A2>& perm,
PutFunction put_element) const
{
assert_macro (perm.size() == size(), "permutation size does not match");
size_type io_proc = odiststream::io_proc();
size_type my_proc = comm().rank();
distributor io_ownership (dis_size(), comm(), (my_proc == io_proc) ? dis_size() : 0);
disarray_rep<T,distributed,A> perm_x (io_ownership);
for (size_type i = 0, n = size(); i < n; i++) {
perm_x.dis_entry (perm[i]) = base::operator[](i);
}
perm_x.template dis_entry_assembly_begin<typename details::default_set_op_traits<T>::type>();
perm_x.template dis_entry_assembly_end <typename details::default_set_op_traits<T>::type>();
return perm_x.base::put_values (ops, put_element);
}
template <class T, class A>
template <class GetFunction>
idiststream&
disarray_rep<T,distributed,A>::get_values (idiststream& ps, GetFunction get_element) {
distributor::tag_type tag = distributor::get_new_tag();
std::istream& s = ps.is();
size_type io_proc = odiststream::io_proc();
if (ownership().process() == io_proc) {
// load first chunk associated to proc 0
if (!load_chunk (s, begin(), end(), get_element))
error_macro("read failed on input stream.");
if (ownership().n_process() > 1) {
// read in other chuncks and send to other processors
// determine maximum chunck owned by other
size_type size_max = 1;
for (size_type iproc = 0; iproc < ownership().n_process(); iproc++) {
size_max = std::max (size_max, ownership().size(iproc));
}
std::vector<T,A> data_proc_j (size_max);
T *start_j = data_proc_j.begin().operator->();
// bizarre qu'on lise ts les blocs dans la meme zone de memoire
// et qu'on attende pas que ce soit envoye pour ecraser par le suivant ?
for (size_type jproc = 0; jproc < ownership().n_process(); jproc++) {
if (jproc == io_proc) continue;
// load first chunk associated to proc j
size_type loc_sz_j = ownership().size(jproc);
if (loc_sz_j == 0) continue;
T *last_j = start_j + loc_sz_j;
if (!load_chunk (s, start_j, last_j, get_element))
error_macro("read failed on input stream.");
comm().send (jproc, tag, start_j, loc_sz_j);
}
}
} else {
if (size() != 0) {
comm().recv(io_proc, tag, begin().operator->(), size());
}
}
return ps;
}
template <class T, class A>
idiststream&
disarray_rep<T,distributed,A>::get_values (idiststream& ips)
{
return get_values (ips, _disarray_get_element_type<T>());
}
template <class T, class A>
void
disarray_rep<T,distributed,A>::dump (std::string name) const
{
base::dump (name + std::to_string(comm().rank()));
}
} // namespace rheolef
# endif // _RHEOLEF_HAVE_MPI
size_type
field::size_type size_type
Definition branch.cc:430
rheolef::disarray_rep< T, distributed, A >::set_dis_indexes
void set_dis_indexes(const Set &ext_idx_set) const
Definition disarray.h:350
rheolef::disarray_rep< T, distributed, A >::begin
const_iterator begin() const
Definition disarray.h:316
rheolef::disarray_rep< T, distributed, A >::dis_size
size_type dis_size() const
Definition disarray.h:325
rheolef::disarray_rep< T, distributed, A >::put_values
odiststream & put_values(odiststream &s) const
Definition disarray_mpi.icc:580
rheolef::disarray_rep< T, distributed, A >::_stash
stash_map_type _stash
Definition disarray.h:435
rheolef::disarray_rep< T, distributed, A >::first_index
size_type first_index() const
Definition disarray.h:323
rheolef::disarray_rep< T, distributed, A >::size
size_type size() const
Definition disarray.h:315
rheolef::disarray_rep< T, distributed, A >::is_container
details::is_container_of_mpi_datatype< T >::type is_container
Definition disarray.h:416
rheolef::disarray_rep< T, distributed, A >::_receive_max_size
size_type _receive_max_size
Definition disarray.h:438
rheolef::disarray_rep< T, distributed, A >::comm
const mpi::communicator & comm() const
Definition disarray.h:322
rheolef::disarray_rep< T, distributed, A >::dis_entry_assembly_begin
void dis_entry_assembly_begin(SetOp my_set_op=SetOp())
Definition disarray_mpi.icc:220
rheolef::disarray_rep< T, distributed, A >::base
disarray_rep< T, sequential, A > base
Definition disarray.h:295
rheolef::disarray_rep< T, distributed, A >::communicator_type
distributor::communicator_type communicator_type
Definition disarray.h:304
rheolef::disarray_rep< T, distributed, A >::get_values
idiststream & get_values(idiststream &s)
Definition disarray_mpi.icc:655
rheolef::disarray_rep< T, distributed, A >::_ext_x
scatter_map_type _ext_x
Definition disarray.h:439
rheolef::disarray_rep< T, distributed, A >::size_type
typename base::size_type size_type
Definition disarray.h:296
rheolef::disarray_rep< T, distributed, A >::const_iterator
typename base::const_iterator const_iterator
Definition disarray.h:300
rheolef::disarray_rep< T, distributed, A >::_receive
message_type _receive
Definition disarray.h:437
rheolef::disarray_rep< T, distributed, A >::dis_entry_assembly
void dis_entry_assembly(SetOp my_set_op=SetOp())
Definition disarray.h:334
rheolef::disarray_rep< T, distributed, A >::end
const_iterator end() const
Definition disarray.h:317
rheolef::disarray_rep< T, distributed, A >::_send
message_type _send
Definition disarray.h:436
rheolef::disarray_rep< T, distributed, A >::disarray_rep
disarray_rep(const distributor &ownership, const T &init_val=T(), const A &alloc=A())
Definition disarray_mpi.icc:55
rheolef::disarray_rep< T, distributed, A >::append_dis_entry
void append_dis_entry(const Set &ext_idx_set, Map &ext_idx_map) const
get values from ext_idx_set, that are managed by another proc
Definition disarray_mpi.icc:509
rheolef::disarray_rep< T, distributed, A >::ownership
const distributor & ownership() const
Definition disarray.h:321
rheolef::disarray_rep< T, distributed, A >::last_index
size_type last_index() const
Definition disarray.h:324
rheolef::disarray_rep< T, sequential, A >::operator[]
reference operator[](size_type i)
Definition disarray.h:247
rheolef::disarray_rep< T, sequential, A >::dump
void dump(std::string name) const
Definition disarray_seq.icc:113
rheolef::disarray_rep< T, sequential, A >::resize
void resize(const distributor &ownership, const T &init_val=T())
Definition disarray_seq.icc:54
rheolef::disarray_rep
Definition disarray.h:214
rheolef::distributor
see the distributor page for the full documentation
Definition distributor.h:69
rheolef::distributor::get_new_tag
static tag_type get_new_tag()
returns a new tag
Definition distributor.cc:133
rheolef::distributor::tag_type
int tag_type
Definition distributor.h:78
rheolef::idiststream
idiststream: see the diststream page for the full documentation
Definition diststream.h:336
rheolef::idiststream::is
std::istream & is()
Definition diststream.h:400
rheolef::odiststream
odiststream: see the diststream page for the full documentation
Definition diststream.h:137
rheolef::odiststream::os
std::ostream & os()
Definition diststream.h:247
rheolef::odiststream::io_proc
static size_type io_proc()
Definition diststream.cc:79
rheolef::scatter_message
Definition scatter_message.h:33
trace_macro
#define trace_macro(message)
Definition dis_macros.h:111
assert_macro
#define assert_macro(ok_condition, message)
Definition dis_macros.h:113
error_macro
#define error_macro(message)
Definition dis_macros.h:49
T
Expr1::float_type T
Definition field_expr.h:230
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::details
Definition compiler_eigen.h:39
rheolef::details::stash_set
void stash_set(Map &stash, typename Map::size_type dis_i, const typename Map::mapped_type &val, const SetOp &set_op, std::false_type)
Definition disarray_mpi.icc:90
rheolef::details::stash_set_plus_multi
void stash_set_plus_multi(MultiMap &stash, typename MultiMap::size_type dis_i, const U &val, const details::generic_set_plus_op &set_op, std::false_type)
Definition disarray_mpi.icc:116
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::mpi_scatter_end
void mpi_scatter_end(InputIterator x, OutputIterator y, Message &from, Message &to, SetOp op, Tag tag, Comm comm)
Definition mpi_scatter_end.h:60
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::load_chunk
bool load_chunk(std::istream &s, RandomIterator iter, RandomIterator last)
Definition load_chunk.h:27
rheolef::disarray_make_store
disarray_store< OutputRandomIterator, SetOp, Size, IsContainer > disarray_make_store(OutputRandomIterator x, SetOp op, Size, IsContainer)
Definition disarray_store.h:60
rheolef::mpi_scatter_init
void mpi_scatter_init(Size nidx, SizeRandomIterator1 idx, Size nidy, SizeRandomIterator2 idy, Size idy_maxval, SizeRandomIterator3 ownership, Tag tag, const distributor::communicator_type &comm, Message &from, Message &to)
Definition mpi_scatter_init.h:73
rheolef::make_apply_iterator
apply_iterator< Iterator, Operator > make_apply_iterator(Iterator i, Operator op)
Definition msg_util.h:114
rheolef::mpi_assembly_begin
Stash::size_type mpi_assembly_begin(const Stash &stash, InputIterator first_stash_idx, InputIterator last_stash_idx, const distributor &ownership, Message &receive, Message &send)
Definition mpi_assembly_begin.h:57
std
STL namespace.
A
Definition diffusion_isotropic.h:25
rheolef::_disarray_get_element_type
disarray element input helper
Definition disarray.h:205
rheolef::_disarray_put_element_type
disarray element output helper
Definition disarray.h:196
rheolef::_disarray_put_matlab_type
Definition disarray.h:200
rheolef::details::is_container::type
std::false_type type
Definition msg_util.h:236
rheolef::disarray_rep< T, distributed, A >::message_type
Definition disarray.h:422
rheolef::first_op
Definition msg_util.h:73