This source file includes following definitions.
- MPI_Comm_spawn_multiple
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 #include "ompi_config.h"
27 #include <stdio.h>
28
29 #include "opal/util/show_help.h"
30
31 #include "ompi/mpi/c/bindings.h"
32 #include "ompi/runtime/params.h"
33 #include "ompi/runtime/mpiruntime.h"
34 #include "ompi/communicator/communicator.h"
35 #include "ompi/errhandler/errhandler.h"
36 #include "ompi/info/info.h"
37 #include "ompi/dpm/dpm.h"
38 #include "ompi/memchecker.h"
39
40 #if OMPI_BUILD_MPI_PROFILING
41 #if OPAL_HAVE_WEAK_SYMBOLS
42 #pragma weak MPI_Comm_spawn_multiple = PMPI_Comm_spawn_multiple
43 #endif
44 #define MPI_Comm_spawn_multiple PMPI_Comm_spawn_multiple
45 #endif
46
47 static const char FUNC_NAME[] = "MPI_Comm_spawn_multiple";
48
49
50 int MPI_Comm_spawn_multiple(int count, char *array_of_commands[], char **array_of_argv[],
51 const int array_of_maxprocs[], const MPI_Info array_of_info[],
52 int root, MPI_Comm comm, MPI_Comm *intercomm,
53 int array_of_errcodes[])
54 {
55 int i=0, rc=0, rank=0, size=0, flag;
56 ompi_communicator_t *newcomp=NULL;
57 bool send_first=false;
58 char port_name[MPI_MAX_PORT_NAME];
59 bool non_mpi = false, cumulative = false;
60
61 MEMCHECKER(
62 memchecker_comm(comm);
63 );
64
65 if ( MPI_PARAM_CHECK ) {
66 OMPI_ERR_INIT_FINALIZE(FUNC_NAME);
67
68 if ( ompi_comm_invalid (comm)) {
69 return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_COMM,
70 FUNC_NAME);
71 }
72 if ( OMPI_COMM_IS_INTER(comm)) {
73 return OMPI_ERRHANDLER_INVOKE(comm, MPI_ERR_COMM, FUNC_NAME);
74 }
75 if ( (0 > root) || (ompi_comm_size(comm) <= root) ) {
76 return OMPI_ERRHANDLER_INVOKE(comm, MPI_ERR_ARG, FUNC_NAME);
77 }
78 if ( NULL == intercomm ) {
79 return OMPI_ERRHANDLER_INVOKE(comm, MPI_ERR_ARG, FUNC_NAME);
80 }
81 }
82
83 rank = ompi_comm_rank ( comm );
84 if ( MPI_PARAM_CHECK ) {
85 if ( rank == root ) {
86 if ( 0 > count ) {
87 return OMPI_ERRHANDLER_INVOKE(comm, MPI_ERR_ARG, FUNC_NAME);
88 }
89 if ( NULL == array_of_commands ) {
90 return OMPI_ERRHANDLER_INVOKE(comm, MPI_ERR_ARG, FUNC_NAME);
91 }
92 if ( NULL == array_of_maxprocs ) {
93 return OMPI_ERRHANDLER_INVOKE(comm, MPI_ERR_ARG, FUNC_NAME);
94 }
95 if ( NULL == array_of_info ) {
96 return OMPI_ERRHANDLER_INVOKE(comm, MPI_ERR_INFO, FUNC_NAME);
97 }
98 for (i = 0; i < count; ++i) {
99 if (NULL == array_of_info[i] ||
100 ompi_info_is_freed(array_of_info[i])) {
101 return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_INFO,
102 FUNC_NAME);
103 }
104
105
106
107
108 ompi_info_get_bool(array_of_info[i], "ompi_non_mpi", &non_mpi,
109 &flag);
110 if (flag && 0 == i) {
111
112
113 cumulative = non_mpi;
114 } else if (!flag) {
115 non_mpi = false;
116 }
117
118
119 if (cumulative != non_mpi) {
120 return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD,
121 MPI_ERR_INFO,
122 FUNC_NAME);
123 }
124 }
125 for ( i=0; i<count; i++ ) {
126 if ( NULL == array_of_commands[i] ) {
127 return OMPI_ERRHANDLER_INVOKE(comm, MPI_ERR_ARG, FUNC_NAME);
128 }
129 if ( 0 > array_of_maxprocs[i] ) {
130 return OMPI_ERRHANDLER_INVOKE(comm, MPI_ERR_ARG, FUNC_NAME);
131 }
132 }
133 }
134 }
135
136 if (!ompi_mpi_dynamics_is_enabled(FUNC_NAME)) {
137 return OMPI_ERRHANDLER_INVOKE(comm, OMPI_ERR_NOT_SUPPORTED, FUNC_NAME);
138 }
139
140 if (rank == root) {
141 if (MPI_INFO_NULL == array_of_info[0]) {
142 non_mpi = false;
143 } else {
144 ompi_info_get_bool(array_of_info[0], "ompi_non_mpi", &non_mpi,
145 &flag);
146 if (!flag) {
147 non_mpi = false;
148 }
149 }
150 }
151
152
153 memset(port_name, 0, MPI_MAX_PORT_NAME);
154
155 OPAL_CR_ENTER_LIBRARY();
156
157 if ( rank == root ) {
158 if (!non_mpi) {
159
160
161 if (OMPI_SUCCESS != (rc = ompi_dpm_open_port (port_name))) {
162 goto error;
163 }
164 } else if (1 < ompi_comm_size(comm)) {
165
166 rc = OMPI_ERR_NOT_SUPPORTED;
167 goto error;
168 }
169 if (OMPI_SUCCESS != (rc = ompi_dpm_spawn(count, (const char **) array_of_commands,
170 array_of_argv, array_of_maxprocs,
171 array_of_info, port_name))) {
172 goto error;
173 }
174 }
175
176 if (non_mpi) {
177 newcomp = MPI_COMM_NULL;
178 } else {
179 rc = ompi_dpm_connect_accept (comm, root, port_name, send_first, &newcomp);
180 }
181
182 error:
183 if (OPAL_ERR_NOT_SUPPORTED == rc) {
184 opal_show_help("help-mpi-api.txt",
185 "MPI function not supported",
186 true,
187 FUNC_NAME,
188 "Underlying runtime environment does not support spawn functionality");
189 }
190
191
192 if (rank == root && !non_mpi) {
193 ompi_dpm_close_port(port_name);
194 }
195
196 OPAL_CR_EXIT_LIBRARY();
197
198
199 if (MPI_ERRCODES_IGNORE != array_of_errcodes) {
200 if (NULL != newcomp) {
201 size = newcomp->c_remote_group->grp_proc_count;
202 } else {
203 for ( i=0; i < count; i++) {
204 size = size + array_of_maxprocs[i];
205 }
206 }
207 for ( i=0; i < size; i++ ) {
208 array_of_errcodes[i]=rc;
209 }
210 }
211
212 *intercomm = newcomp;
213 OMPI_ERRHANDLER_RETURN (rc, comm, rc, FUNC_NAME);
214 }
215