Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
basic implem of MPI_Win_allocate_shared, MPI_Win_shared_query, MPI_Comm_split_type
[simgrid.git] / src / smpi / bindings / smpi_pmpi_comm.cpp
1 /* Copyright (c) 2007-2018. 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_process.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_group(MPI_Comm comm, MPI_Group * group)
53 {
54   if (comm == MPI_COMM_NULL) {
55     return MPI_ERR_COMM;
56   } else if (group == nullptr) {
57     return MPI_ERR_ARG;
58   } else {
59     *group = comm->group();
60     if (*group != MPI_COMM_WORLD->group() && *group != MPI_GROUP_NULL && *group != MPI_GROUP_EMPTY)
61       (*group)->ref();
62     return MPI_SUCCESS;
63   }
64 }
65
66 int PMPI_Comm_compare(MPI_Comm comm1, MPI_Comm comm2, int *result)
67 {
68   if (comm1 == MPI_COMM_NULL || comm2 == MPI_COMM_NULL) {
69     return MPI_ERR_COMM;
70   } else if (result == nullptr) {
71     return MPI_ERR_ARG;
72   } else {
73     if (comm1 == comm2) {       /* Same communicators means same groups */
74       *result = MPI_IDENT;
75     } else {
76       *result = comm1->group()->compare(comm2->group());
77       if (*result == MPI_IDENT) {
78         *result = MPI_CONGRUENT;
79       }
80     }
81     return MPI_SUCCESS;
82   }
83 }
84
85 int PMPI_Comm_dup(MPI_Comm comm, MPI_Comm * newcomm)
86 {
87   if (comm == MPI_COMM_NULL) {
88     return MPI_ERR_COMM;
89   } else if (newcomm == nullptr) {
90     return MPI_ERR_ARG;
91   } else {
92     return comm->dup(newcomm);
93   }
94 }
95
96 int PMPI_Comm_create(MPI_Comm comm, MPI_Group group, MPI_Comm * newcomm)
97 {
98   if (comm == MPI_COMM_NULL) {
99     return MPI_ERR_COMM;
100   } else if (group == MPI_GROUP_NULL) {
101     return MPI_ERR_GROUP;
102   } else if (newcomm == nullptr) {
103     return MPI_ERR_ARG;
104   } else if (group->rank(simgrid::s4u::this_actor::get_pid()) == MPI_UNDEFINED) {
105     *newcomm= MPI_COMM_NULL;
106     return MPI_SUCCESS;
107   }else{
108     group->ref();
109     *newcomm = new simgrid::smpi::Comm(group, nullptr);
110     return MPI_SUCCESS;
111   }
112 }
113
114 int PMPI_Comm_free(MPI_Comm * comm)
115 {
116   if (comm == nullptr) {
117     return MPI_ERR_ARG;
118   } else if (*comm == MPI_COMM_NULL) {
119     return MPI_ERR_COMM;
120   } else {
121     simgrid::smpi::Comm::destroy(*comm);
122     *comm = MPI_COMM_NULL;
123     return MPI_SUCCESS;
124   }
125 }
126
127 int PMPI_Comm_disconnect(MPI_Comm * comm)
128 {
129   /* TODO: wait until all communication in comm are done */
130   if (comm == nullptr) {
131     return MPI_ERR_ARG;
132   } else if (*comm == MPI_COMM_NULL) {
133     return MPI_ERR_COMM;
134   } else {
135     simgrid::smpi::Comm::destroy(*comm);
136     *comm = MPI_COMM_NULL;
137     return MPI_SUCCESS;
138   }
139 }
140
141 int PMPI_Comm_split(MPI_Comm comm, int color, int key, MPI_Comm* comm_out)
142 {
143   int retval = 0;
144   smpi_bench_end();
145
146   if (comm_out == nullptr) {
147     retval = MPI_ERR_ARG;
148   } else if (comm == MPI_COMM_NULL) {
149     retval = MPI_ERR_COMM;
150   } else {
151     *comm_out = comm->split(color, key);
152     retval = MPI_SUCCESS;
153   }
154   smpi_bench_begin();
155
156   return retval;
157 }
158
159 int PMPI_Comm_split_type(MPI_Comm comm, int split_type, int key, MPI_Info info, MPI_Comm *newcomm)
160 {
161   int retval = 0;
162   smpi_bench_end();
163
164   if (newcomm == nullptr) {
165     retval = MPI_ERR_ARG;
166   } else if (comm == MPI_COMM_NULL) {
167     retval = MPI_ERR_COMM;
168   } else {
169     *newcomm = comm->split_type(split_type, key, info);
170     retval = MPI_SUCCESS;
171   }
172   smpi_bench_begin();
173
174   return retval;
175 }
176
177 int PMPI_Comm_create_group(MPI_Comm comm, MPI_Group group, int, MPI_Comm* comm_out)
178 {
179   int retval = 0;
180   smpi_bench_end();
181
182   if (comm_out == nullptr) {
183     retval = MPI_ERR_ARG;
184   } else if (comm == MPI_COMM_NULL) {
185     retval = MPI_ERR_COMM;
186   } else {
187     retval = MPI_Comm_create(comm, group, comm_out);
188   }
189   smpi_bench_begin();
190
191   return retval;
192 }
193
194 MPI_Comm PMPI_Comm_f2c(MPI_Fint comm){
195   return static_cast<MPI_Comm>(simgrid::smpi::Comm::f2c(comm));
196 }
197
198 MPI_Fint PMPI_Comm_c2f(MPI_Comm comm){
199   return comm->c2f();
200 }
201
202 int PMPI_Comm_get_attr (MPI_Comm comm, int comm_keyval, void *attribute_val, int *flag)
203 {
204   return PMPI_Attr_get(comm, comm_keyval, attribute_val,flag);
205 }
206
207 int PMPI_Comm_set_attr (MPI_Comm comm, int comm_keyval, void *attribute_val)
208 {
209   return PMPI_Attr_put(comm, comm_keyval, attribute_val);
210 }
211
212 int PMPI_Comm_delete_attr (MPI_Comm comm, int comm_keyval)
213 {
214   return PMPI_Attr_delete(comm, comm_keyval);
215 }
216
217 int PMPI_Comm_create_keyval(MPI_Comm_copy_attr_function* copy_fn, MPI_Comm_delete_attr_function* delete_fn, int* keyval,
218                             void* extra_state)
219 {
220   return PMPI_Keyval_create(copy_fn, delete_fn, keyval, extra_state);
221 }
222
223 int PMPI_Comm_free_keyval(int* keyval) {
224   return PMPI_Keyval_free(keyval);
225 }
226
227 int PMPI_Attr_delete(MPI_Comm comm, int keyval) {
228   if(keyval == MPI_TAG_UB||keyval == MPI_HOST||keyval == MPI_IO ||keyval == MPI_WTIME_IS_GLOBAL||keyval == MPI_APPNUM
229        ||keyval == MPI_UNIVERSE_SIZE||keyval == MPI_LASTUSEDCODE)
230     return MPI_ERR_ARG;
231   else if (comm==MPI_COMM_NULL)
232     return MPI_ERR_COMM;
233   else
234     return comm->attr_delete<simgrid::smpi::Comm>(keyval);
235 }
236
237 int PMPI_Attr_get(MPI_Comm comm, int keyval, void* attr_value, int* flag) {
238   static int one = 1;
239   static int zero = 0;
240   static int tag_ub = INT_MAX;
241   static int last_used_code = MPI_ERR_LASTCODE;
242
243   if (comm==MPI_COMM_NULL){
244     *flag = 0;
245     return MPI_ERR_COMM;
246   }
247
248   switch (keyval) {
249   case MPI_HOST:
250   case MPI_IO:
251   case MPI_APPNUM:
252     *flag = 1;
253     *static_cast<int**>(attr_value) = &zero;
254     return MPI_SUCCESS;
255   case MPI_UNIVERSE_SIZE:
256     *flag = 1;
257     *static_cast<int**>(attr_value) = &smpi_universe_size;
258     return MPI_SUCCESS;
259   case MPI_LASTUSEDCODE:
260     *flag = 1;
261     *static_cast<int**>(attr_value) = &last_used_code;
262     return MPI_SUCCESS;
263   case MPI_TAG_UB:
264     *flag=1;
265     *static_cast<int**>(attr_value) = &tag_ub;
266     return MPI_SUCCESS;
267   case MPI_WTIME_IS_GLOBAL:
268     *flag = 1;
269     *static_cast<int**>(attr_value) = &one;
270     return MPI_SUCCESS;
271   default:
272     return comm->attr_get<simgrid::smpi::Comm>(keyval, attr_value, flag);
273   }
274 }
275
276 int PMPI_Attr_put(MPI_Comm comm, int keyval, void* attr_value) {
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_put<simgrid::smpi::Comm>(keyval, attr_value);
284 }