This source file includes following definitions.
- ompi_fcoll_base_coll_allgatherv_array
- ompi_fcoll_base_coll_gatherv_array
- ompi_fcoll_base_coll_scatterv_array
- ompi_fcoll_base_coll_allgather_array
- ompi_fcoll_base_coll_gather_array
- ompi_fcoll_base_coll_bcast_array
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 #include "ompi_config.h"
25
26 #include "ompi/runtime/params.h"
27 #include "ompi/communicator/communicator.h"
28 #include "ompi/mca/pml/pml.h"
29 #include "opal/datatype/opal_datatype.h"
30 #include "ompi/datatype/ompi_datatype.h"
31 #include "ompi/request/request.h"
32
33 #include <math.h>
34 #include "ompi/mca/fcoll/base/fcoll_base_coll_array.h"
35 #include "ompi/mca/common/ompio/common_ompio.h"
36
37
38 int ompi_fcoll_base_coll_allgatherv_array (void *sbuf,
39 int scount,
40 ompi_datatype_t *sdtype,
41 void *rbuf,
42 int *rcounts,
43 int *disps,
44 ompi_datatype_t *rdtype,
45 int root_index,
46 int *procs_in_group,
47 int procs_per_group,
48 ompi_communicator_t *comm)
49 {
50 int err = OMPI_SUCCESS;
51 ptrdiff_t extent, lb;
52 int i, rank, j;
53 char *send_buf = NULL;
54 struct ompi_datatype_t *newtype, *send_type;
55
56 rank = ompi_comm_rank (comm);
57 for (j = 0; j < procs_per_group; j++) {
58 if (procs_in_group[j] == rank) {
59 break;
60 }
61 }
62
63 if (MPI_IN_PLACE == sbuf) {
64 err = opal_datatype_get_extent (&rdtype->super, &lb, &extent);
65 if (OMPI_SUCCESS != err) {
66 return OMPI_ERROR;
67 }
68 send_type = rdtype;
69 send_buf = (char*)rbuf;
70
71 for (i = 0; i < j; i++) {
72 send_buf += (rcounts[i] * extent);
73 }
74 }
75 else {
76 send_buf = (char*)sbuf;
77 send_type = sdtype;
78 }
79
80 err = ompi_fcoll_base_coll_gatherv_array (send_buf,
81 rcounts[j],
82 send_type,
83 rbuf,
84 rcounts,
85 disps,
86 rdtype,
87 root_index,
88 procs_in_group,
89 procs_per_group,
90 comm);
91 if (OMPI_SUCCESS != err) {
92 return err;
93 }
94
95 err = ompi_datatype_create_indexed (procs_per_group,
96 rcounts,
97 disps,
98 rdtype,
99 &newtype);
100 if (MPI_SUCCESS != err) {
101 return err;
102 }
103 err = ompi_datatype_commit (&newtype);
104 if(MPI_SUCCESS != err) {
105 return err;
106 }
107
108 ompi_fcoll_base_coll_bcast_array (rbuf,
109 1,
110 newtype,
111 root_index,
112 procs_in_group,
113 procs_per_group,
114 comm);
115
116 ompi_datatype_destroy (&newtype);
117
118 return OMPI_SUCCESS;
119 }
120
121 int ompi_fcoll_base_coll_gatherv_array (void *sbuf,
122 int scount,
123 ompi_datatype_t *sdtype,
124 void *rbuf,
125 int *rcounts,
126 int *disps,
127 ompi_datatype_t *rdtype,
128 int root_index,
129 int *procs_in_group,
130 int procs_per_group,
131 struct ompi_communicator_t *comm)
132 {
133 int i, rank;
134 int err = OMPI_SUCCESS;
135 char *ptmp;
136 ptrdiff_t extent, lb;
137 ompi_request_t **reqs=NULL;
138
139 rank = ompi_comm_rank (comm);
140
141 if (procs_in_group[root_index] != rank) {
142 if (scount > 0) {
143 return MCA_PML_CALL(send(sbuf,
144 scount,
145 sdtype,
146 procs_in_group[root_index],
147 FCOLL_TAG_GATHERV,
148 MCA_PML_BASE_SEND_STANDARD,
149 comm));
150 }
151 return err;
152 }
153
154
155
156
157 err = opal_datatype_get_extent (&rdtype->super, &lb, &extent);
158 if (OMPI_SUCCESS != err) {
159 return OMPI_ERROR;
160 }
161 reqs = (ompi_request_t **) malloc ( procs_per_group *sizeof(ompi_request_t *));
162 if ( NULL == reqs ) {
163 return OMPI_ERR_OUT_OF_RESOURCE;
164 }
165 for (i=0; i<procs_per_group; i++) {
166 ptmp = ((char *) rbuf) + (extent * disps[i]);
167
168 if (procs_in_group[i] == rank) {
169 if (MPI_IN_PLACE != sbuf &&
170 (0 < scount) &&
171 (0 < rcounts[i])) {
172 err = ompi_datatype_sndrcv (sbuf,
173 scount,
174 sdtype,
175 ptmp,
176 rcounts[i],
177 rdtype);
178 }
179 reqs[i] = MPI_REQUEST_NULL;
180 }
181 else {
182
183 if (rcounts[i] > 0) {
184 err = MCA_PML_CALL(irecv(ptmp,
185 rcounts[i],
186 rdtype,
187 procs_in_group[i],
188 FCOLL_TAG_GATHERV,
189 comm,
190 &reqs[i]));
191 }
192 else {
193 reqs[i] = MPI_REQUEST_NULL;
194 }
195 }
196
197 if (OMPI_SUCCESS != err) {
198 free ( reqs );
199 return err;
200 }
201 }
202
203 err = ompi_request_wait_all ( procs_per_group, reqs, MPI_STATUSES_IGNORE );
204 if ( NULL != reqs ) {
205 free ( reqs );
206 }
207 return err;
208 }
209
210 int ompi_fcoll_base_coll_scatterv_array (void *sbuf,
211 int *scounts,
212 int *disps,
213 ompi_datatype_t *sdtype,
214 void *rbuf,
215 int rcount,
216 ompi_datatype_t *rdtype,
217 int root_index,
218 int *procs_in_group,
219 int procs_per_group,
220 struct ompi_communicator_t *comm)
221 {
222 int i, rank;
223 int err = OMPI_SUCCESS;
224 char *ptmp;
225 ptrdiff_t extent, lb;
226 ompi_request_t ** reqs=NULL;
227
228 rank = ompi_comm_rank (comm);
229
230 if (procs_in_group[root_index] != rank) {
231 if (rcount > 0) {
232 err = MCA_PML_CALL(recv(rbuf,
233 rcount,
234 rdtype,
235 procs_in_group[root_index],
236 FCOLL_TAG_SCATTERV,
237 comm,
238 MPI_STATUS_IGNORE));
239 }
240 return err;
241 }
242
243
244
245
246 err = opal_datatype_get_extent (&sdtype->super, &lb, &extent);
247 if (OMPI_SUCCESS != err) {
248 return OMPI_ERROR;
249 }
250 reqs = ( ompi_request_t **) malloc ( procs_per_group * sizeof ( ompi_request_t *));
251 if (NULL == reqs ) {
252 return OMPI_ERR_OUT_OF_RESOURCE;
253 }
254
255 for (i=0 ; i<procs_per_group ; ++i) {
256 ptmp = ((char *) sbuf) + (extent * disps[i]);
257
258 if (procs_in_group[i] == rank) {
259 if (MPI_IN_PLACE != sbuf &&
260 (0 < scounts[i]) &&
261 (0 < rcount)) {
262 err = ompi_datatype_sndrcv (ptmp,
263 scounts[i],
264 sdtype,
265 rbuf,
266 rcount,
267 rdtype);
268 }
269 reqs[i] = MPI_REQUEST_NULL;
270 }
271 else {
272
273 if (scounts[i] > 0) {
274 err = MCA_PML_CALL(isend(ptmp,
275 scounts[i],
276 sdtype,
277 procs_in_group[i],
278 FCOLL_TAG_SCATTERV,
279 MCA_PML_BASE_SEND_STANDARD,
280 comm,
281 &reqs[i]));
282 }
283 else {
284 reqs[i] = MPI_REQUEST_NULL;
285 }
286 }
287 if (OMPI_SUCCESS != err) {
288 free ( reqs );
289 return err;
290 }
291 }
292
293 err = ompi_request_wait_all ( procs_per_group, reqs, MPI_STATUSES_IGNORE );
294 if ( NULL != reqs ) {
295 free ( reqs );
296 }
297 return err;
298 }
299
300 int ompi_fcoll_base_coll_allgather_array (void *sbuf,
301 int scount,
302 ompi_datatype_t *sdtype,
303 void *rbuf,
304 int rcount,
305 ompi_datatype_t *rdtype,
306 int root_index,
307 int *procs_in_group,
308 int procs_per_group,
309 ompi_communicator_t *comm)
310 {
311 int err = OMPI_SUCCESS;
312 int rank;
313 ptrdiff_t extent, lb;
314
315 rank = ompi_comm_rank (comm);
316
317 if (((void *) 1) == sbuf && 0 != rank) {
318 err = opal_datatype_get_extent (&rdtype->super, &lb, &extent);
319 if (OMPI_SUCCESS != err) {
320 return OMPI_ERROR;
321 }
322 sbuf = ((char*) rbuf) + (rank * extent * rcount);
323 sdtype = rdtype;
324 scount = rcount;
325 }
326
327
328 err = ompi_fcoll_base_coll_gather_array (sbuf,
329 scount,
330 sdtype,
331 rbuf,
332 rcount,
333 rdtype,
334 root_index,
335 procs_in_group,
336 procs_per_group,
337 comm);
338
339 if (OMPI_SUCCESS == err) {
340 err = ompi_fcoll_base_coll_bcast_array (rbuf,
341 rcount * procs_per_group,
342 rdtype,
343 root_index,
344 procs_in_group,
345 procs_per_group,
346 comm);
347 }
348
349
350 return err;
351 }
352
353 int ompi_fcoll_base_coll_gather_array (void *sbuf,
354 int scount,
355 ompi_datatype_t *sdtype,
356 void *rbuf,
357 int rcount,
358 ompi_datatype_t *rdtype,
359 int root_index,
360 int *procs_in_group,
361 int procs_per_group,
362 struct ompi_communicator_t *comm)
363 {
364 int i;
365 int rank;
366 char *ptmp;
367 ptrdiff_t incr;
368 ptrdiff_t extent, lb;
369 int err = OMPI_SUCCESS;
370 ompi_request_t ** reqs=NULL;
371
372 rank = ompi_comm_rank (comm);
373
374
375 if (procs_in_group[root_index] != rank) {
376 err = MCA_PML_CALL(send(sbuf,
377 scount,
378 sdtype,
379 procs_in_group[root_index],
380 FCOLL_TAG_GATHER,
381 MCA_PML_BASE_SEND_STANDARD,
382 comm));
383 return err;
384 }
385
386
387 opal_datatype_get_extent (&rdtype->super, &lb, &extent);
388 incr = extent * rcount;
389
390 reqs = ( ompi_request_t **) malloc ( procs_per_group * sizeof ( ompi_request_t *));
391 if (NULL == reqs ) {
392 return OMPI_ERR_OUT_OF_RESOURCE;
393 }
394
395 for (i = 0, ptmp = (char *) rbuf;
396 i < procs_per_group;
397 ++i, ptmp += incr) {
398 if (procs_in_group[i] == rank) {
399 if (MPI_IN_PLACE != sbuf) {
400 err = ompi_datatype_sndrcv (sbuf,
401 scount,
402 sdtype ,
403 ptmp,
404 rcount,
405 rdtype);
406 }
407 else {
408 err = OMPI_SUCCESS;
409 }
410 reqs[i] = MPI_REQUEST_NULL;
411 }
412 else {
413 err = MCA_PML_CALL(irecv(ptmp,
414 rcount,
415 rdtype,
416 procs_in_group[i],
417 FCOLL_TAG_GATHER,
418 comm,
419 &reqs[i]));
420
421
422
423
424
425
426 }
427
428 if (OMPI_SUCCESS != err) {
429 free ( reqs );
430 return err;
431 }
432 }
433
434
435 err = ompi_request_wait_all ( procs_per_group, reqs, MPI_STATUSES_IGNORE );
436 if ( NULL != reqs ) {
437 free ( reqs );
438 }
439
440 return err;
441 }
442
443 int ompi_fcoll_base_coll_bcast_array (void *buff,
444 int count,
445 ompi_datatype_t *datatype,
446 int root_index,
447 int *procs_in_group,
448 int procs_per_group,
449 ompi_communicator_t *comm)
450 {
451 int i, rank;
452 int err = OMPI_SUCCESS;
453 ompi_request_t ** reqs=NULL;
454
455 rank = ompi_comm_rank (comm);
456
457
458 if (procs_in_group[root_index] != rank) {
459 err = MCA_PML_CALL(recv(buff,
460 count,
461 datatype,
462 procs_in_group[root_index],
463 FCOLL_TAG_BCAST,
464 comm,
465 MPI_STATUS_IGNORE));
466 return err;
467 }
468
469
470 reqs = ( ompi_request_t **) malloc ( procs_per_group * sizeof ( ompi_request_t *));
471 if (NULL == reqs ) {
472 return OMPI_ERR_OUT_OF_RESOURCE;
473 }
474
475 for (i=0 ; i<procs_per_group ; i++) {
476 if (procs_in_group[i] == rank) {
477 reqs[i] = MPI_REQUEST_NULL;
478 continue;
479 }
480
481 err = MCA_PML_CALL(isend(buff,
482 count,
483 datatype,
484 procs_in_group[i],
485 FCOLL_TAG_BCAST,
486 MCA_PML_BASE_SEND_STANDARD,
487 comm,
488 &reqs[i]));
489 if (OMPI_SUCCESS != err) {
490 free ( reqs );
491 return err;
492 }
493 }
494 err = ompi_request_wait_all ( procs_per_group, reqs, MPI_STATUSES_IGNORE );
495 if ( NULL != reqs ) {
496 free ( reqs );
497 }
498
499 return err;
500 }