1 #include "rheolef/config.h"
22 #ifdef _RHEOLEF_HAVE_MPI
24 #include "rheolef/hack_array.h"
31 template<
class T,
class A>
41 template<
class T,
class A>
43 :
base(ownership,param,alloc),
51 template <
class T,
class A>
55 base::resize (ownership, param);
59 _receive.waits.clear();
60 _receive.data.clear();
61 _receive_max_size = 0;
66 template <
class T,
class A>
70 if (ownership().is_owned (dis_i)) {
71 size_type i = dis_i - ownership().first_index();
75 assert_macro (dis_i < ownership().dis_size(),
"index "<<dis_i
76 <<
" is out of range [0:" << ownership().dis_size() <<
"[");
78 size_type dis_iraw = base::_value_size*dis_i + 1;
79 typename generic_value_type::const_iterator iter = val._data_begin();
80 for (
size_type loc_iraw = 0, loc_nraw = val._data_size(); loc_iraw < loc_nraw; loc_iraw++, iter++) {
81 _stash.insert (std::pair<const size_type,raw_type>(dis_iraw + loc_iraw, *iter));
84 template <
class T,
class A>
92 raw_base::ownership(),
98 template <
class T,
class A>
107 raw_base::begin() - raw_base::ownership().first_index(),
114 _receive.waits.clear();
115 _receive.data.clear();
116 _receive_max_size = 0;
125 template <
class T,
class A>
126 template <
class Set,
class Map>
135 std::vector<size_type> raw_ext_idx (base::_data_size*ext_idx_set.size());
136 typename Set::const_iterator iter = ext_idx_set.begin();
137 for (
size_type i = 0; i < ext_idx_set.size(); i++, iter++) {
139 for (
size_type l = 0; l < base::_data_size; l++) {
140 size_type raw_i = base::_data_size*i + l;
141 size_type raw_idx = base::_value_size*idx + l + (base::_value_size - base::_data_size);
142 raw_ext_idx [raw_i] = raw_idx;
146 std::vector<size_type> raw_id (raw_ext_idx.size());
147 for (
size_type i = 0; i < raw_id.size(); i++) raw_id[i] = i;
150 size_type raw_dis_size = base::_value_size*ownership().dis_size();
151 size_type raw_size = base::_value_size*ownership().size();
152 distributor raw_ownership (raw_dis_size, ownership().comm(), raw_size);
156 raw_ext_idx.begin().operator->(),
158 raw_id.begin().operator->(),
160 raw_ownership.
begin().operator->(),
162 raw_ownership.
comm(),
167 std::vector<raw_type> raw_buffer (raw_ext_idx.size());
170 typedef typename base::base
raw_base;
171 typename raw_base::const_iterator raw_begin = raw_base::begin();
174 raw_buffer.begin().operator->(),
179 raw_ownership.
comm());
184 raw_buffer.begin().operator->(),
189 raw_ownership.
comm());
192 iter = ext_idx_set.begin();
193 for (
size_type i = 0; i < ext_idx_set.size(); i++, iter++) {
196 typename automatic_value_type::iterator
p =
value._data_begin();
197 for (
size_type l = 0; l < base::_data_size; l++,
p++) {
198 size_type raw_i = base::_data_size*i + l;
199 *
p = raw_buffer[raw_i];
201 ext_idx_map.insert (std::make_pair (idx,
value));
204 template <
class T,
class A>
208 if (ownership().is_owned(dis_i)) {
209 size_type i = dis_i - ownership().first_index();
210 return operator[](i);
212 typename scatter_map_type::const_iterator iter = _ext_x.find (dis_i);
213 check_macro (iter != _ext_x.end(),
"unexpected external index="<<dis_i);
214 return (*iter).second;
216 template <
class T,
class A>
220 std::set<size_type> ext_i;
221 for (
typename scatter_map_type::const_iterator
222 iter = _ext_x.begin(),
223 last = _ext_x.end(); iter != last; ++iter) {
224 ext_i.insert ((*iter).first);
226 get_dis_entry (ext_i, _ext_x);
231 template <
class T,
class A>
232 template <
class PutFunction>
237 std::ostream& os = ops.
os();
241 mpi::reduce(comm(), size(), max_size, mpi::maximum<size_type>(), 0);
244 if (ownership().process() == io_proc) {
245 base::put_values (ops, put_element);
247 std::vector<raw_type> raw_values (max_size*base::_data_size, std::numeric_limits<raw_type>::max());
248 for (
size_type iproc = 0; iproc < ownership().n_process(); iproc++) {
249 if (iproc == io_proc)
continue;
250 size_type loc_sz_i = ownership().size(iproc);
251 if (loc_sz_i == 0)
continue;
252 mpi::status status = comm().recv(iproc, tag, raw_values.begin().operator->(), raw_values.size());
256 check_macro (n_data == loc_sz_i*base::_data_size,
"unexpected receive message size");
257 typename T::automatic_type
tmp (base::_parameter);
258 for (
size_type i = 0; i < loc_sz_i; i++) {
259 typename T::iterator
p =
tmp._data_begin();
260 for (
size_type iloc = 0; iloc < base::_data_size; iloc++,
p++) {
261 *
p = raw_values [i*base::_data_size + iloc];
263 put_element (os,
tmp);
270 std::vector<raw_type> raw_values (size()*base::_data_size, std::numeric_limits<raw_type>::max());
272 for (
size_type j = 0; j < base::_data_size; j++) {
273 raw_values [i*base::_data_size + j] = raw_base::operator[] (i*base::_value_size + j+(base::_value_size - base::_data_size));
276 comm().send(io_proc, tag, raw_values.begin().operator->(), raw_values.size());
281 template <
class T,
class A>
287 template <
class T,
class A>
288 template <
class GetFunction>
293 std::istream& is = ips.is();
294 size_type my_proc = ownership().process();
297 for (
size_type iproc = 0; iproc < ownership().n_process(); iproc++) {
298 size_max = std::max (size_max, ownership().size(iproc));
300 distributor io_ownership (size_max, comm(), (my_proc == io_proc) ? size_max : 0);
302 if (my_proc == io_proc) {
305 if (ownership().n_process() > 1) {
308 std::vector<raw_type> raw_values (size_max*base::_data_size, std::numeric_limits<raw_type>::max());
312 for (
size_type jproc = 0; jproc < ownership().n_process(); jproc++) {
313 if (jproc == io_proc)
continue;
315 size_type loc_sz_j = ownership().size(jproc);
316 if (loc_sz_j == 0)
continue;
320 for (
size_type j = 0; j < base::_data_size; j++) {
321 raw_values [i*base::_data_size + j] = data_proc_j.raw_base::operator[] (i*base::_value_size + j+(base::_value_size - base::_data_size));
324 comm().send (jproc, tag, raw_values.begin().operator->(), loc_sz_j*base::_data_size);
329 std::vector<raw_type> raw_values (size()*base::_data_size, std::numeric_limits<raw_type>::max());
330 comm().recv (io_proc, tag, raw_values.begin().operator->(), size()*base::_data_size);
332 for (
size_type j = 0; j < base::_data_size; j++) {
333 raw_base::operator[] (i*base::_value_size + j+(base::_value_size - base::_data_size))
334 = raw_values [i*base::_data_size + j];
341 template <
class T,
class A>
347 template <
class T,
class A>
348 template <
class PutFunction,
class Permutation>
352 const Permutation& perm,
353 PutFunction put_element)
const
356 assert_macro (perm.size() == size(),
"permutation size does not match");
359 distributor io_ownership (dis_size(), comm(), (my_proc == io_proc) ? dis_size() : 0);
362 perm_x.
dis_entry (perm[i]) = operator[](i);
365 perm_x.hack_array_seq_rep<T,A>::put_values (ops, put_element);
371 template <
class T,
class A>
381 communicator comm = ownership().comm();
384 vector<size_type> send_local_elt_size (nproc, 0);
386 for (
size_type ie = 0; ie < partition.size(); ie++, iter_part++) {
387 send_local_elt_size [*iter_part]++;
389 vector<size_type> recv_local_elt_size (nproc, 0);
390 all_to_all (comm, send_local_elt_size, recv_local_elt_size);
391 vector<size_type> recv_local_elt_start (nproc+1);
392 recv_local_elt_start [0] = 0;
393 for (
size_type iproc = 0; iproc < nproc; iproc++) {
394 recv_local_elt_start [iproc+1] = recv_local_elt_start [iproc] + recv_local_elt_size[iproc];
396 vector<size_type> send_local_elt_start (nproc);
397 all_to_all (comm, recv_local_elt_start.begin().operator->(), send_local_elt_start.begin().operator->());
398 size_type new_local_n_elt = recv_local_elt_start [nproc];
402 distributor new_elt_ownership (global_n_elt, comm, new_local_n_elt);
403 new_array.resize (new_elt_ownership, base::_parameter);
404 old_numbering.resize (new_elt_ownership, numeric_limits<size_type>::max());
405 new_numbering.resize (ownership(), numeric_limits<size_type>::max());
406 iter_part = partition.begin();
409 for (
size_type ie = 0, ne = partition.size(); ie < ne; ie++, iter_part++, iter_elt++, iter_new_num_elt++) {
412 size_type new_global_ie = new_elt_ownership[iproc] + send_local_elt_start[iproc];
413 new_array.dis_entry (new_global_ie) = x;
414 *iter_new_num_elt = new_global_ie;
415 size_type old_global_ie = ownership()[my_proc] + ie;
416 old_numbering.dis_entry (new_global_ie) = old_global_ie;
417 send_local_elt_start[iproc]++;
419 new_array.dis_entry_assembly();
420 old_numbering.template dis_entry_assembly<typename default_set_op<size_type>::type>();
424 #endif // _RHEOLEF_HAVE_MPI