23 #ifndef PSORT_ALLTOALL_H 24 #define PSORT_ALLTOALL_H 31 template <
typename _RandomAccessIter,
typename _ValueType,
typename _Distance>
32 static void alltoall (vector< vector<_Distance> > &right_ends,
33 _RandomAccessIter first,
34 _RandomAccessIter last,
35 _ValueType *trans_data,
36 _Distance *boundaries,
37 MPI_Datatype &MPI_valueType,
38 MPI_Datatype &MPI_distanceType,
42 MPI_Comm_size (comm, &nproc);
43 MPI_Comm_rank (comm, &rank);
46 char errMsg[] =
"32-bit limit for MPI has overflowed";
47 _Distance n_loc_ = last - first;
48 if (n_loc_ > INT_MAX)
throw std::overflow_error(errMsg);
49 int n_loc =
static_cast<int> (n_loc_);
52 int *send_counts =
new int[nproc];
53 int *send_disps =
new int[nproc];
54 for (
int i = 0; i < nproc; ++i) {
55 _Distance scount = right_ends[i + 1][
rank] - right_ends[i][
rank];
56 if (scount > INT_MAX)
throw std::overflow_error(errMsg);
57 send_counts[i] =
static_cast<int> (scount);
60 partial_sum (send_counts, send_counts + nproc - 1, send_disps + 1);
62 int *recv_counts =
new int[nproc];
63 int *recv_disps =
new int[nproc];
64 for (
int i = 0; i < nproc; ++i) {
65 _Distance rcount = right_ends[rank + 1][i] - right_ends[
rank][i];
66 if (rcount > INT_MAX)
throw std::overflow_error(errMsg);
67 recv_counts[i] =
static_cast<int> (rcount);
71 partial_sum (recv_counts, recv_counts + nproc - 1, recv_disps + 1);
73 assert (accumulate (recv_counts, recv_counts + nproc, 0) == n_loc);
76 MPI_Alltoallv (first, send_counts, send_disps, MPI_valueType,
77 trans_data, recv_counts, recv_disps, MPI_valueType, comm);
79 for (
int i=0; i<nproc; ++i) boundaries[i] = (_Distance) recv_disps[i];
80 boundaries[nproc] = (_Distance) n_loc;
82 delete [] recv_counts;
85 delete [] send_counts;