Logo AND Algorithmique Numérique Distribuée

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