This source file includes following definitions.
- ompi_comm_set
- ompi_comm_set_nb
- ompi_comm_group
- ompi_comm_create
- ompi_comm_split
- ompi_comm_split_type_get_part
- ompi_comm_split_verify
- ompi_comm_split_type
- ompi_comm_dup
- ompi_comm_dup_with_info
- ompi_comm_idup
- ompi_comm_idup_with_info
- ompi_comm_idup_internal
- ompi_comm_idup_getcid
- ompi_comm_idup_with_info_activate
- ompi_comm_idup_with_info_finish
- ompi_comm_create_group
- ompi_comm_compare
- ompi_comm_set_name
- ompi_comm_allgather_emulate_intra
- ompi_comm_free
- ompi_comm_get_rprocs
- ompi_comm_overlapping_groups
- ompi_comm_determine_first
- ompi_comm_dump
- rankkeycompare
- ompi_comm_enable
- ompi_comm_fill_rest
- ompi_comm_copy_topo
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33 #include "ompi_config.h"
34 #include <string.h>
35 #include <stdio.h>
36
37 #include "ompi/constants.h"
38 #include "opal/mca/hwloc/base/base.h"
39 #include "opal/dss/dss.h"
40 #include "opal/mca/pmix/pmix.h"
41 #include "opal/util/string_copy.h"
42
43 #include "ompi/proc/proc.h"
44 #include "opal/threads/mutex.h"
45 #include "opal/util/bit_ops.h"
46 #include "opal/util/output.h"
47 #include "ompi/mca/topo/topo.h"
48 #include "ompi/mca/topo/base/base.h"
49 #include "ompi/dpm/dpm.h"
50
51 #include "ompi/attribute/attribute.h"
52 #include "ompi/communicator/communicator.h"
53 #include "ompi/mca/pml/pml.h"
54 #include "ompi/request/request.h"
55
56
57
58
59 static int rankkeycompare(const void *, const void *);
60
61
62
63
64 static int ompi_comm_fill_rest (ompi_communicator_t *comm,
65 int num_procs,
66 ompi_proc_t **proc_pointers,
67 int my_rank,
68 ompi_errhandler_t *errh );
69
70
71
72
73
74
75 typedef int ompi_comm_allgatherfct (void* inbuf, int incount, MPI_Datatype intype,
76 void* outbuf, int outcount, MPI_Datatype outtype,
77 ompi_communicator_t *comm,
78 mca_coll_base_module_t *data);
79
80 static int ompi_comm_allgather_emulate_intra (void* inbuf, int incount, MPI_Datatype intype,
81 void* outbuf, int outcount,
82 MPI_Datatype outtype,
83 ompi_communicator_t *comm,
84 mca_coll_base_module_t *data);
85
86 static int ompi_comm_copy_topo (ompi_communicator_t *oldcomm,
87 ompi_communicator_t *newcomm);
88
89
90 static int ompi_comm_idup_internal (ompi_communicator_t *comm, ompi_group_t *group, ompi_group_t *remote_group,
91 opal_info_t *info, ompi_communicator_t **newcomm, ompi_request_t **req);
92
93
94
95
96
97
98
99
100
101
102 int ompi_comm_set ( ompi_communicator_t **ncomm,
103 ompi_communicator_t *oldcomm,
104 int local_size,
105 int *local_ranks,
106 int remote_size,
107 int *remote_ranks,
108 opal_hash_table_t *attr,
109 ompi_errhandler_t *errh,
110 bool copy_topocomponent,
111 ompi_group_t *local_group,
112 ompi_group_t *remote_group )
113 {
114 ompi_request_t *req;
115 int rc;
116
117 rc = ompi_comm_set_nb (ncomm, oldcomm, local_size, local_ranks, remote_size, remote_ranks,
118 attr, errh, copy_topocomponent, local_group, remote_group, &req);
119 if (OMPI_SUCCESS != rc) {
120 return rc;
121 }
122
123 if (NULL != req) {
124 rc = ompi_request_wait( &req, MPI_STATUS_IGNORE);
125 }
126
127 return rc;
128 }
129
130
131
132
133
134 int ompi_comm_set_nb ( ompi_communicator_t **ncomm,
135 ompi_communicator_t *oldcomm,
136 int local_size,
137 int *local_ranks,
138 int remote_size,
139 int *remote_ranks,
140 opal_hash_table_t *attr,
141 ompi_errhandler_t *errh,
142 bool copy_topocomponent,
143 ompi_group_t *local_group,
144 ompi_group_t *remote_group,
145 ompi_request_t **req )
146 {
147 ompi_communicator_t *newcomm = NULL;
148 int ret;
149
150 if (NULL != local_group) {
151 local_size = ompi_group_size (local_group);
152 }
153
154 if ( (NULL != remote_group) && (&ompi_mpi_group_null.group != remote_group) ) {
155 remote_size = ompi_group_size (remote_group);
156 }
157
158 *req = NULL;
159
160
161 newcomm = OBJ_NEW(ompi_communicator_t);
162 if (NULL == newcomm) {
163 return OMPI_ERR_OUT_OF_RESOURCE;
164 }
165 newcomm->super.s_info = NULL;
166
167 newcomm->c_cube_dim = opal_cube_dim(local_size);
168 newcomm->c_id_available = MPI_UNDEFINED;
169 newcomm->c_id_start_index = MPI_UNDEFINED;
170
171 if (NULL == local_group) {
172
173
174 ret = ompi_group_incl(oldcomm->c_local_group, local_size,
175 local_ranks, &newcomm->c_local_group);
176 if (OPAL_UNLIKELY(OMPI_SUCCESS != ret)) {
177 return ret;
178 }
179 } else {
180 newcomm->c_local_group = local_group;
181 OBJ_RETAIN(newcomm->c_local_group);
182 }
183 newcomm->c_my_rank = newcomm->c_local_group->grp_my_rank;
184
185
186 if ( NULL != remote_group ) {
187 ompi_communicator_t *old_localcomm;
188
189 if (&ompi_mpi_group_null.group == remote_group) {
190 ret = ompi_group_incl(oldcomm->c_remote_group, remote_size,
191 remote_ranks, &newcomm->c_remote_group);
192 if (OPAL_UNLIKELY(OMPI_SUCCESS != ret)) {
193 return ret;
194 }
195 } else {
196 newcomm->c_remote_group = remote_group;
197 OBJ_RETAIN(newcomm->c_remote_group);
198 }
199
200 newcomm->c_flags |= OMPI_COMM_INTER;
201
202 old_localcomm = OMPI_COMM_IS_INTRA(oldcomm) ? oldcomm : oldcomm->c_local_comm;
203
204
205 ompi_comm_idup_internal (old_localcomm, newcomm->c_local_group, NULL, NULL,
206 &newcomm->c_local_comm, req);
207 } else {
208 newcomm->c_remote_group = newcomm->c_local_group;
209 OBJ_RETAIN(newcomm->c_remote_group);
210 }
211
212
213
214
215 if ( 0 < local_size && (OMPI_COMM_IS_INTRA(newcomm) || 0 <remote_size) ) {
216 ompi_dpm_mark_dyncomm (newcomm);
217 }
218
219
220 newcomm->error_handler = errh;
221 OBJ_RETAIN ( newcomm->error_handler );
222
223
224 if ( copy_topocomponent && (NULL != oldcomm->c_topo) ) {
225
226
227
228
229 if (OMPI_SUCCESS != (ret = ompi_comm_copy_topo(oldcomm, newcomm))) {
230 ompi_comm_free(&newcomm);
231 return ret;
232 }
233 }
234
235
236 if (NULL != oldcomm->c_keyhash) {
237 if (NULL != attr) {
238 ompi_attr_hash_init(&newcomm->c_keyhash);
239 if (OMPI_SUCCESS != (ret = ompi_attr_copy_all (COMM_ATTR, oldcomm,
240 newcomm, attr,
241 newcomm->c_keyhash))) {
242 ompi_comm_free(&newcomm);
243 return ret;
244 }
245 }
246 }
247
248 *ncomm = newcomm;
249 return (OMPI_SUCCESS);
250 }
251
252
253
254
255
256
257
258
259 int ompi_comm_group ( ompi_communicator_t* comm, ompi_group_t **group )
260 {
261
262 OBJ_RETAIN(comm->c_local_group);
263
264 *group = comm->c_local_group;
265 return OMPI_SUCCESS;
266 }
267
268
269
270
271
272
273
274 int ompi_comm_create ( ompi_communicator_t *comm, ompi_group_t *group,
275 ompi_communicator_t **newcomm )
276 {
277 ompi_communicator_t *newcomp = NULL;
278 int rsize;
279 int mode,i,j;
280 int *allranks=NULL;
281 int *rranks=NULL;
282 int rc = OMPI_SUCCESS;
283 ompi_group_t *remote_group = NULL;
284
285
286 if (OPAL_UNLIKELY(NULL == newcomm)) {
287 return OMPI_ERR_BAD_PARAM;
288 }
289
290 if ( OMPI_COMM_IS_INTER(comm) ) {
291 int tsize;
292 remote_group = &ompi_mpi_group_null.group;
293
294 tsize = ompi_comm_remote_size(comm);
295 allranks = (int *) malloc ( tsize * sizeof(int));
296 if ( NULL == allranks ) {
297 rc = OMPI_ERR_OUT_OF_RESOURCE;
298 goto exit;
299 }
300
301 rc = comm->c_coll->coll_allgather ( &(group->grp_my_rank),
302 1, MPI_INT, allranks,
303 1, MPI_INT, comm,
304 comm->c_coll->coll_allgather_module);
305 if ( OMPI_SUCCESS != rc ) {
306 goto exit;
307 }
308
309
310 for (rsize=0, i = 0; i < tsize; i++) {
311 if ( MPI_UNDEFINED != allranks[i] ) {
312 rsize++;
313 }
314 }
315
316
317
318 if ( 0 == rsize || 0 == group->grp_proc_count ) {
319 newcomp = MPI_COMM_NULL;
320 rc = OMPI_SUCCESS;
321 goto exit;
322 }
323
324
325 rranks = (int *) malloc ( rsize * sizeof(int));
326 if ( NULL == rranks ) {
327 rc = OMPI_ERR_OUT_OF_RESOURCE;
328 goto exit;
329 }
330
331 for ( j = 0, i = 0; i < tsize; i++ ) {
332 if ( MPI_UNDEFINED != allranks[i] ) {
333 rranks[j] = i;
334 j++;
335 }
336 }
337 mode = OMPI_COMM_CID_INTER;
338
339 } else {
340 rsize = 0;
341 rranks = NULL;
342 mode = OMPI_COMM_CID_INTRA;
343 }
344
345 rc = ompi_comm_set ( &newcomp,
346 comm,
347 0,
348 NULL,
349 rsize,
350 rranks,
351 NULL,
352 comm->error_handler,
353 false,
354 group,
355 remote_group);
356
357 if ( OMPI_SUCCESS != rc ) {
358 goto exit;
359 }
360
361
362 rc = ompi_comm_nextcid (newcomp, comm, NULL, NULL, NULL, false, mode);
363 if ( OMPI_SUCCESS != rc ) {
364 goto exit;
365 }
366
367
368 snprintf(newcomp->c_name, MPI_MAX_OBJECT_NAME, "MPI COMMUNICATOR %d CREATE FROM %d",
369 newcomp->c_contextid, comm->c_contextid );
370
371
372 rc = ompi_comm_activate (&newcomp, comm, NULL, NULL, NULL, false, mode);
373 if ( OMPI_SUCCESS != rc ) {
374 goto exit;
375 }
376
377
378
379
380
381
382
383
384 if ( MPI_UNDEFINED == newcomp->c_local_group->grp_my_rank ) {
385 ompi_comm_free ( &newcomp );
386 }
387
388 exit:
389 if ( NULL != allranks ) {
390 free ( allranks );
391 }
392 if ( NULL != rranks ) {
393 free ( rranks );
394 }
395
396 *newcomm = newcomp;
397 return ( rc );
398 }
399
400
401
402
403
404
405
406
407 int ompi_comm_split( ompi_communicator_t* comm, int color, int key,
408 ompi_communicator_t **newcomm, bool pass_on_topo )
409 {
410 int myinfo[2];
411 int size, my_size;
412 int my_rsize=0;
413 int mode;
414 int rsize;
415 int i, loc;
416 int inter;
417 int *results=NULL, *sorted=NULL;
418 int *rresults=NULL, *rsorted=NULL;
419 int rc=OMPI_SUCCESS;
420 ompi_communicator_t *newcomp = NULL;
421 int *lranks=NULL, *rranks=NULL;
422 ompi_group_t * local_group=NULL, *remote_group=NULL;
423
424 ompi_comm_allgatherfct *allgatherfct=NULL;
425
426
427
428
429
430 myinfo[0] = color;
431 myinfo[1] = key;
432
433 size = ompi_comm_size ( comm );
434 inter = OMPI_COMM_IS_INTER(comm);
435 if ( inter ) {
436 allgatherfct = (ompi_comm_allgatherfct *)ompi_comm_allgather_emulate_intra;
437 } else {
438 allgatherfct = (ompi_comm_allgatherfct *)comm->c_coll->coll_allgather;
439 }
440
441 results = (int*) malloc ( 2 * size * sizeof(int));
442 if ( NULL == results ) {
443 return OMPI_ERR_OUT_OF_RESOURCE;
444 }
445
446 rc = allgatherfct( myinfo, 2, MPI_INT, results, 2, MPI_INT, comm, comm->c_coll->coll_allgather_module );
447 if ( OMPI_SUCCESS != rc ) {
448 goto exit;
449 }
450
451
452 for ( my_size = 0, i=0; i < size; i++) {
453 if ( results[(2*i)+0] == color) {
454 my_size++;
455 }
456 }
457
458
459 if (OPAL_UNLIKELY(0 == my_size)) {
460 rc = OMPI_ERR_BAD_PARAM;
461 goto exit;
462 }
463
464 sorted = (int *) calloc (my_size * 2, sizeof (int));
465 if ( NULL == sorted) {
466 rc = OMPI_ERR_OUT_OF_RESOURCE;
467 goto exit;
468 }
469
470
471 for( loc = 0, i = 0; i < size; i++ ) {
472 if ( results[(2*i)+0] == color) {
473 sorted[(2*loc)+0] = i;
474 sorted[(2*loc)+1] = results[(2*i)+1];
475 loc++;
476 }
477 }
478
479
480
481 if(my_size>1){
482 qsort ((int*)sorted, my_size, sizeof(int)*2, rankkeycompare);
483 }
484
485
486 lranks = (int *) malloc ( my_size * sizeof(int));
487 if ( NULL == lranks ) {
488 rc = OMPI_ERR_OUT_OF_RESOURCE;
489 goto exit;
490 }
491 for (i = 0; i < my_size; i++) {
492 lranks[i] = sorted[i*2];
493 }
494
495
496
497 if ( inter ) {
498 remote_group = &ompi_mpi_group_null.group;
499 rsize = comm->c_remote_group->grp_proc_count;
500 rresults = (int *) malloc ( rsize * 2 * sizeof(int));
501 if ( NULL == rresults ) {
502 rc = OMPI_ERR_OUT_OF_RESOURCE;
503 goto exit;
504 }
505
506
507 rc = comm->c_coll->coll_allgather( myinfo, 2, MPI_INT, rresults, 2,
508 MPI_INT, comm,
509 comm->c_coll->coll_allgather_module);
510 if ( OMPI_SUCCESS != rc ) {
511 goto exit;
512 }
513
514
515 for ( my_rsize = 0, i=0; i < rsize; i++) {
516 if ( rresults[(2*i)+0] == color) {
517 my_rsize++;
518 }
519 }
520
521 if (my_rsize > 0) {
522 rsorted = (int *) calloc (my_rsize * 2, sizeof (int));
523 if ( NULL == rsorted) {
524 rc = OMPI_ERR_OUT_OF_RESOURCE;
525 goto exit;
526 }
527
528
529 for( loc = 0, i = 0; i < rsize; i++ ) {
530 if ( rresults[(2*i)+0] == color) {
531 rsorted[(2*loc)+0] = i;
532 rsorted[(2*loc)+1] = rresults[(2*i)+1];
533 loc++;
534 }
535 }
536
537
538
539 if (my_rsize > 1) {
540 qsort ((int*)rsorted, my_rsize, sizeof(int)*2, rankkeycompare);
541 }
542
543
544 rranks = (int *) malloc ( my_rsize * sizeof(int));
545 if ( NULL == rranks) {
546 rc = OMPI_ERR_OUT_OF_RESOURCE;
547 goto exit;
548 }
549
550 for (i = 0; i < my_rsize; i++) {
551 rranks[i] = rsorted[i*2];
552 }
553 }
554
555 rc = ompi_group_incl(comm->c_local_group, my_size, lranks, &local_group);
556 if (OMPI_SUCCESS != rc) {
557 goto exit;
558 }
559
560 mode = OMPI_COMM_CID_INTER;
561 } else {
562 rranks = NULL;
563 mode = OMPI_COMM_CID_INTRA;
564 }
565
566
567
568
569
570 rc = ompi_comm_set ( &newcomp,
571 comm,
572 my_size,
573 lranks,
574 my_rsize,
575 rranks,
576 NULL,
577 comm->error_handler,
578 pass_on_topo,
579 local_group,
580 remote_group);
581
582 if ( OMPI_SUCCESS != rc ) {
583 goto exit;
584 }
585
586 if ( inter ) {
587 OBJ_RELEASE(local_group);
588 if (NULL != newcomp->c_local_comm) {
589 snprintf(newcomp->c_local_comm->c_name, MPI_MAX_OBJECT_NAME,
590 "MPI COMMUNICATOR %d SPLIT FROM %d",
591 newcomp->c_local_comm->c_contextid,
592 comm->c_local_comm->c_contextid );
593 }
594 }
595
596
597
598
599
600 if ( MPI_UNDEFINED == color || (inter && my_rsize==0)) {
601 newcomp->c_local_group->grp_my_rank = MPI_UNDEFINED;
602 }
603
604
605 rc = ompi_comm_nextcid (newcomp, comm, NULL, NULL, NULL, false, mode);
606 if ( OMPI_SUCCESS != rc ) {
607 goto exit;
608 }
609
610
611 snprintf(newcomp->c_name, MPI_MAX_OBJECT_NAME, "MPI COMMUNICATOR %d SPLIT FROM %d",
612 newcomp->c_contextid, comm->c_contextid );
613
614
615
616
617 rc = ompi_comm_activate (&newcomp, comm, NULL, NULL, NULL, false, mode);
618
619 exit:
620 free ( results );
621 free ( sorted );
622 free ( rresults );
623 free ( rsorted );
624 free ( lranks );
625 free ( rranks );
626
627
628
629 if (inter && my_rsize == 0) {
630 color = MPI_UNDEFINED;
631 }
632 if ( NULL != newcomp && MPI_UNDEFINED == color ) {
633 ompi_comm_free ( &newcomp );
634 }
635
636 *newcomm = newcomp;
637 return rc;
638 }
639
640
641
642
643
644
645
646
647
648 static int ompi_comm_split_type_get_part (ompi_group_t *group, const int split_type, int **ranks_out, int *rank_size) {
649 int size = ompi_group_size (group);
650 int my_size = 0;
651 int *ranks;
652 int ret;
653
654 ranks = malloc (size * sizeof (int));
655 if (OPAL_UNLIKELY(NULL == ranks)) {
656 return OMPI_ERR_OUT_OF_RESOURCE;
657 }
658
659 for (int i = 0 ; i < size ; ++i) {
660 ompi_proc_t *proc = ompi_group_get_proc_ptr_raw (group, i);
661 uint16_t locality, *u16ptr;
662 int include = false;
663
664 if (ompi_proc_is_sentinel (proc)) {
665 opal_process_name_t proc_name = ompi_proc_sentinel_to_name ((uintptr_t) proc);
666
667 if (split_type <= OMPI_COMM_TYPE_HOST) {
668
669
670
671 continue;
672 }
673
674 u16ptr = &locality;
675
676 OPAL_MODEX_RECV_VALUE(ret, OPAL_PMIX_LOCALITY, &proc_name, &u16ptr, OPAL_UINT16);
677 if (OPAL_SUCCESS != ret) {
678 continue;
679 }
680 } else {
681 locality = proc->super.proc_flags;
682 }
683
684 switch (split_type) {
685 case OMPI_COMM_TYPE_HWTHREAD:
686 include = OPAL_PROC_ON_LOCAL_HWTHREAD(locality);
687 break;
688 case OMPI_COMM_TYPE_CORE:
689 include = OPAL_PROC_ON_LOCAL_CORE(locality);
690 break;
691 case OMPI_COMM_TYPE_L1CACHE:
692 include = OPAL_PROC_ON_LOCAL_L1CACHE(locality);
693 break;
694 case OMPI_COMM_TYPE_L2CACHE:
695 include = OPAL_PROC_ON_LOCAL_L2CACHE(locality);
696 break;
697 case OMPI_COMM_TYPE_L3CACHE:
698 include = OPAL_PROC_ON_LOCAL_L3CACHE(locality);
699 break;
700 case OMPI_COMM_TYPE_SOCKET:
701 include = OPAL_PROC_ON_LOCAL_SOCKET(locality);
702 break;
703 case OMPI_COMM_TYPE_NUMA:
704 include = OPAL_PROC_ON_LOCAL_NUMA(locality);
705 break;
706 case MPI_COMM_TYPE_SHARED:
707 include = OPAL_PROC_ON_LOCAL_NODE(locality);
708 break;
709 case OMPI_COMM_TYPE_BOARD:
710 include = OPAL_PROC_ON_LOCAL_BOARD(locality);
711 break;
712 case OMPI_COMM_TYPE_HOST:
713 include = OPAL_PROC_ON_LOCAL_HOST(locality);
714 break;
715 case OMPI_COMM_TYPE_CU:
716 include = OPAL_PROC_ON_LOCAL_CU(locality);
717 break;
718 case OMPI_COMM_TYPE_CLUSTER:
719 include = OPAL_PROC_ON_LOCAL_CLUSTER(locality);
720 break;
721 }
722
723 if (include) {
724 ranks[my_size++] = i;
725 }
726 }
727
728 *rank_size = my_size;
729
730
731 if (OPAL_UNLIKELY(0 == my_size)) {
732 free (ranks);
733 return OMPI_SUCCESS;
734 }
735
736
737 int *tmp = realloc (ranks, my_size * sizeof (int));
738 if (OPAL_LIKELY(NULL != tmp)) {
739 ranks = tmp;
740 }
741
742 *ranks_out = ranks;
743
744 return OMPI_SUCCESS;
745 }
746
747 static int ompi_comm_split_verify (ompi_communicator_t *comm, int split_type, int key, bool *need_split)
748 {
749 int rank = ompi_comm_rank (comm);
750 int size = ompi_comm_size (comm);
751 int *results;
752 int rc;
753
754 if (*need_split) {
755 return OMPI_SUCCESS;
756 }
757
758 results = malloc (2 * sizeof (int) * size);
759 if (OPAL_UNLIKELY(NULL == results)) {
760 return OMPI_ERR_OUT_OF_RESOURCE;
761 }
762
763 *need_split = false;
764
765 results[rank * 2] = split_type;
766 results[rank * 2 + 1] = key;
767
768 rc = comm->c_coll->coll_allgather (MPI_IN_PLACE, 2, MPI_INT, results, 2, MPI_INT, comm,
769 comm->c_coll->coll_allgather_module);
770 if (OMPI_SUCCESS != rc) {
771 free (results);
772 return rc;
773 }
774
775 for (int i = 0 ; i < size ; ++i) {
776 if (MPI_UNDEFINED == results[i * 2] || (i > 1 && results[i * 2 + 1] < results[i * 2 - 1])) {
777 *need_split = true;
778 break;
779 }
780 }
781
782 free (results);
783
784 return OMPI_SUCCESS;
785 }
786
787 int ompi_comm_split_type (ompi_communicator_t *comm, int split_type, int key,
788 opal_info_t *info, ompi_communicator_t **newcomm)
789 {
790 bool need_split = false, no_reorder = false, no_undefined = false;
791 ompi_communicator_t *newcomp = MPI_COMM_NULL;
792 int my_size, my_rsize = 0, mode, inter;
793 int *lranks = NULL, *rranks = NULL;
794 int global_split_type, ok, tmp[4];
795 int rc;
796
797
798 if (OPAL_UNLIKELY(NULL == newcomm)) {
799 return OMPI_ERR_BAD_PARAM;
800 }
801
802 inter = OMPI_COMM_IS_INTER(comm);
803
804
805
806 tmp[0] = split_type;
807 tmp[1] = -split_type;
808 tmp[2] = key;
809 tmp[3] = -key;
810
811 rc = comm->c_coll->coll_allreduce (MPI_IN_PLACE, &tmp, 4, MPI_INT, MPI_MAX, comm,
812 comm->c_coll->coll_allreduce_module);
813 if (OPAL_UNLIKELY(OMPI_SUCCESS != rc)) {
814 return rc;
815 }
816
817 global_split_type = tmp[0];
818
819 if (tmp[0] != -tmp[1] || inter) {
820
821 ok = (MPI_UNDEFINED == split_type) || global_split_type == split_type;
822
823 rc = comm->c_coll->coll_allreduce (MPI_IN_PLACE, &ok, 1, MPI_INT, MPI_MIN, comm,
824 comm->c_coll->coll_allreduce_module);
825 if (OPAL_UNLIKELY(OMPI_SUCCESS != rc)) {
826 return rc;
827 }
828
829 if (inter) {
830
831 rc = comm->c_coll->coll_allreduce (MPI_IN_PLACE, &ok, 1, MPI_INT, MPI_MIN, comm,
832 comm->c_coll->coll_allreduce_module);
833 if (OPAL_UNLIKELY(OMPI_SUCCESS != rc)) {
834 return rc;
835 }
836 }
837
838 if (OPAL_UNLIKELY(!ok)) {
839 return OMPI_ERR_BAD_PARAM;
840 }
841
842 need_split = tmp[0] == -tmp[1];
843 } else {
844
845 no_undefined = true;
846
847 no_reorder = tmp[2] == -tmp[3];
848 }
849
850 if (MPI_UNDEFINED == global_split_type) {
851
852 *newcomm = MPI_COMM_NULL;
853 return OMPI_SUCCESS;
854 }
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882 rc = ompi_comm_split_type_get_part (comm->c_local_group, global_split_type, &lranks, &my_size);
883 if (OPAL_UNLIKELY(OMPI_SUCCESS != rc)) {
884 return rc;
885 }
886
887
888
889 if (inter) {
890 rc = ompi_comm_split_type_get_part (comm->c_remote_group, global_split_type, &rranks, &my_rsize);
891 if (OPAL_UNLIKELY(OMPI_SUCCESS != rc)) {
892 free (lranks);
893 return rc;
894 }
895 }
896
897
898 mode = inter ? OMPI_COMM_CID_INTER : OMPI_COMM_CID_INTRA;
899
900
901
902
903
904 do {
905 rc = ompi_comm_set (&newcomp, comm, my_size, lranks, my_rsize,
906 rranks, NULL, comm->error_handler, false,
907 NULL, NULL);
908 if (OPAL_UNLIKELY(OMPI_SUCCESS != rc)) {
909 break;
910 }
911
912
913 rc = ompi_comm_nextcid (newcomp, comm, NULL, NULL, NULL, false, mode);
914 if (OPAL_UNLIKELY(OMPI_SUCCESS != rc)) {
915 break;
916 }
917
918
919 newcomp->super.s_info = OBJ_NEW(opal_info_t);
920 if (info) {
921 opal_info_dup(info, &(newcomp->super.s_info));
922 }
923
924
925 rc = ompi_comm_activate (&newcomp, comm, NULL, NULL, NULL, false, mode);
926 if (OPAL_UNLIKELY(OMPI_SUCCESS != rc)) {
927 break;
928 }
929
930
931 if (!(no_reorder && no_undefined)) {
932 rc = ompi_comm_split_verify (newcomp, split_type, key, &need_split);
933
934 if (inter) {
935
936 rc = ompi_comm_split_verify (newcomp->c_local_comm, split_type, key, &need_split);
937 }
938 }
939
940 if (!need_split) {
941
942 *newcomm = newcomp;
943
944
945 snprintf(newcomp->c_name, MPI_MAX_OBJECT_NAME, "MPI COMMUNICATOR %d SPLIT_TYPE FROM %d",
946 newcomp->c_contextid, comm->c_contextid );
947 break;
948 }
949
950
951
952 rc = ompi_comm_split (newcomp, split_type, key, newcomm, false);
953
954 ompi_comm_free (&newcomp);
955 } while (0);
956
957 if (OPAL_UNLIKELY(OMPI_SUCCESS != rc && MPI_COMM_NULL != newcomp)) {
958 ompi_comm_free (&newcomp);
959 *newcomm = MPI_COMM_NULL;
960 }
961
962 free (lranks);
963 free (rranks);
964
965 return rc;
966 }
967
968
969
970
971 int ompi_comm_dup ( ompi_communicator_t * comm, ompi_communicator_t **newcomm )
972 {
973 return ompi_comm_dup_with_info (comm, NULL, newcomm);
974 }
975
976
977
978
979 int ompi_comm_dup_with_info ( ompi_communicator_t * comm, opal_info_t *info, ompi_communicator_t **newcomm )
980 {
981 ompi_communicator_t *newcomp = NULL;
982 ompi_group_t *remote_group = NULL;
983 int mode = OMPI_COMM_CID_INTRA, rc = OMPI_SUCCESS;
984
985 if ( OMPI_COMM_IS_INTER ( comm ) ){
986 mode = OMPI_COMM_CID_INTER;
987 remote_group = comm->c_remote_group;
988 }
989
990 *newcomm = MPI_COMM_NULL;
991
992 rc = ompi_comm_set ( &newcomp,
993 comm,
994 0,
995 NULL,
996 0,
997 NULL,
998 comm->c_keyhash,
999 comm->error_handler,
1000 true,
1001 comm->c_local_group,
1002 remote_group );
1003 if ( OMPI_SUCCESS != rc) {
1004 return rc;
1005 }
1006
1007
1008 rc = ompi_comm_nextcid (newcomp, comm, NULL, NULL, NULL, false, mode);
1009 if ( OMPI_SUCCESS != rc ) {
1010 OBJ_RELEASE(newcomp);
1011 return rc;
1012 }
1013
1014
1015 snprintf(newcomp->c_name, MPI_MAX_OBJECT_NAME, "MPI COMMUNICATOR %d DUP FROM %d",
1016 newcomp->c_contextid, comm->c_contextid );
1017
1018
1019 newcomp->super.s_info = OBJ_NEW(opal_info_t);
1020 if (info) {
1021 opal_info_dup(info, &(newcomp->super.s_info));
1022 }
1023
1024
1025 rc = ompi_comm_activate (&newcomp, comm, NULL, NULL, NULL, false, mode);
1026 if ( OMPI_SUCCESS != rc ) {
1027 OBJ_RELEASE(newcomp);
1028 return rc;
1029 }
1030
1031 *newcomm = newcomp;
1032 return MPI_SUCCESS;
1033 }
1034
1035 struct ompi_comm_idup_with_info_context_t {
1036 opal_object_t super;
1037 ompi_communicator_t *comm;
1038 ompi_communicator_t *newcomp;
1039 };
1040
1041 typedef struct ompi_comm_idup_with_info_context_t ompi_comm_idup_with_info_context_t;
1042 OBJ_CLASS_INSTANCE(ompi_comm_idup_with_info_context_t, opal_object_t, NULL, NULL);
1043
1044 static int ompi_comm_idup_with_info_activate (ompi_comm_request_t *request);
1045 static int ompi_comm_idup_with_info_finish (ompi_comm_request_t *request);
1046 static int ompi_comm_idup_getcid (ompi_comm_request_t *request);
1047
1048 int ompi_comm_idup (ompi_communicator_t *comm, ompi_communicator_t **newcomm, ompi_request_t **req)
1049 {
1050 return ompi_comm_idup_with_info (comm, NULL, newcomm, req);
1051 }
1052
1053 int ompi_comm_idup_with_info (ompi_communicator_t *comm, opal_info_t *info, ompi_communicator_t **newcomm, ompi_request_t **req)
1054 {
1055 return ompi_comm_idup_internal (comm, comm->c_local_group, comm->c_remote_group, info, newcomm, req);
1056 }
1057
1058
1059 static int ompi_comm_idup_internal (ompi_communicator_t *comm, ompi_group_t *group, ompi_group_t *remote_group,
1060 opal_info_t *info, ompi_communicator_t **newcomm, ompi_request_t **req)
1061 {
1062 ompi_comm_idup_with_info_context_t *context;
1063 ompi_comm_request_t *request;
1064 ompi_request_t *subreq[1];
1065 int rc;
1066
1067 *newcomm = MPI_COMM_NULL;
1068
1069 if (!OMPI_COMM_IS_INTER (comm)){
1070 remote_group = NULL;
1071 }
1072
1073 request = ompi_comm_request_get ();
1074 if (NULL == request) {
1075 return OMPI_ERR_OUT_OF_RESOURCE;
1076 }
1077
1078 context = OBJ_NEW(ompi_comm_idup_with_info_context_t);
1079 if (NULL == context) {
1080 ompi_comm_request_return (request);
1081 return OMPI_ERR_OUT_OF_RESOURCE;
1082 }
1083
1084 context->comm = comm;
1085
1086 request->context = &context->super;
1087
1088 rc = ompi_comm_set_nb (&context->newcomp,
1089 comm,
1090 0,
1091 NULL,
1092 0,
1093 NULL,
1094 comm->c_keyhash,
1095 comm->error_handler,
1096 true,
1097 group,
1098 remote_group,
1099 subreq);
1100 if (OMPI_SUCCESS != rc) {
1101 ompi_comm_request_return (request);
1102 return rc;
1103 }
1104
1105
1106 {
1107 ompi_communicator_t *newcomp = context->newcomp;
1108 newcomp->super.s_info = OBJ_NEW(opal_info_t);
1109 if (info) {
1110 opal_info_dup(info, &(newcomp->super.s_info));
1111 }
1112 }
1113
1114 ompi_comm_request_schedule_append (request, ompi_comm_idup_getcid, subreq, subreq[0] ? 1 : 0);
1115
1116
1117 *newcomm = context->newcomp;
1118
1119
1120 ompi_comm_request_start (request);
1121 *req = &request->super;
1122
1123 return OMPI_SUCCESS;
1124 }
1125
1126 static int ompi_comm_idup_getcid (ompi_comm_request_t *request)
1127 {
1128 ompi_comm_idup_with_info_context_t *context =
1129 (ompi_comm_idup_with_info_context_t *) request->context;
1130 ompi_request_t *subreq[1];
1131 int rc, mode;
1132
1133 if (OMPI_COMM_IS_INTER(context->comm)){
1134 mode = OMPI_COMM_CID_INTER;
1135 } else {
1136 mode = OMPI_COMM_CID_INTRA;
1137 }
1138
1139
1140 rc = ompi_comm_nextcid_nb (context->newcomp, context->comm, NULL, NULL,
1141 NULL, false, mode, subreq);
1142 if (OMPI_SUCCESS != rc) {
1143 ompi_comm_request_return (request);
1144 OBJ_RELEASE(context->newcomp);
1145 return rc;
1146 }
1147
1148 ompi_comm_request_schedule_append (request, ompi_comm_idup_with_info_activate, subreq, 1);
1149
1150 return OMPI_SUCCESS;
1151 }
1152
1153 static int ompi_comm_idup_with_info_activate (ompi_comm_request_t *request)
1154 {
1155 ompi_comm_idup_with_info_context_t *context =
1156 (ompi_comm_idup_with_info_context_t *) request->context;
1157 ompi_request_t *subreq[1];
1158 int rc, mode;
1159
1160 if (OMPI_COMM_IS_INTER(context->comm)){
1161 mode = OMPI_COMM_CID_INTER;
1162 } else {
1163 mode = OMPI_COMM_CID_INTRA;
1164 }
1165
1166
1167 snprintf(context->newcomp->c_name, MPI_MAX_OBJECT_NAME, "MPI COMMUNICATOR %d DUP FROM %d",
1168 context->newcomp->c_contextid, context->comm->c_contextid );
1169
1170
1171 rc = ompi_comm_activate_nb (&context->newcomp, context->comm, NULL, NULL, NULL, false, mode, subreq);
1172 if ( OMPI_SUCCESS != rc ) {
1173 OBJ_RELEASE(context->newcomp);
1174 return rc;
1175 }
1176
1177 ompi_comm_request_schedule_append (request, ompi_comm_idup_with_info_finish, subreq, 1);
1178
1179 return OMPI_SUCCESS;
1180 }
1181
1182 static int ompi_comm_idup_with_info_finish (ompi_comm_request_t *request)
1183 {
1184
1185 return MPI_SUCCESS;
1186 }
1187
1188
1189
1190
1191 int ompi_comm_create_group (ompi_communicator_t *comm, ompi_group_t *group, int tag, ompi_communicator_t **newcomm)
1192 {
1193 ompi_communicator_t *newcomp = NULL;
1194 int mode = OMPI_COMM_CID_GROUP, rc = OMPI_SUCCESS;
1195
1196 *newcomm = MPI_COMM_NULL;
1197
1198 rc = ompi_comm_set ( &newcomp,
1199 comm,
1200 group->grp_proc_count,
1201 NULL,
1202 0,
1203 NULL,
1204 comm->c_keyhash,
1205 comm->error_handler,
1206 true,
1207 group,
1208 NULL);
1209 if ( OMPI_SUCCESS != rc) {
1210 return rc;
1211 }
1212
1213
1214 rc = ompi_comm_nextcid (newcomp, comm, NULL, &tag, NULL, false, mode);
1215 if ( OMPI_SUCCESS != rc ) {
1216 OBJ_RELEASE(newcomp);
1217 return rc;
1218 }
1219
1220
1221 snprintf(newcomp->c_name, MPI_MAX_OBJECT_NAME, "MPI COMMUNICATOR %d GROUP FROM %d",
1222 newcomp->c_contextid, comm->c_contextid );
1223
1224
1225 rc = ompi_comm_activate (&newcomp, comm, NULL, &tag, NULL, false, mode);
1226 if ( OMPI_SUCCESS != rc ) {
1227 OBJ_RELEASE(newcomp);
1228 return rc;
1229 }
1230
1231 *newcomm = newcomp;
1232 return MPI_SUCCESS;
1233 }
1234
1235
1236
1237
1238 int ompi_comm_compare(ompi_communicator_t *comm1, ompi_communicator_t *comm2, int *result) {
1239
1240 ompi_communicator_t *comp1, *comp2;
1241 int size1, size2, rsize1, rsize2;
1242 int lresult, rresult=MPI_CONGRUENT;
1243 int cmp_result;
1244
1245 comp1 = (ompi_communicator_t *) comm1;
1246 comp2 = (ompi_communicator_t *) comm2;
1247
1248 if ( comp1->c_contextid == comp2->c_contextid ) {
1249 *result = MPI_IDENT;
1250 return MPI_SUCCESS;
1251 }
1252
1253 if ( MPI_COMM_NULL == comm1 || MPI_COMM_NULL == comm2 ) {
1254 *result = MPI_UNEQUAL;
1255 return MPI_SUCCESS;
1256 }
1257
1258
1259 size1 = ompi_comm_size (comp1);
1260 size2 = ompi_comm_size (comp2);
1261 rsize1 = ompi_comm_remote_size (comp1);
1262 rsize2 = ompi_comm_remote_size (comp2);
1263
1264 if ( size1 != size2 || rsize1 != rsize2 ) {
1265 *result = MPI_UNEQUAL;
1266 return MPI_SUCCESS;
1267 }
1268
1269
1270 ompi_group_compare((ompi_group_t *)comp1->c_local_group,
1271 (ompi_group_t *)comp2->c_local_group,
1272 &cmp_result);
1273
1274
1275
1276
1277
1278 if( MPI_IDENT == cmp_result ) {
1279 lresult = MPI_CONGRUENT;
1280 } else {
1281 lresult = cmp_result;
1282 }
1283
1284
1285 if ( rsize1 > 0 ) {
1286
1287 ompi_group_compare((ompi_group_t *)comp1->c_remote_group,
1288 (ompi_group_t *)comp2->c_remote_group,
1289 &cmp_result);
1290
1291
1292
1293
1294
1295 if( MPI_IDENT == cmp_result ) {
1296 rresult = MPI_CONGRUENT;
1297 } else {
1298 rresult = cmp_result;
1299 }
1300 }
1301
1302
1303 if ( MPI_CONGRUENT == rresult ) {
1304 *result = lresult;
1305 }
1306 else if ( MPI_SIMILAR == rresult ) {
1307 if ( MPI_SIMILAR == lresult || MPI_CONGRUENT == lresult ) {
1308 *result = MPI_SIMILAR;
1309 }
1310 else {
1311 *result = MPI_UNEQUAL;
1312 }
1313 }
1314 else if ( MPI_UNEQUAL == rresult ) {
1315 *result = MPI_UNEQUAL;
1316 }
1317
1318 return OMPI_SUCCESS;
1319 }
1320
1321
1322
1323 int ompi_comm_set_name (ompi_communicator_t *comm, const char *name )
1324 {
1325
1326 OPAL_THREAD_LOCK(&(comm->c_lock));
1327 opal_string_copy(comm->c_name, name, MPI_MAX_OBJECT_NAME);
1328 comm->c_flags |= OMPI_COMM_NAMEISSET;
1329 OPAL_THREAD_UNLOCK(&(comm->c_lock));
1330
1331 return OMPI_SUCCESS;
1332 }
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343 static int ompi_comm_allgather_emulate_intra( void *inbuf, int incount,
1344 MPI_Datatype intype, void* outbuf,
1345 int outcount, MPI_Datatype outtype,
1346 ompi_communicator_t *comm,
1347 mca_coll_base_module_t *data)
1348 {
1349 int rank, size, rsize, i, rc;
1350 int *tmpbuf=NULL;
1351 MPI_Request *req=NULL, sendreq;
1352
1353 rsize = ompi_comm_remote_size(comm);
1354 size = ompi_comm_size(comm);
1355 rank = ompi_comm_rank(comm);
1356
1357
1358
1359 if (OPAL_UNLIKELY(0 == rsize || 0 == outcount)) {
1360 return OMPI_ERR_BAD_PARAM;
1361 }
1362
1363
1364 if ( 0 == rank ) {
1365 tmpbuf = (int *) malloc (rsize*outcount*sizeof(int));
1366 if ( NULL == tmpbuf ) {
1367 return (OMPI_ERR_OUT_OF_RESOURCE);
1368 }
1369 req = (MPI_Request *)malloc (rsize*outcount*sizeof(MPI_Request));
1370 if ( NULL == req ) {
1371 free ( tmpbuf );
1372 return (OMPI_ERR_OUT_OF_RESOURCE);
1373 }
1374
1375 for ( i=0; i<rsize; i++) {
1376 rc = MCA_PML_CALL(irecv( &tmpbuf[outcount*i], outcount, outtype, i,
1377 OMPI_COMM_ALLGATHER_TAG, comm, &req[i] ));
1378 if ( OMPI_SUCCESS != rc ) {
1379 goto exit;
1380 }
1381 }
1382 }
1383 rc = MCA_PML_CALL(isend( inbuf, incount, intype, 0, OMPI_COMM_ALLGATHER_TAG,
1384 MCA_PML_BASE_SEND_STANDARD, comm, &sendreq ));
1385 if ( OMPI_SUCCESS != rc ) {
1386 goto exit;
1387 }
1388
1389 if ( 0 == rank ) {
1390 rc = ompi_request_wait_all( rsize, req, MPI_STATUSES_IGNORE);
1391 if ( OMPI_SUCCESS != rc ) {
1392 goto exit;
1393 }
1394 }
1395
1396 rc = ompi_request_wait( &sendreq, MPI_STATUS_IGNORE);
1397 if ( OMPI_SUCCESS != rc ) {
1398 goto exit;
1399 }
1400
1401
1402 rc = MCA_PML_CALL(irecv (outbuf, size*outcount, outtype, 0,
1403 OMPI_COMM_ALLGATHER_TAG, comm, &sendreq));
1404 if ( OMPI_SUCCESS != rc ) {
1405 goto exit;
1406 }
1407
1408 if ( 0 == rank ) {
1409 for ( i=0; i < rsize; i++ ){
1410 rc = MCA_PML_CALL(send (tmpbuf, rsize*outcount, outtype, i,
1411 OMPI_COMM_ALLGATHER_TAG,
1412 MCA_PML_BASE_SEND_STANDARD, comm));
1413 if ( OMPI_SUCCESS != rc ) {
1414 goto exit;
1415 }
1416 }
1417 }
1418
1419 rc = ompi_request_wait( &sendreq, MPI_STATUS_IGNORE );
1420
1421 exit:
1422 if ( NULL != req ) {
1423 free ( req );
1424 }
1425 if ( NULL != tmpbuf ) {
1426 free ( tmpbuf );
1427 }
1428
1429 return (rc);
1430 }
1431
1432
1433
1434
1435
1436
1437
1438
1439 int ompi_comm_free( ompi_communicator_t **comm )
1440 {
1441 int ret;
1442 int cid = (*comm)->c_contextid;
1443 int is_extra_retain = OMPI_COMM_IS_EXTRA_RETAIN(*comm);
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463 if (NULL != (*comm)->c_keyhash) {
1464 ret = ompi_attr_delete_all(COMM_ATTR, *comm, (*comm)->c_keyhash);
1465 if (OMPI_SUCCESS != ret) {
1466 return ret;
1467 }
1468 OBJ_RELEASE((*comm)->c_keyhash);
1469 }
1470
1471 if ( OMPI_COMM_IS_INTER(*comm) ) {
1472 if ( ! OMPI_COMM_IS_INTRINSIC((*comm)->c_local_comm)) {
1473 ompi_comm_free (&(*comm)->c_local_comm);
1474 }
1475 }
1476
1477
1478
1479
1480
1481 if (*comm == ompi_mpi_comm_parent && comm != &ompi_mpi_comm_parent) {
1482 ompi_mpi_comm_parent = &ompi_mpi_comm_null.comm;
1483 }
1484
1485 if (NULL != ((*comm)->super.s_info)) {
1486 OBJ_RELEASE((*comm)->super.s_info);
1487 }
1488
1489
1490 if ( OMPI_COMM_IS_DYNAMIC (*comm) ) {
1491 ompi_comm_num_dyncomm --;
1492 }
1493 OBJ_RELEASE( (*comm) );
1494
1495 if ( is_extra_retain) {
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512 ompi_communicator_t *tmpcomm = (ompi_communicator_t *) opal_pointer_array_get_item(&ompi_mpi_communicators, cid);
1513 if ( NULL != tmpcomm ){
1514 ompi_comm_free(&tmpcomm);
1515 }
1516 }
1517
1518 *comm = MPI_COMM_NULL;
1519 return OMPI_SUCCESS;
1520 }
1521
1522
1523
1524
1525 int ompi_comm_get_rprocs ( ompi_communicator_t *local_comm,
1526 ompi_communicator_t *bridge_comm,
1527 int local_leader,
1528 int remote_leader,
1529 int tag,
1530 int rsize,
1531 ompi_proc_t ***prprocs )
1532 {
1533 MPI_Request req;
1534 int rc = OMPI_SUCCESS;
1535 int local_rank, local_size;
1536 ompi_proc_t **rprocs=NULL;
1537 int32_t size_len;
1538 int int_len=0, rlen;
1539 opal_buffer_t *sbuf=NULL, *rbuf=NULL;
1540 void *sendbuf=NULL;
1541 char *recvbuf;
1542 ompi_proc_t **proc_list=NULL;
1543 int i;
1544
1545 local_rank = ompi_comm_rank (local_comm);
1546 local_size = ompi_comm_size (local_comm);
1547
1548 if (local_rank == local_leader) {
1549 sbuf = OBJ_NEW(opal_buffer_t);
1550 if (NULL == sbuf) {
1551 rc = OMPI_ERR_OUT_OF_RESOURCE;
1552 goto err_exit;
1553 }
1554 if(OMPI_GROUP_IS_DENSE(local_comm->c_local_group)) {
1555 rc = ompi_proc_pack(local_comm->c_local_group->grp_proc_pointers,
1556 local_size, sbuf);
1557 }
1558
1559 else {
1560 proc_list = (ompi_proc_t **) calloc (local_comm->c_local_group->grp_proc_count,
1561 sizeof (ompi_proc_t *));
1562 for(i=0 ; i<local_comm->c_local_group->grp_proc_count ; i++)
1563 proc_list[i] = ompi_group_peer_lookup(local_comm->c_local_group,i);
1564 rc = ompi_proc_pack (proc_list, local_size, sbuf);
1565 }
1566 if ( OMPI_SUCCESS != rc ) {
1567 goto err_exit;
1568 }
1569 if (OPAL_SUCCESS != (rc = opal_dss.unload(sbuf, &sendbuf, &size_len))) {
1570 goto err_exit;
1571 }
1572
1573
1574 rc = MCA_PML_CALL(irecv (&rlen, 1, MPI_INT, remote_leader, tag,
1575 bridge_comm, &req ));
1576 if ( OMPI_SUCCESS != rc ) {
1577 goto err_exit;
1578 }
1579 int_len = (int)size_len;
1580
1581 rc = MCA_PML_CALL(send (&int_len, 1, MPI_INT, remote_leader, tag,
1582 MCA_PML_BASE_SEND_STANDARD, bridge_comm ));
1583 if ( OMPI_SUCCESS != rc ) {
1584 goto err_exit;
1585 }
1586 rc = ompi_request_wait( &req, MPI_STATUS_IGNORE );
1587 if ( OMPI_SUCCESS != rc ) {
1588 goto err_exit;
1589 }
1590 }
1591
1592
1593 rc = local_comm->c_coll->coll_bcast( &rlen, 1, MPI_INT,
1594 local_leader, local_comm,
1595 local_comm->c_coll->coll_bcast_module );
1596 if ( OMPI_SUCCESS != rc ) {
1597 goto err_exit;
1598 }
1599
1600
1601 recvbuf = (char *)malloc(rlen);
1602 if ( NULL == recvbuf ) {
1603 rc = OMPI_ERR_OUT_OF_RESOURCE;
1604 goto err_exit;
1605 }
1606
1607 if ( local_rank == local_leader ) {
1608
1609 rc = MCA_PML_CALL(irecv (recvbuf, rlen, MPI_BYTE, remote_leader, tag,
1610 bridge_comm, &req ));
1611 if ( OMPI_SUCCESS != rc ) {
1612 goto err_exit;
1613 }
1614 rc = MCA_PML_CALL(send(sendbuf, int_len, MPI_BYTE, remote_leader, tag,
1615 MCA_PML_BASE_SEND_STANDARD, bridge_comm ));
1616 if ( OMPI_SUCCESS != rc ) {
1617 goto err_exit;
1618 }
1619 rc = ompi_request_wait( &req, MPI_STATUS_IGNORE );
1620 if ( OMPI_SUCCESS != rc ) {
1621 goto err_exit;
1622 }
1623 }
1624
1625
1626 rc = local_comm->c_coll->coll_bcast( recvbuf, rlen, MPI_BYTE,
1627 local_leader, local_comm,
1628 local_comm->c_coll->coll_bcast_module);
1629 if ( OMPI_SUCCESS != rc ) {
1630 goto err_exit;
1631 }
1632
1633 rbuf = OBJ_NEW(opal_buffer_t);
1634 if (NULL == rbuf) {
1635 rc = OMPI_ERR_OUT_OF_RESOURCE;
1636 goto err_exit;
1637 }
1638
1639 if (OMPI_SUCCESS != (rc = opal_dss.load(rbuf, recvbuf, rlen))) {
1640 goto err_exit;
1641 }
1642
1643
1644
1645
1646 rc = ompi_proc_unpack(rbuf, rsize, &rprocs, NULL, NULL);
1647 OBJ_RELEASE(rbuf);
1648 if (OMPI_SUCCESS != rc) {
1649 goto err_exit;
1650 }
1651
1652
1653 for (i=0; i < rsize; i++) {
1654
1655
1656 uint16_t *u16ptr, u16;
1657 u16ptr = &u16;
1658 OPAL_MODEX_RECV_VALUE(rc, OPAL_PMIX_LOCALITY, &rprocs[i]->super.proc_name, &u16ptr, OPAL_UINT16);
1659 if (OPAL_SUCCESS == rc) {
1660 rprocs[i]->super.proc_flags = u16;
1661 } else {
1662 rprocs[i]->super.proc_flags = OPAL_PROC_NON_LOCAL;
1663 }
1664 }
1665
1666
1667 if (OMPI_SUCCESS != (rc = MCA_PML_CALL(add_procs(rprocs, rsize)))) {
1668 goto err_exit;
1669 }
1670
1671 err_exit:
1672
1673
1674 if ( OMPI_SUCCESS != rc ) {
1675 OMPI_ERROR_LOG(rc);
1676 opal_output(0, "%d: Error in ompi_get_rprocs\n", local_rank);
1677 if ( NULL != rprocs ) {
1678 free ( rprocs );
1679 rprocs=NULL;
1680 }
1681 }
1682
1683 if (NULL != sbuf) {
1684 OBJ_RELEASE(sbuf);
1685 }
1686 if (NULL != rbuf) {
1687 OBJ_RELEASE(rbuf);
1688 }
1689 if ( NULL != proc_list ) {
1690 free ( proc_list );
1691 }
1692 if (NULL != sendbuf) {
1693 free ( sendbuf );
1694 }
1695
1696 *prprocs = rprocs;
1697 return rc;
1698 }
1699
1700
1701
1702
1703
1704
1705
1706 int ompi_comm_overlapping_groups (int size, ompi_proc_t **lprocs,
1707 int rsize, ompi_proc_t ** rprocs)
1708
1709 {
1710 int rc=OMPI_SUCCESS;
1711 int i,j;
1712
1713 for (i=0; i<size; i++) {
1714 for ( j=0; j<rsize; j++) {
1715 if ( lprocs[i] == rprocs[j] ) {
1716 rc = MPI_ERR_COMM;
1717 return rc;
1718 }
1719 }
1720 }
1721
1722 return rc;
1723 }
1724
1725
1726
1727 int ompi_comm_determine_first ( ompi_communicator_t *intercomm, int high )
1728 {
1729 int flag, rhigh;
1730 int rank, rsize;
1731 int *rcounts;
1732 int *rdisps;
1733 int scount=0;
1734 int rc;
1735 ompi_proc_t *ourproc, *theirproc;
1736 ompi_rte_cmp_bitmask_t mask;
1737
1738 rank = ompi_comm_rank (intercomm);
1739 rsize= ompi_comm_remote_size (intercomm);
1740
1741
1742 if (OPAL_UNLIKELY(0 == rsize)) {
1743 return OMPI_ERR_BAD_PARAM;
1744 }
1745
1746 rdisps = (int *) calloc ( rsize, sizeof(int));
1747 if ( NULL == rdisps ){
1748 return OMPI_ERR_OUT_OF_RESOURCE;
1749 }
1750
1751 rcounts = (int *) calloc ( rsize, sizeof(int));
1752 if ( NULL == rcounts ){
1753 free (rdisps);
1754 return OMPI_ERR_OUT_OF_RESOURCE;
1755 }
1756
1757 rcounts[0] = 1;
1758 if ( 0 == rank ) {
1759 scount = 1;
1760 }
1761
1762 rc = intercomm->c_coll->coll_allgatherv(&high, scount, MPI_INT,
1763 &rhigh, rcounts, rdisps,
1764 MPI_INT, intercomm,
1765 intercomm->c_coll->coll_allgatherv_module);
1766 if ( NULL != rdisps ) {
1767 free ( rdisps );
1768 }
1769 if ( NULL != rcounts ) {
1770 free ( rcounts );
1771 }
1772
1773 if ( rc != OMPI_SUCCESS ) {
1774 return rc;
1775 }
1776
1777
1778 if ( high && !rhigh ) {
1779 flag = false;
1780 }
1781 else if ( !high && rhigh ) {
1782 flag = true;
1783 }
1784 else {
1785 ourproc = ompi_group_peer_lookup(intercomm->c_local_group,0);
1786 theirproc = ompi_group_peer_lookup(intercomm->c_remote_group,0);
1787
1788 mask = OMPI_RTE_CMP_JOBID | OMPI_RTE_CMP_VPID;
1789 rc = ompi_rte_compare_name_fields(mask, (const ompi_process_name_t*)&(ourproc->super.proc_name),
1790 (const ompi_process_name_t*)&(theirproc->super.proc_name));
1791 if ( 0 > rc ) {
1792 flag = true;
1793 }
1794 else {
1795 flag = false;
1796 }
1797 }
1798
1799 return flag;
1800 }
1801
1802
1803
1804 int ompi_comm_dump ( ompi_communicator_t *comm )
1805 {
1806 opal_output(0, "Dumping information for comm_cid %d\n", comm->c_contextid);
1807 opal_output(0," f2c index:%d cube_dim: %d\n", comm->c_f_to_c_index,
1808 comm->c_cube_dim);
1809 opal_output(0," Local group: size = %d my_rank = %d\n",
1810 comm->c_local_group->grp_proc_count,
1811 comm->c_local_group->grp_my_rank );
1812
1813 opal_output(0," Communicator is:");
1814
1815 if ( OMPI_COMM_IS_INTER(comm) )
1816 opal_output(0," inter-comm,");
1817 if ( OMPI_COMM_IS_CART(comm))
1818 opal_output(0," topo-cart");
1819 else if ( OMPI_COMM_IS_GRAPH(comm))
1820 opal_output(0," topo-graph");
1821 else if ( OMPI_COMM_IS_DIST_GRAPH(comm))
1822 opal_output(0," topo-dist-graph");
1823 opal_output(0,"\n");
1824
1825 if (OMPI_COMM_IS_INTER(comm)) {
1826 opal_output(0," Remote group size:%d\n", comm->c_remote_group->grp_proc_count);
1827 }
1828 return OMPI_SUCCESS;
1829 }
1830
1831
1832
1833
1834
1835
1836
1837
1838 static int rankkeycompare (const void *p, const void *q)
1839 {
1840 int *a, *b;
1841
1842
1843
1844 a = (int*)p;
1845 b = (int*)q;
1846
1847
1848 if (a[1] < b[1]) {
1849 return (-1);
1850 }
1851 if (a[1] > b[1]) {
1852 return (1);
1853 }
1854
1855
1856 if (a[1] == b[1]) {
1857 if (a[0] < b[0]) {
1858 return (-1);
1859 }
1860 if (a[0] == b[0]) {
1861 return (0);
1862 }
1863 if (a[0] > b[0]) {
1864 return (1);
1865 }
1866 }
1867 return ( 0 );
1868 }
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887 int ompi_comm_enable(ompi_communicator_t *old_comm,
1888 ompi_communicator_t *new_comm,
1889 int new_rank,
1890 int num_procs,
1891 ompi_proc_t** topo_procs)
1892 {
1893 int ret = OMPI_SUCCESS;
1894
1895
1896 new_comm->c_local_group->grp_my_rank = new_rank;
1897 new_comm->c_my_rank = new_rank;
1898
1899
1900 ret = ompi_comm_nextcid (new_comm, old_comm, NULL, NULL, NULL, false,
1901 OMPI_COMM_CID_INTRA);
1902 if (OMPI_SUCCESS != ret) {
1903
1904 goto complete_and_return;
1905 }
1906
1907
1908
1909
1910
1911
1912
1913 ret = ompi_comm_fill_rest(new_comm,
1914 num_procs,
1915 topo_procs,
1916 new_rank,
1917 old_comm->error_handler);
1918
1919 if (OMPI_SUCCESS != ret) {
1920
1921 goto complete_and_return;
1922 }
1923
1924 ret = ompi_comm_activate (&new_comm, old_comm, NULL, NULL, NULL, false,
1925 OMPI_COMM_CID_INTRA);
1926 if (OMPI_SUCCESS != ret) {
1927
1928 goto complete_and_return;
1929 }
1930
1931 complete_and_return:
1932 return ret;
1933 }
1934
1935 static int ompi_comm_fill_rest(ompi_communicator_t *comm,
1936 int num_procs,
1937 ompi_proc_t **proc_pointers,
1938 int my_rank,
1939 ompi_errhandler_t *errh)
1940 {
1941
1942
1943
1944
1945
1946
1947 if (comm->c_local_group) {
1948 OBJ_RELEASE( comm->c_local_group );
1949 }
1950
1951 if (comm->c_remote_group) {
1952 OBJ_RELEASE( comm->c_remote_group );
1953 }
1954
1955
1956 comm->c_local_group = ompi_group_allocate_plist_w_procs (proc_pointers, num_procs);
1957
1958
1959 comm->c_remote_group = comm->c_local_group;
1960 OBJ_RETAIN( comm->c_remote_group );
1961
1962
1963 comm->c_local_group->grp_my_rank = my_rank;
1964 comm->c_my_rank = my_rank;
1965
1966 if( MPI_UNDEFINED != my_rank ) {
1967
1968
1969 ompi_dpm_mark_dyncomm (comm);
1970 }
1971
1972
1973 comm->error_handler = errh;
1974 OBJ_RETAIN (comm->error_handler);
1975
1976
1977
1978
1979
1980 snprintf (comm->c_name, MPI_MAX_OBJECT_NAME, "MPI_COMMUNICATOR %d",
1981 comm->c_contextid);
1982
1983
1984 comm->c_cube_dim = opal_cube_dim(comm->c_local_group->grp_proc_count);
1985
1986 return OMPI_SUCCESS;
1987 }
1988
1989 static int ompi_comm_copy_topo(ompi_communicator_t *oldcomm,
1990 ompi_communicator_t *newcomm)
1991 {
1992 if( NULL == oldcomm->c_topo )
1993 return OMPI_ERR_NOT_FOUND;
1994
1995 newcomm->c_topo = oldcomm->c_topo;
1996 OBJ_RETAIN(newcomm->c_topo);
1997 newcomm->c_flags |= newcomm->c_topo->type;
1998 return OMPI_SUCCESS;
1999 }