23 for (
int i = 0; i < from->
nrecvs; i++) {
50 #define PRINT_VECTOR(v) \
51 if(v != Teuchos::null) { \
52 std::cout << " " << #v << " "; \
53 for(Teuchos::ArrayRCP<int>::size_type n = 0; n < v.size(); ++n) { \
54 std::cout << v[n] << " "; \
56 std::cout << std::endl; \
59 #define PRINT_VAL(val) std::cout << " " << #val << ": " << val << std::endl;
61 for(
int proc = 0; proc <
comm->getSize(); ++proc) {
63 if(proc ==
comm->getRank()) {
65 std::cout <<
"Rank " << proc <<
" " << headerMessage << std::endl;
98 const Teuchos::ArrayRCP<int> &assign,
99 Teuchos::RCP<
const Teuchos::Comm<int> > comm,
104 if (comm == Teuchos::null){
105 throw std::logic_error(
"Invalid communicator: MPI_COMM_NULL.");
108 int my_proc = comm->getRank();
109 int nprocs = comm->getSize();
116 Teuchos::ArrayRCP<int> starts(
new int[nprocs + 1], 0, nprocs + 1,
true);
117 for(
int n = 0; n < starts.size(); ++n) {
126 int no_send_buff = 1;
128 int prev_proc = nprocs;
130 for (
int i = 0; i < nvals; i++) {
131 int proc = assign[i];
132 if (no_send_buff && proc != prev_proc) {
133 if (proc >= 0 && (starts[proc] || prev_proc < 0)) {
146 int self_msg = (starts[my_proc] != 0);
148 Teuchos::ArrayRCP<int> lengths_to;
149 Teuchos::ArrayRCP<int> procs_to;
150 Teuchos::ArrayRCP<int> starts_to;
151 Teuchos::ArrayRCP<int> indices_to;
153 int max_send_size = 0;
160 for (
int i = 0; i < nprocs; i++) {
161 if (starts[i] != 0) ++nsends;
164 lengths_to.resize(nsends);
165 starts_to.resize(nsends);
166 procs_to.resize(nsends);
170 for (
int i = 0; i < nsends; i++) {
171 starts_to[i] = index;
172 int proc = assign[index];
174 index += starts[proc];
180 sort_ints(procs_to, starts_to);
183 for (
int i = 0; i < nsends; i++) {
184 int proc = procs_to[i];
185 lengths_to[i] = starts[proc];
186 if (proc != my_proc && lengths_to[i] > max_send_size) {
187 max_send_size = lengths_to[i];
193 nsends = (starts[0] != 0);
194 for (
int i = 1; i < nprocs; i++) {
197 starts[i] += starts[i - 1];
200 for (
int i = nprocs - 1; i; i--) {
201 starts[i] = starts[i - 1];
206 indices_to = (nactive > 0) ?
207 Teuchos::arcp(
new int[nactive], 0, nactive,
true) : Teuchos::null;
209 for (
int i = 0; i < nvals; i++) {
210 int proc = assign[i];
212 indices_to[starts[proc]] = i;
219 for (
int i = nprocs - 1; i; i--) {
220 starts[i] = starts[i - 1];
223 starts[nprocs] = nactive;
227 lengths_to.resize(nsends);
228 starts_to.resize(nsends);
229 procs_to.resize(nsends);
233 for (
int i = 0; i < nprocs; i++) {
234 if (starts[i + 1] != starts[i]) {
235 starts_to[j] = starts[i];
236 lengths_to[j] = starts[i + 1] - starts[i];
237 if (i != my_proc && lengths_to[j] > max_send_size) {
238 max_send_size = lengths_to[j];
250 Teuchos::ArrayRCP<int> lengths_from;
251 Teuchos::ArrayRCP<int> procs_from;
254 int comm_flag = invert_map(lengths_to, procs_to, nsends, self_msg,
255 lengths_from, procs_from, &nrecvs, my_proc, nprocs,
256 out_of_mem, tag, comm);
259 Teuchos::ArrayRCP<int> starts_from(
260 new int[nrecvs + self_msg], 0, nrecvs + self_msg,
true);
262 for (
int i = 0; i < nrecvs + self_msg; i++) {
264 j += lengths_from[i];
267 if (comm_flag != 0) {
268 throw std::logic_error(
"Failed to construct Zoltan2_Directory_Comm");
271 int total_recv_size = 0;
272 for (
int i = 0; i < nrecvs + self_msg; i++) {
273 total_recv_size += lengths_from[i];
284 plan_forward->
nvals = nvals;
286 plan_forward->
nrecvs = nrecvs;
287 plan_forward->
nsends = nsends;
292 plan_forward->
comm = comm;
296 throw std::logic_error(
"Zoltan2_Directory_Comm.coom untested refactored code (1)");
303 Teuchos::reduceAll(*comm, Teuchos::REDUCE_MAX, 1, &nrecvs, &global_nrecvs);
314 nrec = total_recv_size;
322 int Zoltan2_Directory_Comm::invert_map(
323 const Teuchos::ArrayRCP<int> &lengths_to,
324 const Teuchos::ArrayRCP<int> &procs_to,
327 Teuchos::ArrayRCP<int> &lengths_from,
328 Teuchos::ArrayRCP<int> &procs_from,
334 Teuchos::RCP<
const Teuchos::Comm<int> > comm)
336 Teuchos::ArrayRCP<int> msg_count(
new int[nprocs], 0, nprocs,
true);
337 Teuchos::ArrayRCP<int> counts(
new int[nprocs], 0, nprocs,
true);
338 for(
int i = 0; i < nprocs; ++i) {
343 for (
int i = 0; i < nsends + self_msg; i++) {
344 msg_count[procs_to[i]] = 1;
357 Teuchos::reduceAll<int>(*comm, Teuchos::REDUCE_SUM, nprocs,
358 msg_count.getRawPtr(), counts.getRawPtr());
362 Teuchos::scatter<int, int>(&(counts[0]), 1, &nrecvs, 1, 0, *comm);
366 for (
int i=0; i < nprocs; i++) {
367 if (counts[i] > max_nrecvs) {
368 max_nrecvs = counts[i];
373 Teuchos::broadcast(*comm, 0, &max_nrecvs);
376 lengths_from.resize(nrecvs);
377 procs_from.resize(nrecvs);
382 Teuchos::ArrayRCP<Teuchos::RCP<Teuchos::CommRequest<int> > > requests(nrecvs);
386 for (
int i=0; i < nrecvs; i++) {
387 #ifdef HAVE_MPI // Teuchos::ireceive not implemented for Serial - Serial is just for debugging
388 Teuchos::ArrayRCP<int> single_elem(&lengths_from[i], 0, 1,
false);
389 requests[i] = Teuchos::ireceive(single_elem, MPI_ANY_SOURCE, tag, *comm);
393 for (
int i=0; i < nsends+self_msg; i++) {
394 #ifdef HAVE_MPI // Teuchos::send not implemented for Serial - Serial is just for debugging
395 Teuchos::send(&lengths_to[i], 1, procs_to[i], tag, *comm);
399 for (
int i=0; i < nrecvs; i++) {
401 procs_from[i] = requests[i]->wait()->getSourceRank();
405 lengths_from[i] = lengths_to[i];
411 Teuchos::ArrayRCP<int> sendbuf(
new int[nprocs], 0, nprocs,
true);
412 Teuchos::ArrayRCP<int> recvbuf(
new int[nprocs], 0, nprocs,
true);
414 for (
int i=0; i < nsends + self_msg; i++) {
415 sendbuf[procs_to[i]] = lengths_to[i];
418 throw std::logic_error(
"Zoltan2_Directory_Comm.coom untested refactored code (2)");
422 for (
int i=0, j=0; i < nprocs; i++) {
424 lengths_from[j] = recvbuf[i];
434 sort_ints(procs_from, lengths_from);
436 *pnrecvs = nrecvs - self_msg;
441 int Zoltan2_Directory_Comm::sort_ints(
442 Teuchos::ArrayRCP<int> &vals_sort,
443 Teuchos::ArrayRCP<int> &vals_other)
446 if (vals_sort == Teuchos::null || vals_sort.size() == 0) {
449 if (vals_other == Teuchos::null || vals_other.size() == 0) {
452 if (vals_sort == Teuchos::null || vals_sort.size() == 1) {
457 int already_sorted = 1;
460 int top = vals_sort[0];
461 for (Teuchos::ArrayRCP<int>::size_type i = 1; i < vals_sort.size(); i++) {
462 if (vals_sort[i-1] > vals_sort[i]) {
465 if (top < vals_sort[i]) {
470 if (already_sorted) {
474 Teuchos::ArrayRCP<int> store(
new int[top+2], 0, top+2,
true);
475 for(
int n = 0; n < store.size(); ++n) {
479 Teuchos::ArrayRCP<int> copy_sort(
new int[vals_sort.size()], 0, vals_sort.size(),
true);
480 for(Teuchos::ArrayRCP<int>::size_type n = 0; n < copy_sort.size(); ++n) {
481 copy_sort[n] = vals_sort[n];
484 Teuchos::ArrayRCP<int> copy_other(
new int[vals_other.size()], 0, vals_other.size(),
true);
485 for(Teuchos::ArrayRCP<int>::size_type n = 0; n < copy_other.size(); ++n) {
486 copy_other[n] = vals_other[n];
491 int *p = &(store[1]);
492 for (Teuchos::ArrayRCP<int>::size_type i = 0; i < vals_sort.size(); i++) {
496 for (
int i = 1; i < top+1; i++) {
501 for (Teuchos::ArrayRCP<int>::size_type i = 0; i < vals_sort.size(); i++) {
502 vals_sort[p[copy_sort[i]]] = copy_sort[i];
503 vals_other[p[copy_sort[i]]] = copy_other[i];
512 const Teuchos::ArrayRCP<char> &send_data,
514 Teuchos::ArrayRCP<char> &recv_data)
519 status = do_post (plan_forward, tag, send_data, nbytes, recv_data);
521 status = do_wait (plan_forward, tag, send_data, nbytes, recv_data);
525 status = do_all_to_all(plan_forward, send_data, nbytes, recv_data);
531 int Zoltan2_Directory_Comm::do_post(
534 const Teuchos::ArrayRCP<char> &send_data,
536 Teuchos::ArrayRCP<char> &recv_data)
540 throw std::logic_error(
"Communication plan = NULL");
545 throw std::logic_error(
"Zoltan2_Directory_Comm.coom untested refactored code (3)");
546 return do_all_to_all(plan, send_data, nbytes, recv_data);
549 int my_proc = plan->
comm->getRank();
551 throw std::logic_error(
"Zoltan2_Directory_Comm.coom untested refactored code (4)");
559 throw std::logic_error(
"nsends not zero, but send_data = NULL");
562 if ((plan->
nrecvs + plan->
self_msg) && recv_data == Teuchos::null) {
563 throw std::logic_error(
"Zoltan2_Directory_Comm.coom untested refactored code (5)");
569 throw std::logic_error(
"nrecvs not zero, but recv_data = NULL");
580 plan->
recv_buff = Teuchos::arcp(
new char[rsize], 0, rsize,
true);
583 size_t self_recv_address = 0;
588 Teuchos::ArrayRCP<char> subview(
595 self_recv_address = (size_t)(plan->
starts_from[i]) * (size_t)nbytes;
604 Teuchos::ArrayRCP<char> subview(
611 plan->
request[k] = Teuchos::null;
622 Teuchos::ArrayRCP<char> send_buff;
636 int global_out_of_mem;
637 Teuchos::reduceAll(*plan->
comm, Teuchos::REDUCE_SUM, 1, &out_of_mem,
647 while (proc_index < nblocks && plan->procs_to[proc_index] < my_proc) {
650 if (proc_index == nblocks) {
657 for (
int i = proc_index, j = 0; j < nblocks; j++) {
659 Teuchos::ArrayRCP<char> subview(
662 Teuchos::readySend(subview.getRawPtr(),
static_cast<int>(subview.size()), plan->
procs_to[i], tag, *comm_);
667 if (++i == nblocks) {
681 send_data.getRawPtr()+(size_t)(plan->
starts_to[self_num])*(size_t)nbytes,
682 (
size_t) (plan->
lengths_to[self_num]) * (
size_t) nbytes);
688 for (
int i = proc_index, jj = 0; jj < nblocks; jj++) {
693 for (
int k = 0; k < plan->
lengths_to[i]; k++) {
694 memcpy(&send_buff[offset],
695 &send_data[(
size_t)(plan->
indices_to[j++]) * (
size_t)nbytes], nbytes);
698 Teuchos::readySend(&send_buff[0], plan->
lengths_to[i] * nbytes,
710 for (
int k = 0; k < plan->
lengths_to[self_num]; k++) {
713 (
size_t)(plan->
indices_to[self_index++]) * (
size_t)nbytes],
715 self_recv_address += nbytes;
723 for (
int i = proc_index, j = 0; j < nblocks; j++) {
738 char* lrecv = &plan->
getRecvBuff().getRawPtr()[self_recv_address];
740 &send_data.getRawPtr()[(size_t)(plan->
starts_to_ptr[self_num]) * (size_t)nbytes];
741 int sindex = plan->
sizes_to[self_num], idx;
742 for (idx=0; idx<nbytes; idx++) {
743 memcpy(lrecv, lsend, sindex);
752 for (
int i = proc_index, jj = 0; jj < nblocks; jj++) {
756 for (
int k = 0; k < plan->
lengths_to[i]; k++) {
758 memcpy(&send_buff[offset],
767 Teuchos::readySend(&send_buff[0], plan->
sizes_to[i] * nbytes,
780 for (
int k = 0; k < plan->
lengths_to[self_num]; k++) {
782 char* lrecv = &(plan->
getRecvBuff())[self_recv_address];
783 size_t send_idx = (size_t)kk * (
size_t)nbytes;
784 const char* lsend = &send_data[send_idx];
786 for (idx=0; idx<nbytes; idx++) {
787 memcpy(lrecv, lsend, sindex);
803 int Zoltan2_Directory_Comm::do_wait(
804 Zoltan2_Directory_Plan *plan,
806 const Teuchos::ArrayRCP<char> &,
808 Teuchos::ArrayRCP<char> &recv_data)
811 if (plan->maxed_recvs){
816 int my_proc = plan->comm->getRank();
820 if (plan->indices_from == Teuchos::null) {
821 if (plan->nrecvs > 0) {
822 Teuchos::waitAll(*comm_, plan->request());
827 size_t offsetDst = 0;
828 if (plan->self_msg) {
829 for (self_num = 0; self_num < plan->nrecvs + plan->self_msg;
831 if (plan->procs_from[self_num] == my_proc) {
836 if(plan->sizes_from.size()) {
843 memcpy(&recv_data[offsetDst * (
size_t)nbytes],
844 &(plan->getRecvBuff())[plan->starts_from_ptr[self_num] * (
size_t)nbytes],
845 plan->sizes_from[self_num] * (size_t)nbytes);
846 offsetDst += plan->sizes_from[self_num];
849 int k = plan->starts_from[self_num];
850 for (
int j = plan->lengths_from[self_num]; j; j--) {
851 memcpy(&recv_data[(
size_t)(plan->indices_from[k]) * (
size_t)nbytes],
852 &(plan->getRecvBuff())[(
size_t)k * (
size_t)nbytes], nbytes);
858 self_num = plan->nrecvs;
861 for (
int jj = 0; jj < plan->nrecvs; jj++) {
866 plan->request[jj]->wait();
874 if (index >= self_num) {
878 if(plan->sizes_from.size()) {
885 memcpy(&recv_data[offsetDst * (
size_t)nbytes],
886 &plan->getRecvBuff().getRawPtr()[plan->starts_from_ptr[index] * (size_t)nbytes],
887 plan->sizes_from[index] * (
size_t)nbytes);
888 offsetDst += plan->sizes_from[index];
891 int k = plan->starts_from[index];
892 for (
int j = plan->lengths_from[index]; j; j--) {
893 memcpy(&recv_data.getRawPtr()[(size_t)(plan->indices_from[k]) * (size_t)nbytes],
894 &plan->getRecvBuff().getRawPtr()[(size_t)k * (
size_t)nbytes], nbytes);
909 int Zoltan2_Directory_Comm::do_all_to_all(
910 Zoltan2_Directory_Plan *plan,
911 const Teuchos::ArrayRCP<char> &send_data,
913 Teuchos::ArrayRCP<char> &recv_data)
915 throw std::logic_error(
"Zoltan2_Directory_Comm.coom untested refactored code (6)");
917 int sm = (plan->self_msg > 0) ? 1 : 0;
919 int nSendMsgs = plan->nsends + sm;
920 int nRecvMsgs = plan->nrecvs + sm;
923 for (
int i=0; i <nSendMsgs; i++) {
924 nSendItems += plan->lengths_to[i];
927 for (
int i=0; i <nRecvMsgs; i++) {
928 nRecvItems += plan->lengths_from[i];
931 int nprocs = plan->comm->getSize();
933 Teuchos::ArrayRCP<int> outbufCounts(
new int[nprocs], 0, nprocs,
true);
934 Teuchos::ArrayRCP<int> outbufOffsets(
new int[nprocs], 0, nprocs,
true);
935 Teuchos::ArrayRCP<int> inbufCounts(
new int[nprocs], 0, nprocs,
true);
936 Teuchos::ArrayRCP<int> inbufOffsets(
new int[nprocs], 0, nprocs,
true);
948 if (plan->indices_to == Teuchos::null){
950 for (
int i=1; i< nSendMsgs; i++){
951 if (plan->starts_to[i] < plan->starts_to[i-1]){
958 Teuchos::ArrayRCP<char> outbuf;
959 Teuchos::ArrayRCP<char> inbuf;
960 Teuchos::ArrayRCP<char> buf;
962 if (plan->sizes_to.size()){
969 for (
int i = 0; i < nSendMsgs; i++){
970 outbufLen += plan->sizes_to[i];
973 if (plan->indices_to != Teuchos::null) {
977 buf.resize(outbufLen*nbytes);
978 outbuf.resize(outbufLen*nbytes);
979 char * pBufPtr = &(outbuf[0]);
982 for (
int p = 0; p < nprocs; p++) {
987 if (plan->procs_to[i] == p){
989 for (
int j=0; j < plan->lengths_to[i]; j++,k++){
990 int itemSize = plan->sizes[plan->indices_to[k]] * nbytes;
991 int offset = plan->indices_to_ptr[k] * nbytes;
993 memcpy(pBufPtr, &(send_data[0]) + offset, itemSize);
1002 outbufCounts[p] = length;
1004 outbufOffsets[p] = outbufOffsets[p-1] + outbufCounts[p-1];
1013 if (!sorted || (plan->nvals > nSendItems) ){
1014 buf.resize(outbufLen*nbytes);
1015 outbuf.resize(outbufLen*nbytes);
1022 for(
int n = 0; n < outbufLen*nbytes; ++n) {
1023 outbuf[n] = send_data[n];
1027 char * pBufPtr = &(outbuf[0]);
1030 for (
int p = 0; p < nprocs; p++) {
1035 if (plan->procs_to[i] == p){
1036 length = plan->sizes_to[i] * nbytes;
1037 int offset = plan->starts_to_ptr[i] * nbytes;
1039 if ((!sorted || (plan->nvals > nSendItems)) && length){
1040 memcpy(pBufPtr, &(send_data[0]) + offset, length);
1047 outbufCounts[p] = length;
1049 outbufOffsets[p] = outbufOffsets[p-1] + outbufCounts[p-1];
1054 else if (plan->indices_to != Teuchos::null) {
1059 buf.resize(nSendItems*nbytes);
1060 outbuf.resize(nSendItems*nbytes);
1061 char * pBufPtr = &(outbuf[0]);
1064 for (
int p = 0; p < nprocs; p++){
1069 if (plan->procs_to[i] == p){
1070 for (
int j=0; j < plan->lengths_to[i]; j++,k++) {
1071 int offset = plan->indices_to[k] * nbytes;
1072 memcpy(pBufPtr, &(send_data[0]) + offset, nbytes);
1075 length = plan->lengths_to[i] * nbytes;
1080 outbufCounts[p] = length;
1082 outbufOffsets[p] = outbufOffsets[p-1] + outbufCounts[p-1];
1092 if (!sorted || (plan->nvals > nSendItems)){
1093 buf.resize(nSendItems*nbytes);
1094 outbuf.resize(nSendItems*nbytes);
1105 char * pBufPtr = &(outbuf[0]);
1108 for (
int p=0; p < nprocs; p++) {
1113 if (plan->procs_to[i] == p){
1114 int offset = plan->starts_to[i] * nbytes;
1115 length = plan->lengths_to[i] * nbytes;
1117 if ((!sorted || (plan->nvals > nSendItems)) && length){
1118 memcpy(pBufPtr, &(send_data[0]) + offset, length);
1125 outbufCounts[p] = length;
1127 outbufOffsets[p] = outbufOffsets[p-1] + outbufCounts[p-1];
1136 if (plan->indices_from == Teuchos::null) {
1138 for (i=1; i< nRecvMsgs; i++) {
1139 if (plan->starts_from[i] < plan->starts_from[i-1]){
1156 inbuf.resize(plan->total_recv_size * nbytes);
1159 for (
int p = 0; p < nprocs; p++) {
1163 if (plan->procs_from[i] == p){
1165 if (!plan->using_sizes){
1166 length = plan->lengths_from[i] * nbytes;
1169 length = plan->sizes_from[i] * nbytes;
1175 inbufCounts[p] = length;
1177 inbufOffsets[p] = inbufOffsets[p-1] + inbufCounts[p-1];
1190 char * pBufPtr = &(inbuf[0]);
1192 if (!plan->using_sizes){
1196 if (plan->indices_from == Teuchos::null) {
1197 for (i=0; i < nRecvMsgs; i++){
1198 int offset = plan->starts_from[i] * nbytes;
1199 int length = plan->lengths_from[i] * nbytes;
1200 memcpy(&(recv_data[0]) + offset, pBufPtr, length);
1206 for (i=0; i < nRecvMsgs; i++) {
1208 for (
int j=0; j < plan->lengths_from[i]; j++,k++){
1209 int offset = plan->indices_from[k] * nbytes;
1210 memcpy(&(recv_data[0]) + offset, pBufPtr, nbytes);
1220 for (i=0; i < nRecvMsgs; i++){
1221 int offset = plan->starts_from_ptr[i] * nbytes;
1222 int length = plan->sizes_from[i] * nbytes;
1223 memcpy(&(recv_data[0]) + offset, pBufPtr, length);
1234 const Teuchos::ArrayRCP<char> &send_data,
1236 const Teuchos::ArrayRCP<int> &sizes,
1237 Teuchos::ArrayRCP<char> &recv_data)
1241 int status = create_reverse_plan(tag, sizes);
1252 recv_data = Teuchos::arcp(
new char[new_size], 0, new_size,
true);
1259 throw std::logic_error(
"Zoltan2_Directory_Comm.coom untested refactored code (7)");
1265 status = do_all_to_all(plan_forward->
plan_reverse, send_data,
1271 status = do_post(plan_forward->
plan_reverse, tag, send_data,
1275 status = do_wait (plan_forward->
plan_reverse, tag, send_data,
1281 free_reverse_plan(plan_forward);
1289 throw std::logic_error(
"Plan is NULL!");
1295 int Zoltan2_Directory_Comm::create_reverse_plan(
1297 const Teuchos::ArrayRCP<int> &sizes)
1301 throw std::logic_error(
"memory error");
1305 plan_forward->
plan_reverse =
new Zoltan2_Directory_Plan;
1314 Teuchos::reduceAll<int>(*plan_forward->
comm, Teuchos::REDUCE_SUM, 1,
1315 &plan_forward->
nsends, &global_nsends);
1330 sizes, tag, &sum_recv_sizes);
1332 if (comm_flag != 0) {
1345 const Teuchos::ArrayRCP<int> &sizes,
1347 int *sum_recv_sizes)
1349 return resize(plan_forward, sizes, tag, sum_recv_sizes);
1354 const Teuchos::ArrayRCP<int> &sizes,
1356 int *sum_recv_sizes)
1360 int my_proc = plan->
comm->getRank();
1361 int has_sizes = (sizes.size() != 0);
1364 Teuchos::reduceAll(*comm_, Teuchos::REDUCE_BOR, 1, &has_sizes, &var_sizes);
1366 if (var_sizes && plan->
indices_from != Teuchos::null) {
1373 int nsends = plan->
nsends;
1374 int nrecvs = plan->
nrecvs;
1377 Teuchos::ArrayRCP<int> sizes_to;
1378 Teuchos::ArrayRCP<int> sizes_from;
1379 Teuchos::ArrayRCP<int> starts_to_ptr;
1380 Teuchos::ArrayRCP<int> starts_from_ptr;
1381 Teuchos::ArrayRCP<int> indices_to_ptr;
1382 Teuchos::ArrayRCP<int> indices_from_ptr;
1386 for (
int i = 0; i < nrecvs + self_msg; i++) {
1391 for (
int i = 0; i < nsends + self_msg; i++) {
1392 if (plan->
procs_to[i] != my_proc &&
1409 plan->
sizes = sizes;
1412 if(nsends + self_msg > 0) {
1413 sizes_to = Teuchos::arcp(
1414 new int[nsends + self_msg], 0, nsends + self_msg,
true);
1415 for(
int n = 0; n < sizes_to.size(); ++n) {
1419 if(nrecvs + self_msg > 0) {
1420 sizes_from = Teuchos::arcp(
1421 new int[nrecvs + self_msg], 0, nrecvs + self_msg,
true);
1431 if(nsends + self_msg > 0) {
1432 starts_to_ptr = Teuchos::arcp(
1433 new int[nsends + self_msg], 0, nsends + self_msg,
true);
1437 Teuchos::ArrayRCP<int> index;
1438 Teuchos::ArrayRCP<int> sort_val;
1439 if(nsends + self_msg > 0) {
1440 index = Teuchos::arcp(
1441 new int[nsends + self_msg], 0, nsends + self_msg,
true);
1442 sort_val = Teuchos::arcp(
1443 new int[nsends + self_msg], 0, nsends + self_msg,
true);
1445 for (
int i = 0; i < nsends + self_msg; i++) {
1448 for (
int k = 0; k < plan->
lengths_to[i]; k++) {
1449 sizes_to[i] += sizes[j++];
1455 for (
int i = 0; i < nsends + self_msg; i++) {
1459 sort_ints(sort_val, index);
1461 for (
int i = 0; i < nsends + self_msg; i++) {
1462 starts_to_ptr[index[i]] = sum;
1463 sum += sizes_to[index[i]];
1467 Teuchos::ArrayRCP<int> offset;
1468 if(plan->
nvals > 0) {
1469 offset = Teuchos::arcp(
new int[plan->
nvals], 0, plan->
nvals,
true);
1471 indices_to_ptr.resize(plan->
nvals);
1475 for (
int i = 0; i < plan->
nvals; i++) {
1482 for (
int i = 0; i < nsends + self_msg; i++) {
1483 starts_to_ptr[i] = sum;
1485 for (
int k = 0; k < plan->
lengths_to[i]; k++) {
1486 indices_to_ptr[j] = offset[plan->
indices_to[j]];
1499 exchange_sizes(sizes_to, plan->
procs_to, nsends, self_msg,
1503 if(nrecvs + self_msg > 0) {
1504 starts_from_ptr = Teuchos::arcp(
1505 new int[nrecvs + self_msg], 0, nrecvs + self_msg,
true);
1510 Teuchos::ArrayRCP<int> index;
1511 Teuchos::ArrayRCP<int> sort_val;
1512 if(nrecvs + self_msg > 0) {
1513 index = Teuchos::arcp(
1514 new int[nrecvs + self_msg], 0, nrecvs + self_msg,
true);
1515 sort_val = Teuchos::arcp<int>(
1516 new int[nrecvs + self_msg], 0, nrecvs + self_msg,
true);
1519 for (
int i = 0; i < nrecvs + self_msg; i++) {
1523 sort_ints(sort_val, index);
1526 for (
int i = 0; i < nrecvs + self_msg; i++) {
1527 starts_from_ptr[index[i]] = sum;
1528 sum += sizes_from[index[i]];
1548 Teuchos::ArrayRCP<int> index;
1549 Teuchos::ArrayRCP<int> sort_val;
1550 if(nrecvs + self_msg > 0) {
1551 index = Teuchos::arcp(
1552 new int[nrecvs + self_msg], 0, nrecvs + self_msg,
true);
1553 sort_val = Teuchos::arcp(
1554 new int[nrecvs + self_msg], 0, nrecvs + self_msg,
true);
1557 for (
int i = 0; i < nrecvs + self_msg; i++) {
1561 sort_ints(sort_val, index);
1564 for (
int i = 0; i < nrecvs + self_msg; i++) {
1565 starts_from_ptr[index[i]] = sum;
1566 sum += sizes_from[index[i]];
1577 if (sum_recv_sizes) {
1584 int Zoltan2_Directory_Comm::exchange_sizes(
1585 const Teuchos::ArrayRCP<int> &sizes_to,
1586 const Teuchos::ArrayRCP<int> &procs_to,
1589 Teuchos::ArrayRCP<int> &sizes_from,
1590 const Teuchos::ArrayRCP<int> &procs_from,
1592 int *total_recv_size,
1595 Teuchos::RCP<
const Teuchos::Comm<int> > ) {
1598 int self_index_to = -1;
1599 for (
int i = 0; i < nsends + self_msg; i++) {
1600 if (procs_to[i] != my_proc) {
1601 #ifdef HAVE_MPI // Teuchos::send not implemented for Serial - Serial is just for debugging
1602 Teuchos::send(*comm_, 1, &sizes_to[i], procs_to[i]);
1610 *total_recv_size = 0;
1612 for (
int i = 0; i < nrecvs + self_msg; i++) {
1613 if (procs_from[i] != my_proc) {
1614 #ifdef HAVE_MPI // Teuchos::receive not implemented for Serial - Serial is just for debugging
1615 Teuchos::receive(*comm_, procs_from[i], 1, &sizes_from[i]);
1619 sizes_from[i] = sizes_to[self_index_to];
1621 *total_recv_size += sizes_from[i];
Teuchos::ArrayRCP< int > procs_from
Teuchos::ArrayRCP< int > indices_to
Teuchos::ArrayRCP< int > lengths_to
Teuchos::ArrayRCP< char > recv_buff
Teuchos::ArrayRCP< int > indices_from_ptr
Teuchos::ArrayRCP< int > starts_from
void print(const std::string &headerMessage) const
Teuchos::ArrayRCP< int > procs_to
int do_reverse(int tag, const Teuchos::ArrayRCP< char > &send_data, int nbytes, const Teuchos::ArrayRCP< int > &sizes, Teuchos::ArrayRCP< char > &recv_data)
Teuchos::ArrayRCP< char > getRecvBuff() const
~Zoltan2_Directory_Comm()
Teuchos::ArrayRCP< int > starts_to
Teuchos::ArrayRCP< int > indices_to_ptr
Teuchos::ArrayRCP< int > indices_from
Teuchos::ArrayRCP< int > starts_from_ptr
Teuchos::ArrayRCP< int > sizes_from
Teuchos::ArrayRCP< int > sizes_to
int do_forward(int tag, const Teuchos::ArrayRCP< char > &send_data, int nbytes, Teuchos::ArrayRCP< char > &recv_data)
Teuchos::ArrayRCP< Teuchos::RCP< Teuchos::CommRequest< int > > > request
int resize(const Teuchos::ArrayRCP< int > &sizes, int tag, int *sum_recv_sizes)
Teuchos::ArrayRCP< int > lengths_from
Teuchos::ArrayRCP< int > sizes
Zoltan2_Directory_Plan * plan_reverse
Teuchos::RCP< const Teuchos::Comm< int > > comm
Zoltan2_Directory_Comm(int nvals, const Teuchos::ArrayRCP< int > &assign, Teuchos::RCP< const Teuchos::Comm< int > > comm, int tag)
Teuchos::ArrayRCP< int > starts_to_ptr
void getInvertedValues(Zoltan2_Directory_Plan *from)