30 template<
typename KEY,
typename VAL,
typename IT>
34 MPI_Comm_size(comm, &nprocs);
35 MPI_Comm_rank(comm, &myrank);
36 int nsize = nprocs / 2;
39 bool excluded =
false;
40 if(dist[myrank] == 0) excluded =
true;
43 for(
int i=0; i< nprocs; ++i)
44 if(dist[i] != 0) ++nreals;
48 long * dist_in =
new long[nprocs];
49 for(
int i=0; i< nprocs; ++i) dist_in[i] = (
long) dist[i];
55 long * dist_in =
new long[nreals];
56 int * dist_out =
new int[nprocs-nreals];
59 for(
int i=0; i< nprocs; ++i)
62 dist_out[indout++] = i;
64 dist_in[indin++] = (long) dist[i];
69 outs <<
"To exclude indices: ";
70 copy(dist_out, dist_out+indout, ostream_iterator<int>(outs,
" ")); outs << endl;
74 MPI_Group sort_group, real_group;
75 MPI_Comm_group(comm, &sort_group);
76 MPI_Group_excl(sort_group, indout, dist_out, &real_group);
77 MPI_Group_free(&sort_group);
83 MPI_Comm_create(comm, real_group, &real_comm);
87 MPI_Comm_free(&real_comm);
89 MPI_Group_free(&real_group);
96 IT gl_median = accumulate(dist, dist+nsize, static_cast<IT>(0));
97 sort(array, array+length);
98 int color = (myrank < nsize)? 0: 1;
100 pair<KEY,VAL> * low = array;
101 pair<KEY,VAL> * upp = array;
105 if(color == 1) dist = dist + nsize;
111 MPI_Comm_split(comm, color, myrank, &halfcomm);
116 template<
typename KEY,
typename VAL,
typename IT>
117 void SpParHelper::GlobalSelect(IT gl_rank, pair<KEY,VAL> * & low, pair<KEY,VAL> * & upp, pair<KEY,VAL> * array, IT length,
const MPI_Comm & comm)
120 MPI_Comm_size(comm, &nprocs);
121 MPI_Comm_rank(comm, &myrank);
124 pair<KEY, double> * wmminput =
new pair<KEY,double>[nprocs];
126 MPI_Datatype MPI_sortType;
127 MPI_Type_contiguous (
sizeof(pair<KEY,double>), MPI_CHAR, &MPI_sortType);
128 MPI_Type_commit (&MPI_sortType);
132 IT active = end-begin;
142 begin0 = begin; end0 = end;
143 KEY
median = array[(begin + end)/2].first;
144 wmminput[myrank].first =
median;
145 wmminput[myrank].second =
static_cast<double>(active);
146 MPI_Allgather(MPI_IN_PLACE, 0, MPI_sortType, wmminput, 1, MPI_sortType, comm);
148 for(
int i=0; i<nprocs; ++i)
149 totact += wmminput[i].second;
154 for(
int i=0; i<nprocs; ++i)
155 wmminput[i].second /= totact ;
157 sort(wmminput, wmminput+nprocs);
158 double totweight = 0;
160 while( wmmloc<nprocs && totweight < 0.5 )
162 totweight += wmminput[wmmloc++].second;
165 wmm = wmminput[wmmloc-1].first;
167 pair<KEY,VAL> wmmpair = make_pair(wmm, VAL());
168 low =lower_bound (array+begin, array+end, wmmpair);
169 upp =upper_bound (array+begin, array+end, wmmpair);
170 IT loc_low = low-array;
171 IT loc_upp = upp-array;
173 MPI_Allreduce( &loc_low, &gl_low, 1, MPIType<IT>(), MPI_SUM, comm);
174 MPI_Allreduce( &loc_upp, &gl_upp, 1, MPIType<IT>(), MPI_SUM, comm);
179 begin = (low - array);
181 else if(gl_rank < gl_low)
191 MPI_Allreduce(&active, &nacts, 1, MPIType<IT>(), MPI_SUM, comm);
192 if (begin0 == begin && end0 == end)
break;
194 while((nacts > 2*nprocs) && (!found));
197 MPI_Datatype MPI_pairType;
198 MPI_Type_contiguous (
sizeof(pair<KEY,VAL>), MPI_CHAR, &MPI_pairType);
199 MPI_Type_commit (&MPI_pairType);
201 int * nactives =
new int[nprocs];
202 nactives[myrank] =
static_cast<int>(active);
203 MPI_Allgather(MPI_IN_PLACE, 0, MPI_INT, nactives, 1, MPI_INT, comm);
204 int * dpls =
new int[nprocs]();
205 partial_sum(nactives, nactives+nprocs-1, dpls+1);
206 pair<KEY,VAL> * recvbuf =
new pair<KEY,VAL>[nacts];
208 MPI_Allgatherv(low, active, MPI_pairType, recvbuf, nactives, dpls, MPI_pairType, comm);
210 pair<KEY,int> * allactives =
new pair<KEY,int>[nacts];
212 for(
int i=0; i<nprocs; ++i)
214 for(
int j=0; j<nactives[i]; ++j)
216 allactives[k] = make_pair(recvbuf[k].first, i);
221 sort(allactives, allactives+nacts);
222 MPI_Allreduce(&begin, &gl_low, 1, MPIType<IT>(), MPI_SUM, comm);
223 int diff = gl_rank - gl_low;
224 for(
int k=0; k < diff; ++k)
226 if(allactives[k].second == myrank)
229 delete [] allactives;
231 MPI_Allreduce(&begin, &gl_low, 1, MPIType<IT>(), MPI_SUM, comm);
234 template<
typename KEY,
typename VAL,
typename IT>
238 MPI_Comm_size(comm, &nprocs);
239 MPI_Comm_rank(comm, &myrank);
241 IT * firsthalves =
new IT[nprocs];
242 IT * secondhalves =
new IT[nprocs];
243 firsthalves[myrank] = low-array;
244 secondhalves[myrank] = length - (low-array);
246 MPI_Allgather(MPI_IN_PLACE, 0, MPIType<IT>(), firsthalves, 1, MPIType<IT>(), comm);
247 MPI_Allgather(MPI_IN_PLACE, 0, MPIType<IT>(), secondhalves, 1, MPIType<IT>(), comm);
249 int * sendcnt =
new int[nprocs]();
252 pair<KEY,VAL> * bufbegin = NULL;
256 totrecvcnt = length - (low-array);
257 IT beg_oftransfer = accumulate(secondhalves, secondhalves+myrank, static_cast<IT>(0));
258 IT spaceafter = firsthalves[nfirsthalf];
260 while(i < nprocs && spaceafter < beg_oftransfer)
262 spaceafter += firsthalves[i++];
264 IT end_oftransfer = beg_oftransfer + secondhalves[myrank];
265 IT beg_pour = beg_oftransfer;
266 IT end_pour = min(end_oftransfer, spaceafter);
267 sendcnt[i-1] = end_pour - beg_pour;
268 while( i < nprocs && spaceafter < end_oftransfer )
271 spaceafter += firsthalves[i];
272 end_pour = min(end_oftransfer, spaceafter);
273 sendcnt[i++] = end_pour - beg_pour;
279 totrecvcnt = low-array;
281 IT beg_oftransfer = accumulate(firsthalves+nfirsthalf, firsthalves+myrank, static_cast<IT>(0));
282 IT spaceafter = secondhalves[0];
284 while( i< nfirsthalf && spaceafter < beg_oftransfer)
287 spaceafter += secondhalves[i++];
289 IT end_oftransfer = beg_oftransfer + firsthalves[myrank];
290 IT beg_pour = beg_oftransfer;
291 IT end_pour = min(end_oftransfer, spaceafter);
292 sendcnt[i-1] = end_pour - beg_pour;
293 while( i < nfirsthalf && spaceafter < end_oftransfer )
296 spaceafter += secondhalves[i];
297 end_pour = min(end_oftransfer, spaceafter);
298 sendcnt[i++] = end_pour - beg_pour;
302 int * recvcnt =
new int[nprocs];
303 MPI_Alltoall(sendcnt, 1, MPI_INT, recvcnt, 1, MPI_INT, comm);
311 MPI_Datatype MPI_valueType;
312 MPI_Type_contiguous(
sizeof(pair<KEY,VAL>), MPI_CHAR, &MPI_valueType);
313 MPI_Type_commit(&MPI_valueType);
315 pair<KEY,VAL> * receives =
new pair<KEY,VAL>[totrecvcnt];
316 int * sdpls =
new int[nprocs]();
317 int * rdpls =
new int[nprocs]();
318 partial_sum(sendcnt, sendcnt+nprocs-1, sdpls+1);
319 partial_sum(recvcnt, recvcnt+nprocs-1, rdpls+1);
321 MPI_Alltoallv(bufbegin, sendcnt, sdpls, MPI_valueType, receives, recvcnt, rdpls, MPI_valueType, comm);
323 DeleteAll(sendcnt, recvcnt, sdpls, rdpls);
324 copy(receives, receives+totrecvcnt, bufbegin);
329 template<
typename KEY,
typename VAL,
typename IT>
333 MPI_Comm_rank(World, &rank);
334 MPI_Comm_size(World, &nprocs);
336 MPI_File_open(World,
"temp_sortedkeys", MPI_MODE_CREATE | MPI_MODE_WRONLY, MPI_INFO_NULL, &thefile);
341 IT sizeuntil = accumulate(dist, dist+rank, static_cast<IT>(0));
343 MPI_Offset disp = sizeuntil *
sizeof(KEY);
344 MPI_File_set_view(thefile, disp, MPIType<KEY>(), MPIType<KEY>(),
"native", MPI_INFO_NULL);
346 KEY * packed =
new KEY[length];
347 for(
int i=0; i<length; ++i)
349 packed[i] = array[i].first;
351 MPI_File_write(thefile, packed, length, MPIType<KEY>(), NULL);
352 MPI_File_close(&thefile);
358 FILE * f = fopen(
"temp_sortedkeys",
"r");
361 cerr <<
"Problem reading binary input file\n";
364 IT maxd = *max_element(dist, dist+nprocs);
365 KEY * data =
new KEY[maxd];
367 for(
int i=0; i<nprocs; ++i)
370 fread(data,
sizeof(KEY), dist[i],f);
372 cout <<
"Elements stored on proc " << i <<
": " << endl;
373 copy(data, data+dist[i], ostream_iterator<KEY>(cout,
"\n"));
387 template <
class IT,
class NT,
class DER>
393 assert( (arrwin.size() == arrinfo.
totalsize()));
400 for(
int i=0; i< arrinfo.
indarrs.size(); ++i)
403 MPI_Get( arrinfo.
indarrs[i].addr, arrinfo.
indarrs[i].count, MPIType<IT>(), ownind, 0, arrinfo.
indarrs[i].count, MPIType<IT>(), arrwin[essk++]);
405 for(
int i=0; i< arrinfo.
numarrs.size(); ++i)
408 MPI_Get(arrinfo.
numarrs[i].addr, arrinfo.
numarrs[i].count, MPIType<NT>(), ownind, 0, arrinfo.
numarrs[i].count, MPIType<NT>(), arrwin[essk++]);
418 template<
typename IT,
typename NT,
typename DER>
422 MPI_Comm_rank(comm1d, &myrank);
425 Matrix.
Create(essentials);
429 for(
unsigned int i=0; i< arrinfo.
indarrs.size(); ++i)
431 MPI_Bcast(arrinfo.
indarrs[i].addr, arrinfo.
indarrs[i].count, MPIType<IT>(), root, comm1d);
433 for(
unsigned int i=0; i< arrinfo.
numarrs.size(); ++i)
435 MPI_Bcast(arrinfo.
numarrs[i].addr, arrinfo.
numarrs[i].count, MPIType<NT>(), root, comm1d);
440 template <
class IT,
class NT,
class DER>
449 for(
int i=0; i< arrs.
indarrs.size(); ++i)
452 MPI_Win_create(arrs.
indarrs[i].addr,
453 arrs.
indarrs[i].count *
sizeof(IT),
sizeof(IT), MPI_INFO_NULL, comm1d, &nWin);
454 arrwin.push_back(nWin);
456 for(
int i=0; i< arrs.
numarrs.size(); ++i)
459 MPI_Win_create(arrs.
numarrs[i].addr,
460 arrs.
numarrs[i].count *
sizeof(NT),
sizeof(NT), MPI_INFO_NULL, comm1d, &nWin);
461 arrwin.push_back(nWin);
467 for(
unsigned int i=0; i< arrwin.size(); ++i)
469 MPI_Win_lock(MPI_LOCK_SHARED, ownind, 0, arrwin[i]);
475 for(
unsigned int i=0; i< arrwin.size(); ++i)
477 MPI_Win_unlock( ownind, arrwin[i]);
490 acc_ranks[0] = owner;
492 MPI_Group_incl(group, 1, acc_ranks, &access);
496 for(
unsigned int i=0; i< arrwin.size(); ++i)
497 MPI_Win_start(access, 0, arrwin[i]);
499 MPI_Group_free(&access);
508 for(
unsigned int i=0; i< arrwin.size(); ++i)
509 MPI_Win_post(group, MPI_MODE_NOPUT, arrwin[i]);
512 template <
class IT,
class DER>
517 vector<IT> ess(DER::esscount);
518 for(
int j=0; j< DER::esscount; ++j)
519 ess[j] = sizes[j][owner];
525 template <
class IT,
class DER>
530 vector<IT> ess(DER::esscount);
531 for(
int j=0; j< DER::esscount; ++j)
532 ess[j] = sizes[j][owner];
543 template <
class IT,
class NT,
class DER>
548 MPI_Comm_rank(comm1d, &index);
550 for(IT i=0; (unsigned)i < essentials.size(); ++i)
552 sizes[i][index] = essentials[i];
553 MPI_Allgather(MPI_IN_PLACE, 1, MPIType<IT>(), sizes[i], 1, MPIType<IT>(), comm1d);
561 MPI_Comm_rank(MPI_COMM_WORLD, &myrank);
573 for(
unsigned int i=0; i< arrwin.size(); ++i)
575 MPI_Win_wait(arrwin[i]);
582 for(
unsigned int i=0; i< arrwin.size(); ++i)
584 MPI_Win_free(&arrwin[i]);