This source file includes following definitions.
- MPI_Intercomm_create
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 #include "ompi_config.h"
28
29 #include "ompi/mpi/c/bindings.h"
30 #include "ompi/runtime/params.h"
31 #include "ompi/errhandler/errhandler.h"
32 #include "ompi/mca/pml/pml.h"
33 #include "ompi/communicator/communicator.h"
34 #include "ompi/request/request.h"
35 #include "ompi/memchecker.h"
36
37 #if OMPI_BUILD_MPI_PROFILING
38 #if OPAL_HAVE_WEAK_SYMBOLS
39 #pragma weak MPI_Intercomm_create = PMPI_Intercomm_create
40 #endif
41 #define MPI_Intercomm_create PMPI_Intercomm_create
42 #endif
43
44 static const char FUNC_NAME[] = "MPI_Intercomm_create";
45
46
47 int MPI_Intercomm_create(MPI_Comm local_comm, int local_leader,
48 MPI_Comm bridge_comm, int remote_leader,
49 int tag, MPI_Comm *newintercomm)
50 {
51 int local_size=0, local_rank=0;
52 int lleader=0, rleader=0;
53 ompi_communicator_t *newcomp=NULL;
54 struct ompi_proc_t **rprocs=NULL;
55 int rc=0, rsize=0;
56 ompi_proc_t **proc_list=NULL;
57 int j;
58 ompi_group_t *new_group_pointer;
59
60 MEMCHECKER(
61 memchecker_comm(local_comm);
62 memchecker_comm(bridge_comm);
63 );
64
65 if ( MPI_PARAM_CHECK ) {
66 OMPI_ERR_INIT_FINALIZE(FUNC_NAME);
67
68 if ( ompi_comm_invalid ( local_comm ) ||
69 ( local_comm->c_flags & OMPI_COMM_INTER ) )
70 return OMPI_ERRHANDLER_INVOKE ( MPI_COMM_WORLD, MPI_ERR_COMM,
71 FUNC_NAME);
72
73 if ( NULL == newintercomm )
74 return OMPI_ERRHANDLER_INVOKE ( local_comm, MPI_ERR_ARG,
75 FUNC_NAME);
76
77
78
79
80
81 }
82
83 OPAL_CR_ENTER_LIBRARY();
84
85 local_size = ompi_comm_size ( local_comm );
86 local_rank = ompi_comm_rank ( local_comm );
87 lleader = local_leader;
88 rleader = remote_leader;
89
90 if ( MPI_PARAM_CHECK ) {
91 if ( (0 > local_leader) || (local_leader >= local_size) )
92 return OMPI_ERRHANDLER_INVOKE ( local_comm, MPI_ERR_ARG,
93 FUNC_NAME);
94
95
96
97 if ( local_rank == local_leader ) {
98 if ( ompi_comm_invalid ( bridge_comm ) ||
99 (bridge_comm->c_flags & OMPI_COMM_INTER) ) {
100 OPAL_CR_EXIT_LIBRARY();
101 return OMPI_ERRHANDLER_INVOKE ( local_comm, MPI_ERR_COMM,
102 FUNC_NAME);
103 }
104 if ( (remote_leader < 0) || (remote_leader >= ompi_comm_size(bridge_comm))) {
105 OPAL_CR_EXIT_LIBRARY();
106 return OMPI_ERRHANDLER_INVOKE ( local_comm, MPI_ERR_ARG,
107 FUNC_NAME);
108 }
109 }
110 }
111
112 if ( local_rank == local_leader ) {
113 MPI_Request req;
114
115
116 rc = MCA_PML_CALL(irecv(&rsize, 1, MPI_INT, rleader, tag, bridge_comm,
117 &req));
118 if ( rc != MPI_SUCCESS ) {
119 goto err_exit;
120 }
121 rc = MCA_PML_CALL(send (&local_size, 1, MPI_INT, rleader, tag,
122 MCA_PML_BASE_SEND_STANDARD, bridge_comm));
123 if ( rc != MPI_SUCCESS ) {
124 goto err_exit;
125 }
126 rc = ompi_request_wait( &req, MPI_STATUS_IGNORE);
127 if ( rc != MPI_SUCCESS ) {
128 goto err_exit;
129 }
130 }
131
132
133 rc = local_comm->c_coll->coll_bcast ( &rsize, 1, MPI_INT, lleader,
134 local_comm,
135 local_comm->c_coll->coll_bcast_module);
136 if ( rc != MPI_SUCCESS ) {
137 goto err_exit;
138 }
139
140 rc = ompi_comm_get_rprocs( local_comm, bridge_comm, lleader,
141 remote_leader, tag, rsize, &rprocs );
142 if ( OMPI_SUCCESS != rc ) {
143 goto err_exit;
144 }
145
146 if ( MPI_PARAM_CHECK ) {
147 if(OMPI_GROUP_IS_DENSE(local_comm->c_local_group)) {
148 rc = ompi_comm_overlapping_groups(local_comm->c_local_group->grp_proc_count,
149 local_comm->c_local_group->grp_proc_pointers,
150 rsize,
151 rprocs);
152 }
153 else {
154 proc_list = (ompi_proc_t **) calloc (local_comm->c_local_group->grp_proc_count,
155 sizeof (ompi_proc_t *));
156 for(j=0 ; j<local_comm->c_local_group->grp_proc_count ; j++) {
157 proc_list[j] = ompi_group_peer_lookup(local_comm->c_local_group,j);
158 }
159 rc = ompi_comm_overlapping_groups(local_comm->c_local_group->grp_proc_count,
160 proc_list,
161 rsize,
162 rprocs);
163 }
164 if ( OMPI_SUCCESS != rc ) {
165 goto err_exit;
166 }
167 }
168 new_group_pointer = ompi_group_allocate(rsize);
169 if( NULL == new_group_pointer ) {
170 rc = MPI_ERR_GROUP;
171 goto err_exit;
172 }
173
174
175 for (j = 0; j < rsize; j++) {
176 new_group_pointer->grp_proc_pointers[j] = rprocs[j];
177 OBJ_RETAIN(rprocs[j]);
178 }
179
180 rc = ompi_comm_set ( &newcomp,
181 local_comm,
182 local_comm->c_local_group->grp_proc_count,
183 NULL,
184 rsize,
185 NULL,
186 NULL,
187 local_comm->error_handler,
188 false,
189 local_comm->c_local_group,
190 new_group_pointer
191 );
192
193 if ( MPI_SUCCESS != rc ) {
194 goto err_exit;
195 }
196
197 OBJ_RELEASE(new_group_pointer);
198 new_group_pointer = MPI_GROUP_NULL;
199
200
201 rc = ompi_comm_nextcid (newcomp, local_comm, bridge_comm, &lleader,
202 &rleader, false, OMPI_COMM_CID_INTRA_BRIDGE);
203 if ( MPI_SUCCESS != rc ) {
204 goto err_exit;
205 }
206
207
208 rc = ompi_comm_activate (&newcomp, local_comm, bridge_comm, &lleader, &rleader,
209 false, OMPI_COMM_CID_INTRA_BRIDGE);
210 if ( MPI_SUCCESS != rc ) {
211 goto err_exit;
212 }
213
214 err_exit:
215 OPAL_CR_EXIT_LIBRARY();
216
217 if ( NULL != rprocs ) {
218 free ( rprocs );
219 }
220 if ( NULL != proc_list ) {
221 free ( proc_list );
222 }
223 if ( OMPI_SUCCESS != rc ) {
224 *newintercomm = MPI_COMM_NULL;
225 return OMPI_ERRHANDLER_INVOKE(local_comm, rc,
226 FUNC_NAME);
227 }
228
229 *newintercomm = newcomp;
230 return MPI_SUCCESS;
231 }
232