Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Add support for MPI Errhandlers in Comm, File, Win.
[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 "smpi_errhandler.hpp"
12 #include "src/smpi/include/smpi_actor.hpp"
13
14 XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(smpi_pmpi);
15
16 /* PMPI User level calls */
17
18 int PMPI_Comm_rank(MPI_Comm comm, int *rank)
19 {
20   if (comm == MPI_COMM_NULL) {
21     return MPI_ERR_COMM;
22   } else if (rank == nullptr) {
23     return MPI_ERR_ARG;
24   } else {
25     *rank = comm->rank();
26     return MPI_SUCCESS;
27   }
28 }
29
30 int PMPI_Comm_size(MPI_Comm comm, int *size)
31 {
32   if (comm == MPI_COMM_NULL) {
33     return MPI_ERR_COMM;
34   } else if (size == nullptr) {
35     return MPI_ERR_ARG;
36   } else {
37     *size = comm->size();
38     return MPI_SUCCESS;
39   }
40 }
41
42 int PMPI_Comm_get_name (MPI_Comm comm, char* name, int* len)
43 {
44   if (comm == MPI_COMM_NULL)  {
45     return MPI_ERR_COMM;
46   } else if (name == nullptr || len == nullptr)  {
47     return MPI_ERR_ARG;
48   } else {
49     comm->get_name(name, len);
50     return MPI_SUCCESS;
51   }
52 }
53
54 int PMPI_Comm_set_name (MPI_Comm comm, const char* name)
55 {
56   if (comm == MPI_COMM_NULL)  {
57     return MPI_ERR_COMM;
58   } else if (name == nullptr)  {
59     return MPI_ERR_ARG;
60   } else {
61     comm->set_name(name);
62     return MPI_SUCCESS;
63   }
64 }
65
66 int PMPI_Comm_group(MPI_Comm comm, MPI_Group * group)
67 {
68   if (comm == MPI_COMM_NULL) {
69     return MPI_ERR_COMM;
70   } else if (group == nullptr) {
71     return MPI_ERR_ARG;
72   } else {
73     *group = comm->group();
74     if (*group != MPI_COMM_WORLD->group() && *group != MPI_GROUP_NULL && *group != MPI_GROUP_EMPTY)
75       (*group)->ref();
76     return MPI_SUCCESS;
77   }
78 }
79
80 int PMPI_Comm_compare(MPI_Comm comm1, MPI_Comm comm2, int *result)
81 {
82   if (comm1 == MPI_COMM_NULL || comm2 == MPI_COMM_NULL) {
83     return MPI_ERR_COMM;
84   } else if (result == nullptr) {
85     return MPI_ERR_ARG;
86   } else {
87     if (comm1 == comm2) {       /* Same communicators means same groups */
88       *result = MPI_IDENT;
89     } else {
90       *result = comm1->group()->compare(comm2->group());
91       if (*result == MPI_IDENT) {
92         *result = MPI_CONGRUENT;
93       }
94     }
95     return MPI_SUCCESS;
96   }
97 }
98
99 int PMPI_Comm_dup(MPI_Comm comm, MPI_Comm * newcomm)
100 {
101   if (comm == MPI_COMM_NULL) {
102     return MPI_ERR_COMM;
103   } else if (newcomm == nullptr) {
104     return MPI_ERR_ARG;
105   } else {
106     return comm->dup(newcomm);
107   }
108 }
109
110 int PMPI_Comm_dup_with_info(MPI_Comm comm, MPI_Info info, MPI_Comm * newcomm)
111 {
112   if (comm == MPI_COMM_NULL) {
113     return MPI_ERR_COMM;
114   } else if (newcomm == nullptr) {
115     return MPI_ERR_ARG;
116   } else {
117     comm->dup_with_info(info, newcomm);
118     return MPI_SUCCESS;
119   }
120 }
121
122 int PMPI_Comm_create(MPI_Comm comm, MPI_Group group, MPI_Comm * newcomm)
123 {
124   if (comm == MPI_COMM_NULL) {
125     return MPI_ERR_COMM;
126   } else if (group == MPI_GROUP_NULL) {
127     return MPI_ERR_GROUP;
128   } else if (newcomm == nullptr) {
129     return MPI_ERR_ARG;
130   } else if (group->rank(simgrid::s4u::this_actor::get_pid()) == MPI_UNDEFINED) {
131     *newcomm= MPI_COMM_NULL;
132     return MPI_SUCCESS;
133   }else{
134     group->ref();
135     *newcomm = new simgrid::smpi::Comm(group, nullptr);
136     return MPI_SUCCESS;
137   }
138 }
139
140 int PMPI_Comm_free(MPI_Comm * comm)
141 {
142   if (comm == nullptr) {
143     return MPI_ERR_ARG;
144   } else if (*comm == MPI_COMM_NULL) {
145     return MPI_ERR_COMM;
146   } else {
147     simgrid::smpi::Comm::destroy(*comm);
148     *comm = MPI_COMM_NULL;
149     return MPI_SUCCESS;
150   }
151 }
152
153 int PMPI_Comm_disconnect(MPI_Comm * comm)
154 {
155   /* TODO: wait until all communication in comm are done */
156   if (comm == nullptr) {
157     return MPI_ERR_ARG;
158   } else if (*comm == MPI_COMM_NULL) {
159     return MPI_ERR_COMM;
160   } else {
161     simgrid::smpi::Comm::destroy(*comm);
162     *comm = MPI_COMM_NULL;
163     return MPI_SUCCESS;
164   }
165 }
166
167 int PMPI_Comm_split(MPI_Comm comm, int color, int key, MPI_Comm* comm_out)
168 {
169   int retval = 0;
170   smpi_bench_end();
171
172   if (comm_out == nullptr) {
173     retval = MPI_ERR_ARG;
174   } else if (comm == MPI_COMM_NULL) {
175     retval = MPI_ERR_COMM;
176   } else {
177     *comm_out = comm->split(color, key);
178     retval = MPI_SUCCESS;
179   }
180   smpi_bench_begin();
181
182   return retval;
183 }
184
185 int PMPI_Comm_split_type(MPI_Comm comm, int split_type, int key, MPI_Info info, MPI_Comm *newcomm)
186 {
187   int retval = 0;
188   smpi_bench_end();
189
190   if (newcomm == nullptr) {
191     retval = MPI_ERR_ARG;
192   } else if (comm == MPI_COMM_NULL) {
193     retval = MPI_ERR_COMM;
194   } else {
195     *newcomm = comm->split_type(split_type, key, info);
196     retval = MPI_SUCCESS;
197   }
198   smpi_bench_begin();
199
200   return retval;
201 }
202
203 int PMPI_Comm_create_group(MPI_Comm comm, MPI_Group group, int, MPI_Comm* comm_out)
204 {
205   int retval = 0;
206   smpi_bench_end();
207
208   if (comm_out == nullptr) {
209     retval = MPI_ERR_ARG;
210   } else if (comm == MPI_COMM_NULL) {
211     retval = MPI_ERR_COMM;
212   } else {
213     retval = MPI_Comm_create(comm, group, comm_out);
214   }
215   smpi_bench_begin();
216
217   return retval;
218 }
219
220 MPI_Comm PMPI_Comm_f2c(MPI_Fint comm){
221   if(comm==-1)
222     return MPI_COMM_NULL;
223   return static_cast<MPI_Comm>(simgrid::smpi::Comm::f2c(comm));
224 }
225
226 MPI_Fint PMPI_Comm_c2f(MPI_Comm comm){
227   if(comm==MPI_COMM_NULL)
228     return -1;
229   return comm->c2f();
230 }
231
232 int PMPI_Comm_get_attr (MPI_Comm comm, int comm_keyval, void *attribute_val, int *flag)
233 {
234   return PMPI_Attr_get(comm, comm_keyval, attribute_val,flag);
235 }
236
237 int PMPI_Comm_set_attr (MPI_Comm comm, int comm_keyval, void *attribute_val)
238 {
239   return PMPI_Attr_put(comm, comm_keyval, attribute_val);
240 }
241
242 int PMPI_Comm_get_info(MPI_Comm comm, MPI_Info* info)
243 {
244   if (comm == MPI_COMM_NULL)  {
245     return MPI_ERR_WIN;
246   } else {
247     *info = comm->info();
248     return MPI_SUCCESS;
249   }
250 }
251
252 int PMPI_Comm_set_info(MPI_Comm  comm, MPI_Info info)
253 {
254   if (comm == MPI_COMM_NULL)  {
255     return MPI_ERR_TYPE;
256   } else {
257     comm->set_info(info);
258     return MPI_SUCCESS;
259   }
260 }
261
262 int PMPI_Comm_delete_attr (MPI_Comm comm, int comm_keyval)
263 {
264   return PMPI_Attr_delete(comm, comm_keyval);
265 }
266
267 int PMPI_Comm_create_keyval(MPI_Comm_copy_attr_function* copy_fn, MPI_Comm_delete_attr_function* delete_fn, int* keyval,
268                             void* extra_state)
269 {
270   return PMPI_Keyval_create(copy_fn, delete_fn, keyval, extra_state);
271 }
272
273 int PMPI_Comm_free_keyval(int* keyval) {
274   return PMPI_Keyval_free(keyval);
275 }
276
277 int PMPI_Attr_delete(MPI_Comm comm, int keyval) {
278   if(keyval == MPI_TAG_UB||keyval == MPI_HOST||keyval == MPI_IO ||keyval == MPI_WTIME_IS_GLOBAL||keyval == MPI_APPNUM
279        ||keyval == MPI_UNIVERSE_SIZE||keyval == MPI_LASTUSEDCODE)
280     return MPI_ERR_ARG;
281   else if (comm==MPI_COMM_NULL)
282     return MPI_ERR_COMM;
283   else
284     return comm->attr_delete<simgrid::smpi::Comm>(keyval);
285 }
286
287 int PMPI_Attr_get(MPI_Comm comm, int keyval, void* attr_value, int* flag) {
288   static int one = 1;
289   static int zero = 0;
290   static int tag_ub = INT_MAX;
291   static int last_used_code = MPI_ERR_LASTCODE;
292   static int universe_size;
293
294   if (comm==MPI_COMM_NULL){
295     *flag = 0;
296     return MPI_ERR_COMM;
297   }
298
299   switch (keyval) {
300   case MPI_HOST:
301   case MPI_IO:
302   case MPI_APPNUM:
303     *flag = 1;
304     *static_cast<int**>(attr_value) = &zero;
305     return MPI_SUCCESS;
306   case MPI_UNIVERSE_SIZE:
307     *flag = 1;
308     universe_size                   = smpi_get_universe_size();
309     *static_cast<int**>(attr_value) = &universe_size;
310     return MPI_SUCCESS;
311   case MPI_LASTUSEDCODE:
312     *flag = 1;
313     *static_cast<int**>(attr_value) = &last_used_code;
314     return MPI_SUCCESS;
315   case MPI_TAG_UB:
316     *flag=1;
317     *static_cast<int**>(attr_value) = &tag_ub;
318     return MPI_SUCCESS;
319   case MPI_WTIME_IS_GLOBAL:
320     *flag = 1;
321     *static_cast<int**>(attr_value) = &one;
322     return MPI_SUCCESS;
323   default:
324     return comm->attr_get<simgrid::smpi::Comm>(keyval, attr_value, flag);
325   }
326 }
327
328 int PMPI_Attr_put(MPI_Comm comm, int keyval, void* attr_value) {
329   if(keyval == MPI_TAG_UB||keyval == MPI_HOST||keyval == MPI_IO ||keyval == MPI_WTIME_IS_GLOBAL||keyval == MPI_APPNUM
330        ||keyval == MPI_UNIVERSE_SIZE||keyval == MPI_LASTUSEDCODE)
331     return MPI_ERR_ARG;
332   else if (comm==MPI_COMM_NULL)
333     return MPI_ERR_COMM;
334   else
335   return comm->attr_put<simgrid::smpi::Comm>(keyval, attr_value);
336 }
337
338 int PMPI_Errhandler_free(MPI_Errhandler* errhandler){
339   if (errhandler==nullptr){
340     return MPI_ERR_ARG;
341   }
342   simgrid::smpi::Errhandler::unref(*errhandler);
343   return MPI_SUCCESS;
344 }
345
346 int PMPI_Errhandler_create(MPI_Handler_function* function, MPI_Errhandler* errhandler){
347   *errhandler=new simgrid::smpi::Errhandler(function);
348   return MPI_SUCCESS;
349 }
350
351 int PMPI_Errhandler_get(MPI_Comm comm, MPI_Errhandler* errhandler){
352   if (comm == nullptr) {
353     return MPI_ERR_COMM;
354   } else if (errhandler==nullptr){
355     return MPI_ERR_ARG;
356   }
357   *errhandler=comm->errhandler();
358   return MPI_SUCCESS;
359 }
360
361 int PMPI_Errhandler_set(MPI_Comm comm, MPI_Errhandler errhandler){
362   if (comm == nullptr) {
363     return MPI_ERR_COMM;
364   } else if (errhandler==nullptr){
365     return MPI_ERR_ARG;
366   }
367   comm->set_errhandler(errhandler);
368   return MPI_SUCCESS;
369 }
370
371 int PMPI_Comm_call_errhandler(MPI_Comm comm,int errorcode){
372   if (comm == nullptr) {
373     return MPI_ERR_COMM;
374   }
375   comm->errhandler()->call(comm, errorcode);
376   return MPI_SUCCESS;
377 }
378
379 int PMPI_Comm_create_errhandler( MPI_Comm_errhandler_fn *function, MPI_Errhandler *errhandler){
380   return MPI_Errhandler_create(function, errhandler);
381 }
382 int PMPI_Comm_get_errhandler(MPI_Comm comm, MPI_Errhandler* errhandler){
383   return PMPI_Errhandler_get(comm, errhandler);
384 }
385 int PMPI_Comm_set_errhandler(MPI_Comm comm, MPI_Errhandler errhandler){
386   return PMPI_Errhandler_set(comm, errhandler);
387 }