Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
MPI_Comm_dup_with_info
[simgrid.git] / src / smpi / bindings / smpi_pmpi_comm.cpp
1 /* Copyright (c) 2007-2019. The SimGrid Team. All rights reserved.          */
2
3 /* This program is free software; you can redistribute it and/or modify it
4  * under the terms of the license (GNU LGPL) which comes with this package. */
5
6 #include <climits>
7
8 #include "private.hpp"
9 #include "smpi_comm.hpp"
10 #include "smpi_info.hpp"
11 #include "src/smpi/include/smpi_actor.hpp"
12
13 XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(smpi_pmpi);
14
15 /* PMPI User level calls */
16
17 int PMPI_Comm_rank(MPI_Comm comm, int *rank)
18 {
19   if (comm == MPI_COMM_NULL) {
20     return MPI_ERR_COMM;
21   } else if (rank == nullptr) {
22     return MPI_ERR_ARG;
23   } else {
24     *rank = comm->rank();
25     return MPI_SUCCESS;
26   }
27 }
28
29 int PMPI_Comm_size(MPI_Comm comm, int *size)
30 {
31   if (comm == MPI_COMM_NULL) {
32     return MPI_ERR_COMM;
33   } else if (size == nullptr) {
34     return MPI_ERR_ARG;
35   } else {
36     *size = comm->size();
37     return MPI_SUCCESS;
38   }
39 }
40
41 int PMPI_Comm_get_name (MPI_Comm comm, char* name, int* len)
42 {
43   if (comm == MPI_COMM_NULL)  {
44     return MPI_ERR_COMM;
45   } else if (name == nullptr || len == nullptr)  {
46     return MPI_ERR_ARG;
47   } else {
48     comm->get_name(name, len);
49     return MPI_SUCCESS;
50   }
51 }
52
53 int PMPI_Comm_set_name (MPI_Comm comm, const char* name)
54 {
55   if (comm == MPI_COMM_NULL)  {
56     return MPI_ERR_COMM;
57   } else if (name == nullptr)  {
58     return MPI_ERR_ARG;
59   } else {
60     comm->set_name(name);
61     return MPI_SUCCESS;
62   }
63 }
64
65 int PMPI_Comm_group(MPI_Comm comm, MPI_Group * group)
66 {
67   if (comm == MPI_COMM_NULL) {
68     return MPI_ERR_COMM;
69   } else if (group == nullptr) {
70     return MPI_ERR_ARG;
71   } else {
72     *group = comm->group();
73     if (*group != MPI_COMM_WORLD->group() && *group != MPI_GROUP_NULL && *group != MPI_GROUP_EMPTY)
74       (*group)->ref();
75     return MPI_SUCCESS;
76   }
77 }
78
79 int PMPI_Comm_compare(MPI_Comm comm1, MPI_Comm comm2, int *result)
80 {
81   if (comm1 == MPI_COMM_NULL || comm2 == MPI_COMM_NULL) {
82     return MPI_ERR_COMM;
83   } else if (result == nullptr) {
84     return MPI_ERR_ARG;
85   } else {
86     if (comm1 == comm2) {       /* Same communicators means same groups */
87       *result = MPI_IDENT;
88     } else {
89       *result = comm1->group()->compare(comm2->group());
90       if (*result == MPI_IDENT) {
91         *result = MPI_CONGRUENT;
92       }
93     }
94     return MPI_SUCCESS;
95   }
96 }
97
98 int PMPI_Comm_dup(MPI_Comm comm, MPI_Comm * newcomm)
99 {
100   if (comm == MPI_COMM_NULL) {
101     return MPI_ERR_COMM;
102   } else if (newcomm == nullptr) {
103     return MPI_ERR_ARG;
104   } else {
105     return comm->dup(newcomm);
106   }
107 }
108
109 int PMPI_Comm_dup_with_info(MPI_Comm comm, MPI_Info info, MPI_Comm * newcomm)
110 {
111   if (comm == MPI_COMM_NULL) {
112     return MPI_ERR_COMM;
113   } else if (newcomm == nullptr) {
114     return MPI_ERR_ARG;
115   } else {
116     comm->dup(newcomm);
117     if(info!=MPI_INFO_NULL)
118       (*newcomm)->set_info(info);
119     return MPI_SUCCESS;
120   }
121 }
122
123 int PMPI_Comm_create(MPI_Comm comm, MPI_Group group, MPI_Comm * newcomm)
124 {
125   if (comm == MPI_COMM_NULL) {
126     return MPI_ERR_COMM;
127   } else if (group == MPI_GROUP_NULL) {
128     return MPI_ERR_GROUP;
129   } else if (newcomm == nullptr) {
130     return MPI_ERR_ARG;
131   } else if (group->rank(simgrid::s4u::this_actor::get_pid()) == MPI_UNDEFINED) {
132     *newcomm= MPI_COMM_NULL;
133     return MPI_SUCCESS;
134   }else{
135     group->ref();
136     *newcomm = new simgrid::smpi::Comm(group, nullptr);
137     return MPI_SUCCESS;
138   }
139 }
140
141 int PMPI_Comm_free(MPI_Comm * comm)
142 {
143   if (comm == nullptr) {
144     return MPI_ERR_ARG;
145   } else if (*comm == MPI_COMM_NULL) {
146     return MPI_ERR_COMM;
147   } else {
148     simgrid::smpi::Comm::destroy(*comm);
149     *comm = MPI_COMM_NULL;
150     return MPI_SUCCESS;
151   }
152 }
153
154 int PMPI_Comm_disconnect(MPI_Comm * comm)
155 {
156   /* TODO: wait until all communication in comm are done */
157   if (comm == nullptr) {
158     return MPI_ERR_ARG;
159   } else if (*comm == MPI_COMM_NULL) {
160     return MPI_ERR_COMM;
161   } else {
162     simgrid::smpi::Comm::destroy(*comm);
163     *comm = MPI_COMM_NULL;
164     return MPI_SUCCESS;
165   }
166 }
167
168 int PMPI_Comm_split(MPI_Comm comm, int color, int key, MPI_Comm* comm_out)
169 {
170   int retval = 0;
171   smpi_bench_end();
172
173   if (comm_out == nullptr) {
174     retval = MPI_ERR_ARG;
175   } else if (comm == MPI_COMM_NULL) {
176     retval = MPI_ERR_COMM;
177   } else {
178     *comm_out = comm->split(color, key);
179     retval = MPI_SUCCESS;
180   }
181   smpi_bench_begin();
182
183   return retval;
184 }
185
186 int PMPI_Comm_split_type(MPI_Comm comm, int split_type, int key, MPI_Info info, MPI_Comm *newcomm)
187 {
188   int retval = 0;
189   smpi_bench_end();
190
191   if (newcomm == nullptr) {
192     retval = MPI_ERR_ARG;
193   } else if (comm == MPI_COMM_NULL) {
194     retval = MPI_ERR_COMM;
195   } else {
196     *newcomm = comm->split_type(split_type, key, info);
197     retval = MPI_SUCCESS;
198   }
199   smpi_bench_begin();
200
201   return retval;
202 }
203
204 int PMPI_Comm_create_group(MPI_Comm comm, MPI_Group group, int, MPI_Comm* comm_out)
205 {
206   int retval = 0;
207   smpi_bench_end();
208
209   if (comm_out == nullptr) {
210     retval = MPI_ERR_ARG;
211   } else if (comm == MPI_COMM_NULL) {
212     retval = MPI_ERR_COMM;
213   } else {
214     retval = MPI_Comm_create(comm, group, comm_out);
215   }
216   smpi_bench_begin();
217
218   return retval;
219 }
220
221 MPI_Comm PMPI_Comm_f2c(MPI_Fint comm){
222   return static_cast<MPI_Comm>(simgrid::smpi::Comm::f2c(comm));
223 }
224
225 MPI_Fint PMPI_Comm_c2f(MPI_Comm comm){
226   return comm->c2f();
227 }
228
229 int PMPI_Comm_get_attr (MPI_Comm comm, int comm_keyval, void *attribute_val, int *flag)
230 {
231   return PMPI_Attr_get(comm, comm_keyval, attribute_val,flag);
232 }
233
234 int PMPI_Comm_set_attr (MPI_Comm comm, int comm_keyval, void *attribute_val)
235 {
236   return PMPI_Attr_put(comm, comm_keyval, attribute_val);
237 }
238
239 int PMPI_Comm_get_info(MPI_Comm comm, MPI_Info* info)
240 {
241   if (comm == MPI_COMM_NULL)  {
242     return MPI_ERR_WIN;
243   } else {
244     *info = comm->info();
245     return MPI_SUCCESS;
246   }
247 }
248
249 int PMPI_Comm_set_info(MPI_Comm  comm, MPI_Info info)
250 {
251   if (comm == MPI_COMM_NULL)  {
252     return MPI_ERR_TYPE;
253   } else {
254     comm->set_info(info);
255     return MPI_SUCCESS;
256   }
257 }
258
259 int PMPI_Comm_delete_attr (MPI_Comm comm, int comm_keyval)
260 {
261   return PMPI_Attr_delete(comm, comm_keyval);
262 }
263
264 int PMPI_Comm_create_keyval(MPI_Comm_copy_attr_function* copy_fn, MPI_Comm_delete_attr_function* delete_fn, int* keyval,
265                             void* extra_state)
266 {
267   return PMPI_Keyval_create(copy_fn, delete_fn, keyval, extra_state);
268 }
269
270 int PMPI_Comm_free_keyval(int* keyval) {
271   return PMPI_Keyval_free(keyval);
272 }
273
274 int PMPI_Attr_delete(MPI_Comm comm, int keyval) {
275   if(keyval == MPI_TAG_UB||keyval == MPI_HOST||keyval == MPI_IO ||keyval == MPI_WTIME_IS_GLOBAL||keyval == MPI_APPNUM
276        ||keyval == MPI_UNIVERSE_SIZE||keyval == MPI_LASTUSEDCODE)
277     return MPI_ERR_ARG;
278   else if (comm==MPI_COMM_NULL)
279     return MPI_ERR_COMM;
280   else
281     return comm->attr_delete<simgrid::smpi::Comm>(keyval);
282 }
283
284 int PMPI_Attr_get(MPI_Comm comm, int keyval, void* attr_value, int* flag) {
285   static int one = 1;
286   static int zero = 0;
287   static int tag_ub = INT_MAX;
288   static int last_used_code = MPI_ERR_LASTCODE;
289
290   if (comm==MPI_COMM_NULL){
291     *flag = 0;
292     return MPI_ERR_COMM;
293   }
294
295   switch (keyval) {
296   case MPI_HOST:
297   case MPI_IO:
298   case MPI_APPNUM:
299     *flag = 1;
300     *static_cast<int**>(attr_value) = &zero;
301     return MPI_SUCCESS;
302   case MPI_UNIVERSE_SIZE:
303     *flag = 1;
304     *static_cast<int**>(attr_value) = &smpi_universe_size;
305     return MPI_SUCCESS;
306   case MPI_LASTUSEDCODE:
307     *flag = 1;
308     *static_cast<int**>(attr_value) = &last_used_code;
309     return MPI_SUCCESS;
310   case MPI_TAG_UB:
311     *flag=1;
312     *static_cast<int**>(attr_value) = &tag_ub;
313     return MPI_SUCCESS;
314   case MPI_WTIME_IS_GLOBAL:
315     *flag = 1;
316     *static_cast<int**>(attr_value) = &one;
317     return MPI_SUCCESS;
318   default:
319     return comm->attr_get<simgrid::smpi::Comm>(keyval, attr_value, flag);
320   }
321 }
322
323 int PMPI_Attr_put(MPI_Comm comm, int keyval, void* attr_value) {
324   if(keyval == MPI_TAG_UB||keyval == MPI_HOST||keyval == MPI_IO ||keyval == MPI_WTIME_IS_GLOBAL||keyval == MPI_APPNUM
325        ||keyval == MPI_UNIVERSE_SIZE||keyval == MPI_LASTUSEDCODE)
326     return MPI_ERR_ARG;
327   else if (comm==MPI_COMM_NULL)
328     return MPI_ERR_COMM;
329   else
330   return comm->attr_put<simgrid::smpi::Comm>(keyval, attr_value);
331 }