Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge branch 'master' of https://framagit.org/simgrid/simgrid
[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   return static_cast<MPI_Comm>(simgrid::smpi::Comm::f2c(comm));
221 }
222
223 MPI_Fint PMPI_Comm_c2f(MPI_Comm comm){
224   return comm->c2f();
225 }
226
227 int PMPI_Comm_get_attr (MPI_Comm comm, int comm_keyval, void *attribute_val, int *flag)
228 {
229   return PMPI_Attr_get(comm, comm_keyval, attribute_val,flag);
230 }
231
232 int PMPI_Comm_set_attr (MPI_Comm comm, int comm_keyval, void *attribute_val)
233 {
234   return PMPI_Attr_put(comm, comm_keyval, attribute_val);
235 }
236
237 int PMPI_Comm_get_info(MPI_Comm comm, MPI_Info* info)
238 {
239   if (comm == MPI_COMM_NULL)  {
240     return MPI_ERR_WIN;
241   } else {
242     *info = comm->info();
243     return MPI_SUCCESS;
244   }
245 }
246
247 int PMPI_Comm_set_info(MPI_Comm  comm, MPI_Info info)
248 {
249   if (comm == MPI_COMM_NULL)  {
250     return MPI_ERR_TYPE;
251   } else {
252     comm->set_info(info);
253     return MPI_SUCCESS;
254   }
255 }
256
257 int PMPI_Comm_delete_attr (MPI_Comm comm, int comm_keyval)
258 {
259   return PMPI_Attr_delete(comm, comm_keyval);
260 }
261
262 int PMPI_Comm_create_keyval(MPI_Comm_copy_attr_function* copy_fn, MPI_Comm_delete_attr_function* delete_fn, int* keyval,
263                             void* extra_state)
264 {
265   return PMPI_Keyval_create(copy_fn, delete_fn, keyval, extra_state);
266 }
267
268 int PMPI_Comm_free_keyval(int* keyval) {
269   return PMPI_Keyval_free(keyval);
270 }
271
272 int PMPI_Attr_delete(MPI_Comm comm, int keyval) {
273   if(keyval == MPI_TAG_UB||keyval == MPI_HOST||keyval == MPI_IO ||keyval == MPI_WTIME_IS_GLOBAL||keyval == MPI_APPNUM
274        ||keyval == MPI_UNIVERSE_SIZE||keyval == MPI_LASTUSEDCODE)
275     return MPI_ERR_ARG;
276   else if (comm==MPI_COMM_NULL)
277     return MPI_ERR_COMM;
278   else
279     return comm->attr_delete<simgrid::smpi::Comm>(keyval);
280 }
281
282 int PMPI_Attr_get(MPI_Comm comm, int keyval, void* attr_value, int* flag) {
283   static int one = 1;
284   static int zero = 0;
285   static int tag_ub = INT_MAX;
286   static int last_used_code = MPI_ERR_LASTCODE;
287
288   if (comm==MPI_COMM_NULL){
289     *flag = 0;
290     return MPI_ERR_COMM;
291   }
292
293   switch (keyval) {
294   case MPI_HOST:
295   case MPI_IO:
296   case MPI_APPNUM:
297     *flag = 1;
298     *static_cast<int**>(attr_value) = &zero;
299     return MPI_SUCCESS;
300   case MPI_UNIVERSE_SIZE:
301     *flag = 1;
302     *static_cast<int**>(attr_value) = &smpi_universe_size;
303     return MPI_SUCCESS;
304   case MPI_LASTUSEDCODE:
305     *flag = 1;
306     *static_cast<int**>(attr_value) = &last_used_code;
307     return MPI_SUCCESS;
308   case MPI_TAG_UB:
309     *flag=1;
310     *static_cast<int**>(attr_value) = &tag_ub;
311     return MPI_SUCCESS;
312   case MPI_WTIME_IS_GLOBAL:
313     *flag = 1;
314     *static_cast<int**>(attr_value) = &one;
315     return MPI_SUCCESS;
316   default:
317     return comm->attr_get<simgrid::smpi::Comm>(keyval, attr_value, flag);
318   }
319 }
320
321 int PMPI_Attr_put(MPI_Comm comm, int keyval, void* attr_value) {
322   if(keyval == MPI_TAG_UB||keyval == MPI_HOST||keyval == MPI_IO ||keyval == MPI_WTIME_IS_GLOBAL||keyval == MPI_APPNUM
323        ||keyval == MPI_UNIVERSE_SIZE||keyval == MPI_LASTUSEDCODE)
324     return MPI_ERR_ARG;
325   else if (comm==MPI_COMM_NULL)
326     return MPI_ERR_COMM;
327   else
328   return comm->attr_put<simgrid::smpi::Comm>(keyval, attr_value);
329 }