11 #ifndef _SORT_UTILS_H_ 12 #define _SORT_UTILS_H_ 16 #define PARAM_UNUSED(x) x __attribute__ ((unused)) 18 #define PARAM_UNUSED(x) x 24 template<
class S,
class Comparator>
36 return (
less(data[a], data[b])
38 : (
less(data[b], data[a])
46 template<
class S,
class Comparator>
58 return (
less(data[b], data[a])
60 : (
less(data[a], data[b])
68 template<
class InIt,
class Comparator>
78 inline bool operator () (
const unsigned& a,
const unsigned& b)
80 return (
less(*(data[a]), *(data[b]))
82 : (
less(*(data[b]), *(data[a]))
90 template<
class InIt,
class Comparator>
102 return (
less(*(data[b]), *(data[a]))
104 : (
less(*(data[a]), *(data[b]))
114 #define MPI_INDEX_TYPE MPI_LONG_LONG_INT 115 #define MPI_KEY_TYPE MPI_UNSIGNED_LONG_LONG 124 SortComm( MPI_Comm a_comm ) : m_comm(a_comm)
126 MPI_Comm_size(a_comm,&m_numpes);
127 MPI_Comm_rank(a_comm,&m_mype);
136 std::string sort_format_pe_number(
int i)
138 std::ostringstream ss;
140 ss << std::setw(4) << i;
147 static std::string sort_format_iam(
const SortComm* env)
149 return sort_format_pe_number(env->m_mype) +
": ";
154 std::ostream& sort_pe_out(
const SortComm* env)
156 return std::cout << sort_format_iam(env);
159 std::ostream& sort_pe_err(
const SortComm* env)
161 return std::cerr << sort_format_iam(env) <<
"ERROR: ";
164 std::ostream& sort_nullstream()
166 static std::ostream rc(NULL);
171 std::ostream& sort_root_out(
const SortComm* env)
173 return (env->m_mype == 0) ? sort_pe_out(env) : sort_nullstream();
176 std::ostream& sort_root_err(
const SortComm* env)
178 return (env->m_mype == 0) ? sort_pe_err(env) : sort_nullstream();
183 void sort_pe_msg(
const SortComm* env,
const std::string msg)
185 sort_pe_out(env) << msg << std::endl;
188 void sort_root_msg(
const SortComm* env,
const std::string msg)
190 sort_root_out(env) << msg << std::endl;
193 PE_NUM pe_right(PE_NUM
id,
const SortComm* env)
195 return (
id + 1) % env->m_numpes;
198 PE_NUM pe_left(PE_NUM
id,
const SortComm* env)
200 return (
id - 1 + env->m_numpes) % env->m_numpes;
206 TAG_ALLTOALLV_MANUAL=10001
208 , TAG_EXTERNAL_ALLTOALL=10002
217 TAG_SHIFT_RIGHT_DONE=10009,
218 TAG_START_SHIFT_LEFT=10010
222 , TAG_LEFT_MAX=10012,
227 , TAG_PART_DIST=10015
233 struct MultiwaySelectResult
245 : m_lborder(a_lborder)
247 m_sdispl =
new int[a_env->m_numpes + 1];
248 m_scount =
new int[a_env->m_numpes];
249 m_rcount =
new int[a_env->m_numpes];
250 m_rdispl =
new int[a_env->m_numpes];
251 const int P = a_env->m_numpes;
253 int *lborder=
new int[P];
254 for (
int ii=0;ii<P; ii++)
257 lborder[ii] = a_lborder[ii];
260 MPI_Alltoall( lborder, 1, MPI_INT,
261 m_sdispl, 1, MPI_INT, a_env->m_comm );
268 for (
int ii = 0; ii < P; ++ii)
270 m_scount[ii] = m_sdispl[ii + 1] - m_sdispl[ii];
274 MPI_Alltoall(m_scount, 1, MPI_INT,
275 m_rcount, 1, MPI_INT, a_env->m_comm);
279 for (
int ii = 1; ii < P; ++ii)
281 m_rdispl[ii] = m_rdispl[ii - 1] + m_rcount[ii - 1];
287 MultiwaySelectResult(
int* a_sdisp,
291 m_scount =
new int[env->m_numpes];
292 m_rcount =
new int[env->m_numpes];
293 m_rdispl =
new int[env->m_numpes];
300 std::cout <<
"\t[" << env->m_mype <<
"]MultiwaySelectResult m_sdispl = " << m_sdispl[0] <<
" " << m_sdispl[1] <<
" " << m_sdispl[2] <<
" " << m_sdispl[3] <<
" " << m_sdispl[4] << std::endl;
302 for (
int i = 0; i < env->m_numpes; ++i)
304 m_scount[i] = m_sdispl[i + 1] - m_sdispl[i];
308 MPI_Alltoall(m_scount, 1, MPI_INT,
309 m_rcount, 1, MPI_INT, env->m_comm);
311 std::cout <<
"\t[" << env->m_mype <<
"]MultiwaySelectResult m_rcount = " << m_rcount[0] <<
" " << m_rcount[1] <<
" " << m_rcount[2] <<
" " << m_rcount[3] << std::endl;
314 for (
int i = 1; i < env->m_numpes; ++i)
316 m_rdispl[i] = m_rdispl[i - 1] + m_rcount[i - 1];
318 MPI_Barrier(env->m_comm);
319 std::cout <<
"\t[" << env->m_mype <<
"]MultiwaySelectResult m_rdispl = " << m_rdispl[0] <<
" " << m_rdispl[1] <<
" " << m_rdispl[2] <<
" " << m_rdispl[3] << std::endl;
322 ~MultiwaySelectResult()
334 template<
typename block_type,
typename value_type,
class Comparator>
335 void test_multiway_select(value_type*
data,
337 MultiwaySelectResult* msr,
350 MPI_Allgather(msr->m_lborder, env->m_numpes, MPI_INDEX_TYPE,
351 lborder_global, env->m_numpes, MPI_INDEX_TYPE,
356 MPI_Gather(msr->m_sdispl, env->m_numpes, MPI_INDEX_TYPE,
357 sdispl_global, env->m_numpes, MPI_INDEX_TYPE,
361 MPI_Gather(msr->m_rdispl, env->m_numpes, MPI_INDEX_TYPE,
362 rdispl_global, env->m_numpes, MPI_INDEX_TYPE,
366 MPI_Gather(msr->m_scount, env->m_numpes, MPI_INDEX_TYPE,
367 scount_global, env->m_numpes, MPI_INDEX_TYPE,
371 MPI_Gather(msr->m_rcount, env->m_numpes, MPI_INDEX_TYPE,
372 rcount_global, env->m_numpes, MPI_INDEX_TYPE,
378 MPI_Gather(&length, 1, MPI_INDEX_TYPE,
379 rlen, 1, MPI_INDEX_TYPE,
383 if (env->m_mype == 0)
387 std::cout <<
"lborder = " << std::endl;
391 for (
int r = 0; r < env->m_numpes; ++r)
395 for (
int i = 0; i < env->m_numpes; ++i)
397 std::cout << std::setw(11) << lborder_global[r * env->m_numpes + i];
399 tsum += lborder_global[r * env->m_numpes + i];
402 std::cout <<
", sum = " << tsum
403 <<
" is " << (tsum == rsum ?
"okay" :
"WRONG")
406 err += (tsum == rsum) ? 0 : 1;
413 std::cout <<
"scount = " << std::endl;
415 for (
int r = 0; r < env->m_numpes; ++r)
419 for (
int i = 0; i < env->m_numpes; ++i)
421 std::cout << std::setw(11) << scount_global[r * env->m_numpes + i];
423 tsum += scount_global[r * env->m_numpes + i];
426 std::cout <<
", sum = " << tsum
427 <<
" is " << (tsum == rlen[r] ?
"okay" :
"WRONG")
430 err += (tsum == rlen[r]) ? 0 : 1;
436 std::cout <<
"rcount = " << std::endl;
438 for (
int r = 0; r < env->m_numpes; ++r)
442 for (
int i = 0; i < env->m_numpes; ++i)
444 std::cout << std::setw(11) << rcount_global[r * env->m_numpes + i];
446 tsum += rcount_global[r * env->m_numpes + i];
449 std::cout <<
", sum = " << tsum
450 <<
" is " << (tsum == rlen[r] ?
"okay" :
"WRONG")
453 err += (tsum == rlen[r]) ? 0 : 1;
458 std::cout <<
"sdispl = " << std::endl;
460 for (
int r = 0; r < env->m_numpes; ++r)
462 err += (sdispl_global[r * env->m_numpes + 0] == 0) ? 0 : 1;
464 std::cout << std::setw(11) << sdispl_global[r * env->m_numpes + 0];
468 for (
int i = 1; i < env->m_numpes; ++i)
470 std::cout << std::setw(11) << sdispl_global[r * env->m_numpes + i];
472 asc &= (sdispl_global[r * env->m_numpes + i]
473 >= sdispl_global[r * env->m_numpes + i - 1]
477 std::cout <<
", ascending: " << (asc ?
"okay" :
"WRONG") << std::endl;
485 std::cout <<
"rdispl = " << std::endl;
487 for (
int r = 0; r < env->m_numpes; ++r)
489 err += (rdispl_global[r * env->m_numpes + 0] == 0) ? 0 : 1;
491 std::cout << std::setw(11) << rdispl_global[r * env->m_numpes + 0];
495 for (
int i = 1; i < env->m_numpes; ++i)
497 std::cout << std::setw(11) << rdispl_global[r * env->m_numpes + i];
499 asc &= (rdispl_global[r * env->m_numpes + i]
500 >= rdispl_global[r * env->m_numpes + i - 1]
504 std::cout <<
", ascending: " << (asc ?
"okay" :
"WRONG") << std::endl;
512 sort_pe_out(env) <<
"msr local errors: " << err << std::endl;
516 MPI_Reduce(&err, &serr, 1, MPI_UNSIGNED, MPI_SUM, 0, env->m_comm);
520 sort_root_out(env) <<
"msr local error sum: " << err << std::endl;
524 value_type* blval =
new value_type[env->m_numpes * env->m_numpes];
525 value_type* brval =
new value_type[env->m_numpes * env->m_numpes];
527 for (
int r = 0; r < env->m_numpes; ++r)
529 if (lborder_global[r * env->m_numpes + env->m_mype] < length)
531 value_type val =
data[lborder_global[r * env->m_numpes + env->m_mype]];
532 blval[env->m_mype * env->m_numpes + r] = val;
536 blval[env->m_mype * env->m_numpes + r] =
less.max_value();
539 if (lborder_global[r * env->m_numpes + env->m_mype] - 1 < 0)
541 brval[env->m_mype * env->m_numpes + r] =
less.min_value();
545 value_type val =
data[lborder_global[r * env->m_numpes + env->m_mype] - 1];
546 brval[env->m_mype * env->m_numpes + r] = val;
550 MPI_Datatype mpi_value_type;
551 MPI_Type_contiguous(
sizeof(value_type), MPI_BYTE, &mpi_value_type);
552 MPI_Type_commit(&mpi_value_type);
554 MPI_Gather(&blval[env->m_mype * env->m_numpes], env->m_numpes, mpi_value_type,
555 blval, env->m_numpes, mpi_value_type,
558 MPI_Gather(&brval[env->m_mype * env->m_numpes], env->m_numpes, mpi_value_type,
559 brval, env->m_numpes, mpi_value_type,
563 MPI_Type_free(const_cast<MPI_Datatype*>(&mpi_value_type));
565 if (env->m_mype == 0)
567 value_type* vmin =
new value_type[env->m_numpes];
568 value_type* vmax =
new value_type[env->m_numpes];
570 std::cout <<
"blval = " << std::endl;
572 for (
int r = 0; r < env->m_numpes; ++r)
574 vmin[r] =
less.max_value();
576 for (
int k = 0; k < env->m_numpes; ++k)
578 std::cout << blval[k * env->m_numpes + r];
580 if (
less(blval[k * env->m_numpes + r], vmin[r]))
582 vmin[r] = blval[k * env->m_numpes + r];
585 std::cout <<
" => min[" << sort_format_pe_number(r) <<
"] = " << vmin[r] << std::endl;
588 std::cout <<
"brval = " << std::endl;
590 for (
int r = 0; r < env->m_numpes; ++r)
592 vmax[r] =
less.min_value();
594 for (
int k = 0; k < env->m_numpes; ++k)
596 std::cout << brval[k * env->m_numpes + r];
598 if (
less(vmax[r], brval[k * env->m_numpes + r]))
600 vmax[r] = brval[k * env->m_numpes + r];
603 std::cout <<
" => max[" << sort_format_pe_number(r - 1) <<
"] = " << vmax[r] << std::endl;
606 for (
int r = 0; r < env->m_numpes - 1; ++r)
608 std::cout <<
"max[" << sort_format_pe_number(r) <<
"] <= " 609 <<
"min[" << sort_format_pe_number(r + 1) <<
"] iff " 610 << vmax[r + 1] <<
" <= " 611 << vmin[r + 1] <<
": " 612 << (
less(vmin[r + 1], vmax[r + 1]) ?
"WRONG" :
"okay") << std::endl;
614 err +=
less(vmin[r + 1], vmax[r + 1]) ? 1 : 0;
617 sort_pe_out(env) <<
"msr global error count: " << err << std::endl;
621 sort_pe_msg(env,
"* msr is ERRONEOUS");
626 sort_pe_msg(env,
"* msr looks GOOD");
635 delete[] lborder_global;
636 delete[] sdispl_global;
637 delete[] rdispl_global;
638 delete[] scount_global;
639 delete[] rcount_global;
647 #endif // SORT_UTILS_H IndirectIndirectInvertedLess(InIt *data, Comparator &less)
Definition: sort_utils.H:96
S * data
Definition: sort_utils.H:27
#define CH_assert(cond)
Definition: CHArray.H:37
Definition: sort_utils.H:69
Comparator & less
Definition: sort_utils.H:50
InIt * data
Definition: sort_utils.H:71
Comparator & less
Definition: sort_utils.H:28
IndirectInvertedLess(S *data, Comparator &less)
Definition: sort_utils.H:52
IndirectIndirectLess(InIt *data, Comparator &less)
Definition: sort_utils.H:74
Comparator & less
Definition: sort_utils.H:72
InIt * data
Definition: sort_utils.H:93
Definition: sort_utils.H:91
Definition: sort_utils.H:47
Comparator & less
Definition: sort_utils.H:94
bool operator()(const index_type &a, const index_type &b)
Definition: sort_utils.H:34
Definition: sort_utils.H:25
long long index_type
Definition: sort_utils.H:22
S * data
Definition: sort_utils.H:49
IndirectLess(S *data, Comparator &less)
Definition: sort_utils.H:30
unsigned long long key_type
Definition: sort_utils.H:21