Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Apply the default settings of 'smpi/buffering' too
[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_with_info(info, newcomm);
117     return MPI_SUCCESS;
118   }
119 }
120
121 int PMPI_Comm_create(MPI_Comm comm, MPI_Group group, MPI_Comm * newcomm)
122 {
123   if (comm == MPI_COMM_NULL) {
124     return MPI_ERR_COMM;
125   } else if (group == MPI_GROUP_NULL) {
126     return MPI_ERR_GROUP;
127   } else if (newcomm == nullptr) {
128     return MPI_ERR_ARG;
129   } else if (group->rank(simgrid::s4u::this_actor::get_pid()) == MPI_UNDEFINED) {
130     *newcomm= MPI_COMM_NULL;
131     return MPI_SUCCESS;
132   }else{
133     group->ref();
134     *newcomm = new simgrid::smpi::Comm(group, nullptr);
135     return MPI_SUCCESS;
136   }
137 }
138
139 int PMPI_Comm_free(MPI_Comm * comm)
140 {
141   if (comm == nullptr) {
142     return MPI_ERR_ARG;
143   } else if (*comm == MPI_COMM_NULL) {
144     return MPI_ERR_COMM;
145   } else {
146     simgrid::smpi::Comm::destroy(*comm);
147     *comm = MPI_COMM_NULL;
148     return MPI_SUCCESS;
149   }
150 }
151
152 int PMPI_Comm_disconnect(MPI_Comm * comm)
153 {
154   /* TODO: wait until all communication in comm are done */
155   if (comm == nullptr) {
156     return MPI_ERR_ARG;
157   } else if (*comm == MPI_COMM_NULL) {
158     return MPI_ERR_COMM;
159   } else {
160     simgrid::smpi::Comm::destroy(*comm);
161     *comm = MPI_COMM_NULL;
162     return MPI_SUCCESS;
163   }
164 }
165
166 int PMPI_Comm_split(MPI_Comm comm, int color, int key, MPI_Comm* comm_out)
167 {
168   int retval = 0;
169   smpi_bench_end();
170
171   if (comm_out == nullptr) {
172     retval = MPI_ERR_ARG;
173   } else if (comm == MPI_COMM_NULL) {
174     retval = MPI_ERR_COMM;
175   } else {
176     *comm_out = comm->split(color, key);
177     retval = MPI_SUCCESS;
178   }
179   smpi_bench_begin();
180
181   return retval;
182 }
183
184 int PMPI_Comm_split_type(MPI_Comm comm, int split_type, int key, MPI_Info info, MPI_Comm *newcomm)
185 {
186   int retval = 0;
187   smpi_bench_end();
188
189   if (newcomm == nullptr) {
190     retval = MPI_ERR_ARG;
191   } else if (comm == MPI_COMM_NULL) {
192     retval = MPI_ERR_COMM;
193   } else {
194     *newcomm = comm->split_type(split_type, key, info);
195     retval = MPI_SUCCESS;
196   }
197   smpi_bench_begin();
198
199   return retval;
200 }
201
202 int PMPI_Comm_create_group(MPI_Comm comm, MPI_Group group, int, MPI_Comm* comm_out)
203 {
204   int retval = 0;
205   smpi_bench_end();
206
207   if (comm_out == nullptr) {
208     retval = MPI_ERR_ARG;
209   } else if (comm == MPI_COMM_NULL) {
210     retval = MPI_ERR_COMM;
211   } else {
212     retval = MPI_Comm_create(comm, group, comm_out);
213   }
214   smpi_bench_begin();
215
216   return retval;
217 }
218
219 MPI_Comm PMPI_Comm_f2c(MPI_Fint comm){
220   if(comm==-1)
221     return MPI_COMM_NULL;
222   return static_cast<MPI_Comm>(simgrid::smpi::Comm::f2c(comm));
223 }
224
225 MPI_Fint PMPI_Comm_c2f(MPI_Comm comm){
226   if(comm==MPI_COMM_NULL)
227     return -1;
228   return comm->c2f();
229 }
230
231 int PMPI_Comm_get_attr (MPI_Comm comm, int comm_keyval, void *attribute_val, int *flag)
232 {
233   return PMPI_Attr_get(comm, comm_keyval, attribute_val,flag);
234 }
235
236 int PMPI_Comm_set_attr (MPI_Comm comm, int comm_keyval, void *attribute_val)
237 {
238   return PMPI_Attr_put(comm, comm_keyval, attribute_val);
239 }
240
241 int PMPI_Comm_get_info(MPI_Comm comm, MPI_Info* info)
242 {
243   if (comm == MPI_COMM_NULL)  {
244     return MPI_ERR_WIN;
245   } else {
246     *info = comm->info();
247     return MPI_SUCCESS;
248   }
249 }
250
251 int PMPI_Comm_set_info(MPI_Comm  comm, MPI_Info info)
252 {
253   if (comm == MPI_COMM_NULL)  {
254     return MPI_ERR_TYPE;
255   } else {
256     comm->set_info(info);
257     return MPI_SUCCESS;
258   }
259 }
260
261 int PMPI_Comm_delete_attr (MPI_Comm comm, int comm_keyval)
262 {
263   return PMPI_Attr_delete(comm, comm_keyval);
264 }
265
266 int PMPI_Comm_create_keyval(MPI_Comm_copy_attr_function* copy_fn, MPI_Comm_delete_attr_function* delete_fn, int* keyval,
267                             void* extra_state)
268 {
269   return PMPI_Keyval_create(copy_fn, delete_fn, keyval, extra_state);
270 }
271
272 int PMPI_Comm_free_keyval(int* keyval) {
273   return PMPI_Keyval_free(keyval);
274 }
275
276 int PMPI_Attr_delete(MPI_Comm comm, int keyval) {
277   if(keyval == MPI_TAG_UB||keyval == MPI_HOST||keyval == MPI_IO ||keyval == MPI_WTIME_IS_GLOBAL||keyval == MPI_APPNUM
278        ||keyval == MPI_UNIVERSE_SIZE||keyval == MPI_LASTUSEDCODE)
279     return MPI_ERR_ARG;
280   else if (comm==MPI_COMM_NULL)
281     return MPI_ERR_COMM;
282   else
283     return comm->attr_delete<simgrid::smpi::Comm>(keyval);
284 }
285
286 int PMPI_Attr_get(MPI_Comm comm, int keyval, void* attr_value, int* flag) {
287   static int one = 1;
288   static int zero = 0;
289   static int tag_ub = INT_MAX;
290   static int last_used_code = MPI_ERR_LASTCODE;
291   static int universe_size;
292
293   if (comm==MPI_COMM_NULL){
294     *flag = 0;
295     return MPI_ERR_COMM;
296   }
297
298   switch (keyval) {
299   case MPI_HOST:
300   case MPI_IO:
301   case MPI_APPNUM:
302     *flag = 1;
303     *static_cast<int**>(attr_value) = &zero;
304     return MPI_SUCCESS;
305   case MPI_UNIVERSE_SIZE:
306     *flag = 1;
307     universe_size                   = smpi_get_universe_size();
308     *static_cast<int**>(attr_value) = &universe_size;
309     return MPI_SUCCESS;
310   case MPI_LASTUSEDCODE:
311     *flag = 1;
312     *static_cast<int**>(attr_value) = &last_used_code;
313     return MPI_SUCCESS;
314   case MPI_TAG_UB:
315     *flag=1;
316     *static_cast<int**>(attr_value) = &tag_ub;
317     return MPI_SUCCESS;
318   case MPI_WTIME_IS_GLOBAL:
319     *flag = 1;
320     *static_cast<int**>(attr_value) = &one;
321     return MPI_SUCCESS;
322   default:
323     return comm->attr_get<simgrid::smpi::Comm>(keyval, attr_value, flag);
324   }
325 }
326
327 int PMPI_Attr_put(MPI_Comm comm, int keyval, void* attr_value) {
328   if(keyval == MPI_TAG_UB||keyval == MPI_HOST||keyval == MPI_IO ||keyval == MPI_WTIME_IS_GLOBAL||keyval == MPI_APPNUM
329        ||keyval == MPI_UNIVERSE_SIZE||keyval == MPI_LASTUSEDCODE)
330     return MPI_ERR_ARG;
331   else if (comm==MPI_COMM_NULL)
332     return MPI_ERR_COMM;
333   else
334   return comm->attr_put<simgrid::smpi::Comm>(keyval, attr_value);
335 }