76 SizeRandomIterator1 idx,
78 SizeRandomIterator2 idy,
80 SizeRandomIterator3 ownership,
94 std::vector<size_type> msg_size(nproc, 0);
95 std::vector<size_type> msg_mark(nproc, 0);
96 std::vector<size_type> owner (nidx);
101 for (; iproc < nproc; iproc++) {
102 if (idx[i] >= ownership[iproc] && idx[i] < ownership[iproc+1]) {
105 if (!msg_mark[iproc]) {
112 check_macro (iproc != nproc,
"bad stash data: idx["<<i<<
"]="<<idx[i]<<
" out of range [0:"<<ownership[nproc]<<
"[");
120 msg_size [my_proc] = 0;
121 msg_mark [my_proc] = 0;
127 std::vector<size_type> work(nproc);
130 msg_mark.begin().operator->(),
132 work.begin().operator->(),
133 std::plus<size_type>());
134 size_type receive_nproc = work [my_proc];
140 msg_size.begin().operator->(),
142 work.begin().operator->(),
143 mpi::maximum<size_type>());
144 size_type receive_max_size = work [my_proc];
148 std::list<std::pair<size_type,mpi::request> > receive_waits;
149 std::vector<size_type> receive_data (receive_nproc*receive_max_size);
150 for (
size_type i_receive = 0; i_receive < receive_nproc; i_receive++) {
151 mpi::request i_req = comm.irecv (
154 receive_data.begin().operator->() + i_receive*receive_max_size,
156 receive_waits.push_back (std::make_pair(i_receive, i_req));
163 std::vector<size_type> send_data (nidx);
164 std::copy (idx, idx+nidx, send_data.begin());
168 std::list<std::pair<size_type,mpi::request> > send_waits;
172 for (
size_type iproc = 0; iproc < nproc; iproc++) {
174 if (i_msg_size == 0)
continue;
175 mpi::request i_req = comm.isend (
178 send_data.begin().operator->() + i_start,
180 send_waits.push_back(std::make_pair(i_send,i_req));
182 i_start += i_msg_size;
191 typedef boost::transform_iterator<select2nd<size_t,mpi::request>, std::list<std::pair<size_t,mpi::request> >::iterator>
193 std::vector<size_type> receive_size (receive_nproc);
194 std::vector<size_type> receive_proc (receive_nproc);
196 while (receive_waits.size() != 0) {
201 std::pair<mpi::status,request_iterator> pair_status = mpi::wait_any (iter_r_waits, last_r_waits);
203 boost::optional<int> i_msg_size_opt = pair_status.first.count<data_type>();
204 check_macro (i_msg_size_opt,
"receive wait failed");
205 int iproc = pair_status.first.source();
206 check_macro (iproc >= 0,
"receive: source iproc = "<<iproc<<
" < 0 !");
208 size_type i_msg_size = (size_t)i_msg_size_opt.get();
209 std::list<std::pair<size_t,mpi::request> >::iterator i_pair_ptr = pair_status.second.base();
210 size_type i_receive = (*i_pair_ptr).first;
211 receive_proc [i_receive] = iproc;
212 receive_size [i_receive] = i_msg_size;
213 receive_total_size += i_msg_size;
214 receive_waits.erase (i_pair_ptr);
219 to.resize (receive_total_size, receive_nproc);
225 std::vector<size_type> perm(receive_nproc);
228 receive_proc.begin().operator->(),
229 perm.begin().operator->(),
238 receive_proc.begin(),
239 receive_size.begin(),
240 receive_data.begin(),
245 to.indices().begin());
249 from.resize(nidy, send_nproc);
253 std::vector<size_type> proc2from_proc(nproc);
257 from.procs().begin(),
258 from.starts().begin(),
259 proc2from_proc.begin());
264 std::vector<size_type> start(send_nproc+1);
265 copy (from.starts().begin(), from.starts().end(), start.begin());
270 proc2from_proc.begin(),
274 from.indices().begin());
278 if (send_waits.size() != 0) {
281 mpi::wait_all (iter_s_waits, last_s_waits);
287 from.local_slots.resize(n_local);
288 to.local_slots.resize(n_local);
297 to.local_slots.begin(),
298 to.local_slots.end(),
299 from.local_slots.begin());
304 to.local_slots.begin(),
305 to.local_slots.end(),
306 from.local_slots.begin());
308 if (has_opt && n_local != 0) {
309 to.local_is_copy =
true;
310 to.local_copy_start = to.local_slots[0];
311 to.local_copy_length = n_local;
312 from.local_is_copy =
true;
313 from.local_copy_start = from.local_slots[0];
314 from.local_copy_length = n_local;