43
43
MPID_Comm *comm_ptr,
46
if(comm_ptr->rank == 0)
47
TRACE_ERR("Entering MPIDO_Alltoallv\n");
46
#ifndef HAVE_PAMI_IN_PLACE
47
if (sendbuf == MPI_IN_PLACE)
49
MPID_Abort (NULL, 0, 1, "'MPI_IN_PLACE' requries support for `PAMI_IN_PLACE`");
53
TRACE_ERR("Entering MPIDO_Alltoallv\n");
48
54
volatile unsigned active = 1;
49
int sndtypelen, rcvtypelen, snd_contig, rcv_contig;
55
void *snd_noncontig_buff = NULL, *rcv_noncontig_buff = NULL;
56
void *sbuf = NULL, *rbuf = NULL;
57
int recvok=PAMI_SUCCESS, sendok=PAMI_SUCCESS;
58
int sndtypelen, rcvtypelen, snd_contig=0, rcv_contig=0;
50
59
MPID_Datatype *sdt, *rdt;
51
60
pami_type_t stype, rtype;
52
61
MPI_Aint sdt_true_lb, rdt_true_lb;
53
62
MPIDI_Post_coll_t alltoallv_post;
57
if(sendbuf == MPI_IN_PLACE)
58
pamidt = 0; /* Disable until ticket #632 is fixed */
59
if(MPIDI_Datatype_to_pami(sendtype, &stype, -1, NULL, &tmp) != MPI_SUCCESS)
61
if(MPIDI_Datatype_to_pami(recvtype, &rtype, -1, NULL, &tmp) != MPI_SUCCESS)
65
(comm_ptr->mpid.user_selected_type[PAMI_XFER_ALLTOALLV_INT] ==
66
MPID_COLL_USE_MPICH) ||
65
const int rank = comm_ptr->rank;
67
/* We can't afford the tracing in ndebug/performance libraries */
68
const unsigned verbose = 0;
70
const unsigned verbose = (MPIDI_Process.verbose >= MPIDI_VERBOSE_DETAILS_ALL) && (rank == 0);
72
const struct MPIDI_Comm* const mpid = &(comm_ptr->mpid);
73
const int selected_type = mpid->user_selected_type[PAMI_XFER_ALLTOALLV_INT];
74
const int size = comm_ptr->local_size;
75
int sendcontinuous , recvcontinuous=0;
76
size_t recv_size=0, send_size=0;
77
size_t totalrecvcount=0;
78
int *lrecvdispls = NULL; /* possible local displs calculated for noncontinous */
79
int *lsenddispls = NULL;/* possible local displs calculated for noncontinous */
80
int *lrecvcounts = NULL;/* possible local counts calculated for noncontinous */
81
int *lsendcounts = NULL;/* possible local counts calculated for noncontinous */
82
const int *precvdispls = recvdispls; /* pointer to displs to use as pami parmi */
83
const int *psenddispls = senddispls; /* pointer to displs to use as pami parmi */
84
const int *precvcounts = recvcounts; /* pointer to counts to use as pami parmi */
85
const int *psendcounts = sendcounts; /* pointer to counts to use as pami parmi */
86
int inplace = sendbuf == MPI_IN_PLACE? 1 : 0;
87
if(selected_type == MPID_COLL_USE_MPICH)
69
if(unlikely(MPIDI_Process.verbose >= MPIDI_VERBOSE_DETAILS_ALL && comm_ptr->rank == 0))
70
90
fprintf(stderr,"Using MPICH alltoallv algorithm\n");
72
TRACE_ERR("Using MPICH alltoallv\n");
73
91
return MPIR_Alltoallv(sendbuf, sendcounts, senddispls, sendtype,
74
92
recvbuf, recvcounts, recvdispls, recvtype,
75
93
comm_ptr, mpierrno);
78
TRACE_ERR("Using %s for alltoallv protocol\n", pname);
98
sendok = MPIDI_Datatype_to_pami(sendtype, &stype, -1, NULL, &tmp);
99
MPIDI_Datatype_get_info(1, sendtype, snd_contig, sndtypelen, sdt, sdt_true_lb);
100
sbuf = (char *)sendbuf + sdt_true_lb;
101
if(!snd_contig || (sendok != PAMI_SUCCESS))
103
stype = PAMI_TYPE_UNSIGNED_CHAR;
104
size_t totalsendcount = sendcounts[0];
105
sendcontinuous = senddispls[0] == 0? 1 : 0 ;
107
psenddispls = lsenddispls = MPIU_Malloc(size*sizeof(int));
108
psendcounts = lsendcounts = MPIU_Malloc(size*sizeof(int));
110
lsendcounts[0]= sndtypelen * sendcounts[0];
111
for(i=1; i<size; ++i)
113
lsenddispls[i]= sndtypelen * totalsendcount;
114
totalsendcount += sendcounts[i];
115
if(senddispls[i] != (senddispls[i-1] + (sendcounts[i-1]*sndtypelen)))
117
lsendcounts[i]= sndtypelen * sendcounts[i];
119
send_size = sndtypelen * totalsendcount;
120
TRACE_ERR("Pack receive sndv_contig %zu, sendok %zd, totalsendcount %zu, sendcontinuous %zu, sndtypelen %zu, send_size %zu\n",
121
(size_t)snd_contig, (size_t)sendok, (size_t)totalsendcount, (size_t)sendcontinuous, (size_t) sndtypelen, (size_t)send_size);
122
snd_noncontig_buff = MPIU_Malloc(send_size);
123
sbuf = snd_noncontig_buff;
124
if(snd_noncontig_buff == NULL)
126
MPID_Abort(NULL, MPI_ERR_NO_SPACE, 1,
127
"Fatal: Cannot allocate pack buffer");
131
MPIR_Localcopy(sendbuf, totalsendcount, sendtype,
132
snd_noncontig_buff, send_size,MPI_CHAR);
137
MPID_Datatype_get_extent_macro(sendtype,extent);
138
for(i=0; i<size; ++i)
140
char* scbuf = (char*)sendbuf + senddispls[i]*extent;
141
char* rcbuf = (char*)snd_noncontig_buff + psenddispls[i];
142
MPIR_Localcopy(scbuf, sendcounts[i], sendtype,
143
rcbuf, psendcounts[i], MPI_CHAR);
144
TRACE_ERR("Pack send src extent %zu, displ[%zu]=%zu, count[%zu]=%zu buf[%zu]=%u\n",
145
(size_t)extent, (size_t)i,(size_t)senddispls[i],(size_t)i,(size_t)sendcounts[i],(size_t)senddispls[i], *(int*)scbuf);
146
TRACE_ERR("Pack send dest displ[%zu]=%zu, count[%zu]=%zu buf[%zu]=%u\n",
147
(size_t)i,(size_t)psenddispls[i],(size_t)i,(size_t)psendcounts[i],(size_t)psenddispls[i], *(int*)rcbuf);
80
152
MPIDI_Datatype_get_info(1, recvtype, rcv_contig, rcvtypelen, rdt, rdt_true_lb);
153
recvok = MPIDI_Datatype_to_pami(recvtype, &rtype, -1, NULL, &tmp);
154
rbuf = (char *)recvbuf + rdt_true_lb;
155
if(!rcv_contig || (recvok != PAMI_SUCCESS))
157
rtype = PAMI_TYPE_UNSIGNED_CHAR;
158
totalrecvcount = recvcounts[0];
159
recvcontinuous = recvdispls[0] == 0? 1 : 0 ;
161
precvdispls = lrecvdispls = MPIU_Malloc(size*sizeof(int));
162
precvcounts = lrecvcounts = MPIU_Malloc(size*sizeof(int));
164
lrecvcounts[0]= rcvtypelen * recvcounts[0];
165
for(i=1; i<size; ++i)
167
lrecvdispls[i]= rcvtypelen * totalrecvcount;
168
totalrecvcount += recvcounts[i];
169
if(recvdispls[i] != (recvdispls[i-1] + (recvcounts[i-1]*rcvtypelen)))
171
lrecvcounts[i]= rcvtypelen * recvcounts[i];
173
recv_size = rcvtypelen * totalrecvcount;
174
TRACE_ERR("Pack receive rcv_contig %zu, recvok %zd, totalrecvcount %zu, recvcontinuous %zu, rcvtypelen %zu, recv_size %zu\n",
175
(size_t)rcv_contig, (size_t)recvok, (size_t)totalrecvcount, (size_t)recvcontinuous,(size_t)rcvtypelen, (size_t)recv_size);
176
rcv_noncontig_buff = MPIU_Malloc(recv_size);
177
rbuf = rcv_noncontig_buff;
178
if(rcv_noncontig_buff == NULL)
180
MPID_Abort(NULL, MPI_ERR_NO_SPACE, 1,
181
"Fatal: Cannot allocate pack buffer");
183
/* need to copy it now if it's used for the send buffer and then do not do in place */
187
stype = PAMI_TYPE_UNSIGNED_CHAR;
188
size_t totalsendcount = recvcounts[0];
189
sendcontinuous = recvdispls[0] == 0? 1 : 0 ;
191
psenddispls = lsenddispls = MPIU_Malloc(size*sizeof(int));
192
psendcounts = lsendcounts = MPIU_Malloc(size*sizeof(int));
194
lsendcounts[0]= rcvtypelen * recvcounts[0];
195
for(i=1; i<size; ++i)
197
lsenddispls[i]= rcvtypelen * totalsendcount;
198
totalsendcount += recvcounts[i];
199
if(recvdispls[i] != (recvdispls[i-1] + (recvcounts[i-1]*rcvtypelen)))
201
lsendcounts[i]= rcvtypelen * recvcounts[i];
203
send_size = rcvtypelen * totalsendcount;
204
TRACE_ERR("Pack MPI_IN_PLACE receive sndv_contig %zu, sendok %zd, totalsendcount %zu, sendcontinuous %zu, rcvtypelen %zu, send_size %zu\n",
205
(size_t)snd_contig, (size_t)sendok, (size_t)totalsendcount, (size_t)sendcontinuous, (size_t) rcvtypelen, (size_t)send_size);
206
snd_noncontig_buff = MPIU_Malloc(send_size);
207
sbuf = snd_noncontig_buff;
208
if(snd_noncontig_buff == NULL)
210
MPID_Abort(NULL, MPI_ERR_NO_SPACE, 1,
211
"Fatal: Cannot allocate pack buffer");
215
MPIR_Localcopy(recvbuf, totalsendcount, recvtype,
216
snd_noncontig_buff, send_size,MPI_CHAR);
221
MPID_Datatype_get_extent_macro(recvtype,extent);
222
for(i=0; i<size; ++i)
224
char* scbuf = (char*)recvbuf + recvdispls[i]*extent;
225
char* rcbuf = (char*)snd_noncontig_buff + psenddispls[i];
226
MPIR_Localcopy(scbuf, recvcounts[i], recvtype,
227
rcbuf, psendcounts[i], MPI_CHAR);
228
TRACE_ERR("Pack send src extent %zu, displ[%zu]=%zu, count[%zu]=%zu buf[%zu]=%u\n",
229
(size_t)extent, (size_t)i,(size_t)recvdispls[i],(size_t)i,(size_t)recvcounts[i],(size_t)recvdispls[i], *(int*)scbuf);
230
TRACE_ERR("Pack send dest extent %zu, displ[%zu]=%zu, count[%zu]=%zu buf[%zu]=%u\n",
231
(size_t)extent, (size_t)i,(size_t)psenddispls[i],(size_t)i,(size_t)psendcounts[i],(size_t)psenddispls[i], *(int*)rcbuf);
82
238
pami_xfer_t alltoallv;
83
239
pami_algorithm_t my_alltoallv;
84
pami_metadata_t *my_alltoallv_md;
240
const pami_metadata_t *my_md = (pami_metadata_t *)NULL;
87
if(comm_ptr->mpid.user_selected_type[PAMI_XFER_ALLTOALLV_INT] == MPID_COLL_OPTIMIZED)
243
if(selected_type == MPID_COLL_OPTIMIZED)
89
245
TRACE_ERR("Optimized alltoallv was selected\n");
90
my_alltoallv = comm_ptr->mpid.opt_protocol[PAMI_XFER_ALLTOALLV_INT][0];
91
my_alltoallv_md = &comm_ptr->mpid.opt_protocol_md[PAMI_XFER_ALLTOALLV_INT][0];
92
queryreq = comm_ptr->mpid.must_query[PAMI_XFER_ALLTOALLV_INT][0];
246
my_alltoallv = mpid->opt_protocol[PAMI_XFER_ALLTOALLV_INT][0];
247
my_md = &mpid->opt_protocol_md[PAMI_XFER_ALLTOALLV_INT][0];
248
queryreq = mpid->must_query[PAMI_XFER_ALLTOALLV_INT][0];
95
251
{ /* is this purely an else? or do i need to check for some other selectedvar... */
96
252
TRACE_ERR("Alltoallv specified by user\n");
97
my_alltoallv = comm_ptr->mpid.user_selected[PAMI_XFER_ALLTOALLV_INT];
98
my_alltoallv_md = &comm_ptr->mpid.user_metadata[PAMI_XFER_ALLTOALLV_INT];
99
queryreq = comm_ptr->mpid.user_selected_type[PAMI_XFER_ALLTOALLV_INT];
253
my_alltoallv = mpid->user_selected[PAMI_XFER_ALLTOALLV_INT];
254
my_md = &mpid->user_metadata[PAMI_XFER_ALLTOALLV_INT];
255
queryreq = selected_type;
101
257
alltoallv.algorithm = my_alltoallv;
102
char *pname = my_alltoallv_md->name;
258
char *pname = my_md->name;
105
261
alltoallv.cb_done = cb_alltoallv;
106
262
alltoallv.cookie = (void *)&active;
107
263
/* We won't bother with alltoallv since MPI is always going to be ints. */
108
if(sendbuf == MPI_IN_PLACE)
110
if(unlikely(MPIDI_Process.verbose >= MPIDI_VERBOSE_DETAILS_ALL))
266
if(unlikely(verbose))
111
267
fprintf(stderr,"alltoallv MPI_IN_PLACE buffering\n");
112
268
alltoallv.cmd.xfer_alltoallv_int.stype = rtype;
113
alltoallv.cmd.xfer_alltoallv_int.sdispls = (int *) recvdispls;
114
alltoallv.cmd.xfer_alltoallv_int.stypecounts = (int *) recvcounts;
115
alltoallv.cmd.xfer_alltoallv_int.sndbuf = (char *)recvbuf+rdt_true_lb;
269
alltoallv.cmd.xfer_alltoallv_int.sdispls = (int *) precvdispls;
270
alltoallv.cmd.xfer_alltoallv_int.stypecounts = (int *) precvcounts;
271
alltoallv.cmd.xfer_alltoallv_int.sndbuf = PAMI_IN_PLACE;
119
MPIDI_Datatype_get_info(1, sendtype, snd_contig, sndtypelen, sdt, sdt_true_lb);
120
275
alltoallv.cmd.xfer_alltoallv_int.stype = stype;
121
alltoallv.cmd.xfer_alltoallv_int.sdispls = (int *) senddispls;
122
alltoallv.cmd.xfer_alltoallv_int.stypecounts = (int *) sendcounts;
123
alltoallv.cmd.xfer_alltoallv_int.sndbuf = (char *)sendbuf+sdt_true_lb;
276
alltoallv.cmd.xfer_alltoallv_int.sdispls = (int *) psenddispls;
277
alltoallv.cmd.xfer_alltoallv_int.stypecounts = (int *) psendcounts;
278
alltoallv.cmd.xfer_alltoallv_int.sndbuf = sbuf;
125
alltoallv.cmd.xfer_alltoallv_int.rcvbuf = (char *)recvbuf+rdt_true_lb;
280
alltoallv.cmd.xfer_alltoallv_int.rcvbuf = rbuf;
127
alltoallv.cmd.xfer_alltoallv_int.rdispls = (int *) recvdispls;
128
alltoallv.cmd.xfer_alltoallv_int.rtypecounts = (int *) recvcounts;
282
alltoallv.cmd.xfer_alltoallv_int.rdispls = (int *) precvdispls;
283
alltoallv.cmd.xfer_alltoallv_int.rtypecounts = (int *) precvcounts;
129
284
alltoallv.cmd.xfer_alltoallv_int.rtype = rtype;
131
if(unlikely(queryreq == MPID_COLL_ALWAYS_QUERY || queryreq == MPID_COLL_CHECK_FN_REQUIRED))
286
if(unlikely(queryreq == MPID_COLL_ALWAYS_QUERY ||
287
queryreq == MPID_COLL_CHECK_FN_REQUIRED))
133
289
metadata_result_t result = {0};
134
290
TRACE_ERR("querying alltoallv protocol %s, type was %d\n", pname, queryreq);
135
result = my_alltoallv_md->check_fn(&alltoallv);
291
if(my_md->check_fn == NULL)
293
/* process metadata bits */
294
if((!my_md->check_correct.values.inplace) && (sendbuf == MPI_IN_PLACE))
295
result.check.unspecified = 1;
296
/* Can't check ranges like this. Non-local. Comment out for now.
297
if(my_md->check_correct.values.rangeminmax)
299
MPI_Aint data_true_lb;
300
MPID_Datatype *data_ptr;
301
int data_size, data_contig;
302
MPIDI_Datatype_get_info(??, sendtype, data_contig, data_size, data_ptr, data_true_lb);
303
if((my_md->range_lo <= data_size) &&
304
(my_md->range_hi >= data_size))
308
result.check.range = 1;
309
if(unlikely(verbose))
311
fprintf(stderr,"message size (%u) outside range (%zu<->%zu) for %s.\n",
321
else /* calling the check fn is sufficient */
322
result = my_md->check_fn(&alltoallv);
136
323
TRACE_ERR("bitmask: %#X\n", result.bitmask);
324
result.check.nonlocal = 0; /* #warning REMOVE THIS WHEN IMPLEMENTED */
139
fprintf(stderr,"Query failed for %s\n", pname);
327
if(unlikely(verbose))
328
fprintf(stderr,"Query failed for %s. Using MPICH alltoallv\n", pname);
329
MPIDI_Update_last_algorithm(comm_ptr, "ALLTOALLV_MPICH");
330
return MPIR_Alltoallv(sendbuf, sendcounts, senddispls, sendtype,
331
recvbuf, recvcounts, recvdispls, recvtype,
334
if(my_md->check_correct.values.asyncflowctl && !(--(comm_ptr->mpid.num_requests)))
336
comm_ptr->mpid.num_requests = MPIDI_Process.optimized.num_requests;
338
if(unlikely(verbose))
339
fprintf(stderr,"Query barrier required for %s\n", pname);
340
MPIDO_Barrier(comm_ptr, &tmpmpierrno);
143
if(unlikely(MPIDI_Process.verbose >= MPIDI_VERBOSE_DETAILS_ALL && comm_ptr->rank == 0))
344
if(unlikely(verbose))
145
346
unsigned long long int threadID;
146
347
MPIU_Thread_id_t tid;
148
349
threadID = (unsigned long long int)tid;
149
350
fprintf(stderr,"<%llx> Using protocol %s for alltoallv on %u\n",
151
my_alltoallv_md->name,
152
353
(unsigned) comm_ptr->context_id);
155
356
MPIDI_Context_post(MPIDI_Context[0], &alltoallv_post.state,
156
357
MPIDI_Pami_post_wrapper, (void *)&alltoallv);
158
TRACE_ERR("%d waiting on active %d\n", comm_ptr->rank, active);
359
TRACE_ERR("%d waiting on active %d\n", rank, active);
159
360
MPID_PROGRESS_WAIT_WHILE(active);
362
if(!rcv_contig || (recvok != PAMI_SUCCESS))
366
MPIR_Localcopy(rcv_noncontig_buff, recv_size,MPI_CHAR,
367
recvbuf, totalrecvcount, recvtype);
373
MPID_Datatype_get_extent_macro(recvtype,extent);
374
for(i=0; i<size; ++i)
376
char* scbuf = (char*)rcv_noncontig_buff+ precvdispls[i];
377
char* rcbuf = (char*)recvbuf + recvdispls[i]*extent;
378
MPIR_Localcopy(scbuf, precvcounts[i], MPI_CHAR,
379
rcbuf, recvcounts[i], recvtype);
380
TRACE_ERR("Pack recv src extent %zu, displ[%zu]=%zu, count[%zu]=%zu buf[%zu]=%u\n",
381
(size_t)extent, (size_t)i,(size_t)precvdispls[i],(size_t)i,(size_t)precvcounts[i],(size_t)precvdispls[i], *(int*)scbuf);
382
TRACE_ERR("Pack recv dest extent %zu, displ[%zu]=%zu, count[%zu]=%zu buf[%zu]=%u\n",
383
(size_t)extent, (size_t)i,(size_t)recvdispls[i],(size_t)i,(size_t)recvcounts[i],(size_t)recvdispls[i], *(int*)rcbuf);
386
MPIU_Free(rcv_noncontig_buff);
388
if(!snd_contig || (sendok != PAMI_SUCCESS)) MPIU_Free(snd_noncontig_buff);
389
if(lrecvdispls) MPIU_Free(lrecvdispls);
390
if(lsenddispls) MPIU_Free(lsenddispls);
391
if(lrecvcounts) MPIU_Free(lrecvcounts);
392
if(lsendcounts) MPIU_Free(lsendcounts);
162
394
TRACE_ERR("Leaving alltoallv\n");
401
int MPIDO_Alltoallv_simple(const void *sendbuf,
402
const int *sendcounts,
403
const int *senddispls,
404
MPI_Datatype sendtype,
406
const int *recvcounts,
407
const int *recvdispls,
408
MPI_Datatype recvtype,
412
#ifndef HAVE_PAMI_IN_PLACE
413
if (sendbuf == MPI_IN_PLACE)
415
MPID_Abort (NULL, 0, 1, "'MPI_IN_PLACE' requries support for `PAMI_IN_PLACE`");
419
TRACE_ERR("Entering MPIDO_Alltoallv_optimized\n");
420
volatile unsigned active = 1;
421
int sndtypelen, rcvtypelen, snd_contig = 1, rcv_contig = 1;
422
MPID_Datatype *sdt, *rdt;
423
pami_type_t stype = NULL, rtype;
424
MPI_Aint sdt_true_lb = 0, rdt_true_lb;
425
MPIDI_Post_coll_t alltoallv_post;
426
void *snd_noncontig_buff = NULL, *rcv_noncontig_buff = NULL;
427
void *sbuf = NULL, *rbuf = NULL;
428
int recvok=PAMI_SUCCESS, sendok=PAMI_SUCCESS;
430
const int rank = comm_ptr->rank;
431
const int size = comm_ptr->local_size;
433
int sendcontinuous , recvcontinuous=0;
434
size_t recv_size=0, send_size=0;
435
size_t totalrecvcount=0;
436
int *lrecvdispls = NULL; /* possible local displs calculated for noncontinous */
437
int *lsenddispls = NULL;/* possible local displs calculated for noncontinous */
438
int *lrecvcounts = NULL;/* possible local counts calculated for noncontinous */
439
int *lsendcounts = NULL;/* possible local counts calculated for noncontinous */
440
const int *precvdispls = recvdispls; /* pointer to displs to use as pami parmi */
441
const int *psenddispls = senddispls; /* pointer to displs to use as pami parmi */
442
const int *precvcounts = recvcounts; /* pointer to counts to use as pami parmi */
443
const int *psendcounts = sendcounts; /* pointer to counts to use as pami parmi */
444
int inplace = sendbuf == MPI_IN_PLACE? 1 : 0;
449
const struct MPIDI_Comm* const mpid = &(comm_ptr->mpid);
450
/* We don't pack and unpack in alltoallv as we do in alltoall because alltoallv has
451
more overhead of book keeping for sendcounts/displs and recvcounts/displs. Since,
452
alltoallv is non-rooted and all tasks has type info, decision to punt to mpich
453
will be the same on all tasks */
456
/* Check if collsel has MPICH algorithm as the best performing one, if so, call MPICH now w/o doing any conversions */
457
MPIDI_Datatype_get_info(1, recvtype, rcv_contig, rcvtypelen, rdt, rdt_true_lb);
458
if(MPIDI_Pamix_collsel_advise != NULL && mpid->collsel_fast_query != NULL)
460
advisor_algorithm_t advisor_algorithms[1];
461
int num_algorithms = MPIDI_Pamix_collsel_advise(mpid->collsel_fast_query, PAMI_XFER_ALLTOALLV_INT, rcvtypelen * recvcounts[0], advisor_algorithms, 1);
464
if(advisor_algorithms[0].algorithm_type == COLLSEL_EXTERNAL_ALGO)
466
return MPIR_Alltoallv(sendbuf, sendcounts, senddispls, sendtype,
467
recvbuf, recvcounts, recvdispls, recvtype,
473
/* Now do checks on send data and datatypes (contig and contin) and do necessary conversions */
476
sendok = MPIDI_Datatype_to_pami(sendtype, &stype, -1, NULL, &tmp);
477
MPIDI_Datatype_get_info(1, sendtype, snd_contig, sndtypelen, sdt, sdt_true_lb);
478
sbuf = (char *)sendbuf + sdt_true_lb;
479
if(!snd_contig || (sendok != PAMI_SUCCESS))
481
stype = PAMI_TYPE_UNSIGNED_CHAR;
482
size_t totalsendcount = sendcounts[0];
483
sendcontinuous = senddispls[0] == 0? 1 : 0 ;
485
psenddispls = lsenddispls = MPIU_Malloc(size*sizeof(int));
486
psendcounts = lsendcounts = MPIU_Malloc(size*sizeof(int));
488
lsendcounts[0]= sndtypelen * sendcounts[0];
489
for(i=1; i<size; ++i)
491
lsenddispls[i]= sndtypelen * totalsendcount;
492
totalsendcount += sendcounts[i];
493
if(senddispls[i] != (senddispls[i-1] + (sendcounts[i-1])))
495
lsendcounts[i]= sndtypelen * sendcounts[i];
497
send_size = sndtypelen * totalsendcount;
498
TRACE_ERR("Pack receive sndv_contig %zu, sendok %zd, totalsendcount %zu, sendcontinuous %zu, sndtypelen %zu, send_size %zu\n",
499
(size_t)snd_contig, (size_t)sendok, (size_t)totalsendcount, (size_t)sendcontinuous, (size_t) sndtypelen, (size_t)send_size);
500
snd_noncontig_buff = MPIU_Malloc(send_size);
501
sbuf = snd_noncontig_buff;
502
if(snd_noncontig_buff == NULL)
504
MPID_Abort(NULL, MPI_ERR_NO_SPACE, 1,
505
"Fatal: Cannot allocate pack buffer");
509
MPIR_Localcopy(sendbuf, totalsendcount, sendtype,
510
snd_noncontig_buff, send_size,MPI_CHAR);
515
MPID_Datatype_get_extent_macro(sendtype,extent);
516
for(i=0; i<size; ++i)
518
char* scbuf = (char*)sendbuf + senddispls[i]*extent;
519
char* rcbuf = (char*)snd_noncontig_buff + psenddispls[i];
520
MPIR_Localcopy(scbuf, sendcounts[i], sendtype,
521
rcbuf, psendcounts[i], MPI_CHAR);
522
TRACE_ERR("Pack send src extent %zu, displ[%zu]=%zu, count[%zu]=%zu buf[%zu]=%u\n",
523
(size_t)extent, (size_t)i,(size_t)senddispls[i],(size_t)i,(size_t)sendcounts[i],(size_t)senddispls[i], *(int*)scbuf);
524
TRACE_ERR("Pack send dest displ[%zu]=%zu, count[%zu]=%zu buf[%zu]=%u\n",
525
(size_t)i,(size_t)psenddispls[i],(size_t)i,(size_t)psendcounts[i],(size_t)psenddispls[i], *(int*)rcbuf);
531
recvok = MPIDI_Datatype_to_pami(recvtype, &rtype, -1, NULL, &tmp);
532
rbuf = (char *)recvbuf + rdt_true_lb;
533
if(!rcv_contig || (recvok != PAMI_SUCCESS))
535
rtype = PAMI_TYPE_UNSIGNED_CHAR;
536
totalrecvcount = recvcounts[0];
537
recvcontinuous = recvdispls[0] == 0? 1 : 0 ;
539
precvdispls = lrecvdispls = MPIU_Malloc(size*sizeof(int));
540
precvcounts = lrecvcounts = MPIU_Malloc(size*sizeof(int));
542
lrecvcounts[0]= rcvtypelen * recvcounts[0];
543
for(i=1; i<size; ++i)
545
lrecvdispls[i]= rcvtypelen * totalrecvcount;
546
totalrecvcount += recvcounts[i];
547
if(recvdispls[i] != (recvdispls[i-1] + (recvcounts[i-1])))
549
lrecvcounts[i]= rcvtypelen * recvcounts[i];
551
recv_size = rcvtypelen * totalrecvcount;
552
TRACE_ERR("Pack receive rcv_contig %zu, recvok %zd, totalrecvcount %zu, recvcontinuous %zu, rcvtypelen %zu, recv_size %zu\n",
553
(size_t)rcv_contig, (size_t)recvok, (size_t)totalrecvcount, (size_t)recvcontinuous,(size_t)rcvtypelen, (size_t)recv_size);
554
rcv_noncontig_buff = MPIU_Malloc(recv_size);
555
rbuf = rcv_noncontig_buff;
556
if(rcv_noncontig_buff == NULL)
558
MPID_Abort(NULL, MPI_ERR_NO_SPACE, 1,
559
"Fatal: Cannot allocate pack buffer");
561
/* need to copy it now if it's used for the send buffer and then do not do in place */
565
stype = PAMI_TYPE_UNSIGNED_CHAR;
566
size_t totalsendcount = recvcounts[0];
567
sendcontinuous = recvdispls[0] == 0? 1 : 0 ;
569
psenddispls = lsenddispls = MPIU_Malloc(size*sizeof(int));
570
psendcounts = lsendcounts = MPIU_Malloc(size*sizeof(int));
572
lsendcounts[0]= rcvtypelen * recvcounts[0];
573
for(i=1; i<size; ++i)
575
lsenddispls[i]= rcvtypelen * totalsendcount;
576
totalsendcount += recvcounts[i];
577
if(recvdispls[i] != (recvdispls[i-1] + (recvcounts[i-1])))
579
lsendcounts[i]= rcvtypelen * recvcounts[i];
581
send_size = rcvtypelen * totalsendcount;
582
TRACE_ERR("Pack MPI_IN_PLACE receive sndv_contig %zu, sendok %zd, totalsendcount %zu, sendcontinuous %zu, rcvtypelen %zu, send_size %zu\n",
583
(size_t)snd_contig, (size_t)sendok, (size_t)totalsendcount, (size_t)sendcontinuous, (size_t) rcvtypelen, (size_t)send_size);
584
snd_noncontig_buff = MPIU_Malloc(send_size);
585
sbuf = snd_noncontig_buff;
586
if(snd_noncontig_buff == NULL)
588
MPID_Abort(NULL, MPI_ERR_NO_SPACE, 1,
589
"Fatal: Cannot allocate pack buffer");
593
MPIR_Localcopy(recvbuf, totalsendcount, recvtype,
594
snd_noncontig_buff, send_size,MPI_CHAR);
599
MPID_Datatype_get_extent_macro(recvtype,extent);
600
for(i=0; i<size; ++i)
602
char* scbuf = (char*)recvbuf + recvdispls[i]*extent;
603
char* rcbuf = (char*)snd_noncontig_buff + psenddispls[i];
604
MPIR_Localcopy(scbuf, recvcounts[i], recvtype,
605
rcbuf, psendcounts[i], MPI_CHAR);
606
TRACE_ERR("Pack send src extent %zu, displ[%zu]=%zu, count[%zu]=%zu buf[%zu]=%u\n",
607
(size_t)extent, (size_t)i,(size_t)recvdispls[i],(size_t)i,(size_t)recvcounts[i],(size_t)recvdispls[i], *(int*)scbuf);
608
TRACE_ERR("Pack send dest extent %zu, displ[%zu]=%zu, count[%zu]=%zu buf[%zu]=%u\n",
609
(size_t)extent, (size_t)i,(size_t)psenddispls[i],(size_t)i,(size_t)psendcounts[i],(size_t)psenddispls[i], *(int*)rcbuf);
617
pami_xfer_t alltoallv;
618
const pami_metadata_t *my_alltoallv_md;
619
my_alltoallv_md = &mpid->coll_metadata[PAMI_XFER_ALLTOALLV_INT][0][0];
621
alltoallv.algorithm = mpid->coll_algorithm[PAMI_XFER_ALLTOALLV_INT][0][0];
622
char *pname = my_alltoallv_md->name;
624
alltoallv.cb_done = cb_alltoallv;
625
alltoallv.cookie = (void *)&active;
628
alltoallv.cmd.xfer_alltoallv_int.stype = rtype;
629
alltoallv.cmd.xfer_alltoallv_int.sdispls = (int *) precvdispls;
630
alltoallv.cmd.xfer_alltoallv_int.stypecounts = (int *) precvcounts;
631
alltoallv.cmd.xfer_alltoallv_int.sndbuf = PAMI_IN_PLACE;
635
alltoallv.cmd.xfer_alltoallv_int.stype = stype;
636
alltoallv.cmd.xfer_alltoallv_int.sdispls = (int *) psenddispls;
637
alltoallv.cmd.xfer_alltoallv_int.stypecounts = (int *) psendcounts;
638
alltoallv.cmd.xfer_alltoallv_int.sndbuf = sbuf;
640
alltoallv.cmd.xfer_alltoallv_int.rcvbuf = rbuf;
642
alltoallv.cmd.xfer_alltoallv_int.rdispls = (int *) precvdispls;
643
alltoallv.cmd.xfer_alltoallv_int.rtypecounts = (int *) precvcounts;
644
alltoallv.cmd.xfer_alltoallv_int.rtype = rtype;
647
MPIDI_Context_post(MPIDI_Context[0], &alltoallv_post.state,
648
MPIDI_Pami_post_wrapper, (void *)&alltoallv);
650
TRACE_ERR("%d waiting on active %d\n", rank, active);
651
MPID_PROGRESS_WAIT_WHILE(active);
653
if(!rcv_contig || (recvok != PAMI_SUCCESS))
657
MPIR_Localcopy(rcv_noncontig_buff, recv_size,MPI_CHAR,
658
recvbuf, totalrecvcount, recvtype);
664
MPID_Datatype_get_extent_macro(recvtype,extent);
665
for(i=0; i<size; ++i)
667
char* scbuf = (char*)rcv_noncontig_buff+ precvdispls[i];
668
char* rcbuf = (char*)recvbuf + recvdispls[i]*extent;
669
MPIR_Localcopy(scbuf, precvcounts[i], MPI_CHAR,
670
rcbuf, recvcounts[i], recvtype);
671
TRACE_ERR("Pack recv src extent %zu, displ[%zu]=%zu, count[%zu]=%zu buf[%zu]=%u\n",
672
(size_t)extent, (size_t)i,(size_t)precvdispls[i],(size_t)i,(size_t)precvcounts[i],(size_t)precvdispls[i], *(int*)scbuf);
673
TRACE_ERR("Pack recv dest extent %zu, displ[%zu]=%zu, count[%zu]=%zu buf[%zu]=%u\n",
674
(size_t)extent, (size_t)i,(size_t)recvdispls[i],(size_t)i,(size_t)recvcounts[i],(size_t)recvdispls[i], *(int*)rcbuf);
677
MPIU_Free(rcv_noncontig_buff);
679
if(!snd_contig || (sendok != PAMI_SUCCESS)) MPIU_Free(snd_noncontig_buff);
680
if(lrecvdispls) MPIU_Free(lrecvdispls);
681
if(lsenddispls) MPIU_Free(lsenddispls);
682
if(lrecvcounts) MPIU_Free(lrecvcounts);
683
if(lsendcounts) MPIU_Free(lsendcounts);
686
TRACE_ERR("Leaving alltoallv\n");
693
MPIDO_CSWrapper_alltoallv(pami_xfer_t *alltoallv,
697
MPID_Comm *comm_ptr = (MPID_Comm*)comm;
698
MPI_Datatype sendtype, recvtype;
700
MPIDI_coll_check_in_place(alltoallv->cmd.xfer_alltoallv_int.sndbuf, &sbuf);
701
int rc = MPIDI_Dtpami_to_dtmpi( alltoallv->cmd.xfer_alltoallv_int.stype,
705
if(rc == -1) return rc;
707
rc = MPIDI_Dtpami_to_dtmpi( alltoallv->cmd.xfer_alltoallv_int.rtype,
711
if(rc == -1) return rc;
713
rc = MPIR_Alltoallv(sbuf,
714
alltoallv->cmd.xfer_alltoallv_int.stypecounts,
715
alltoallv->cmd.xfer_alltoallv_int.sdispls, sendtype,
716
alltoallv->cmd.xfer_alltoallv_int.rcvbuf,
717
alltoallv->cmd.xfer_alltoallv_int.rtypecounts,
718
alltoallv->cmd.xfer_alltoallv_int.rdispls, recvtype,
719
comm_ptr, &mpierrno);
720
if(alltoallv->cb_done && rc == 0)
721
alltoallv->cb_done(NULL, alltoallv->cookie, PAMI_SUCCESS);