Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
f0f2ed449a4f323f9f68f77ceaf0ef058d45963a
[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::Actor::self()->getPid())==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_create_group(MPI_Comm comm, MPI_Group group, int, MPI_Comm* comm_out)
160 {
161   int retval = 0;
162   smpi_bench_end();
163
164   if (comm_out == nullptr) {
165     retval = MPI_ERR_ARG;
166   } else if (comm == MPI_COMM_NULL) {
167     retval = MPI_ERR_COMM;
168   } else {
169     retval = MPI_Comm_create(comm, group, comm_out);
170   }
171   smpi_bench_begin();
172
173   return retval;
174 }
175
176 MPI_Comm PMPI_Comm_f2c(MPI_Fint comm){
177   return static_cast<MPI_Comm>(simgrid::smpi::Comm::f2c(comm));
178 }
179
180 MPI_Fint PMPI_Comm_c2f(MPI_Comm comm){
181   return comm->c2f();
182 }
183
184 int PMPI_Comm_get_attr (MPI_Comm comm, int comm_keyval, void *attribute_val, int *flag)
185 {
186   return PMPI_Attr_get(comm, comm_keyval, attribute_val,flag);
187 }
188
189 int PMPI_Comm_set_attr (MPI_Comm comm, int comm_keyval, void *attribute_val)
190 {
191   return PMPI_Attr_put(comm, comm_keyval, attribute_val);
192 }
193
194 int PMPI_Comm_delete_attr (MPI_Comm comm, int comm_keyval)
195 {
196   return PMPI_Attr_delete(comm, comm_keyval);
197 }
198
199 int PMPI_Comm_create_keyval(MPI_Comm_copy_attr_function* copy_fn, MPI_Comm_delete_attr_function* delete_fn, int* keyval,
200                             void* extra_state)
201 {
202   return PMPI_Keyval_create(copy_fn, delete_fn, keyval, extra_state);
203 }
204
205 int PMPI_Comm_free_keyval(int* keyval) {
206   return PMPI_Keyval_free(keyval);
207 }
208
209 int PMPI_Attr_delete(MPI_Comm comm, int keyval) {
210   if(keyval == MPI_TAG_UB||keyval == MPI_HOST||keyval == MPI_IO ||keyval == MPI_WTIME_IS_GLOBAL||keyval == MPI_APPNUM
211        ||keyval == MPI_UNIVERSE_SIZE||keyval == MPI_LASTUSEDCODE)
212     return MPI_ERR_ARG;
213   else if (comm==MPI_COMM_NULL)
214     return MPI_ERR_COMM;
215   else
216     return comm->attr_delete<simgrid::smpi::Comm>(keyval);
217 }
218
219 int PMPI_Attr_get(MPI_Comm comm, int keyval, void* attr_value, int* flag) {
220   static int one = 1;
221   static int zero = 0;
222   static int tag_ub = INT_MAX;
223   static int last_used_code = MPI_ERR_LASTCODE;
224
225   if (comm==MPI_COMM_NULL){
226     *flag = 0;
227     return MPI_ERR_COMM;
228   }
229
230   switch (keyval) {
231   case MPI_HOST:
232   case MPI_IO:
233   case MPI_APPNUM:
234     *flag = 1;
235     *static_cast<int**>(attr_value) = &zero;
236     return MPI_SUCCESS;
237   case MPI_UNIVERSE_SIZE:
238     *flag = 1;
239     *static_cast<int**>(attr_value) = &smpi_universe_size;
240     return MPI_SUCCESS;
241   case MPI_LASTUSEDCODE:
242     *flag = 1;
243     *static_cast<int**>(attr_value) = &last_used_code;
244     return MPI_SUCCESS;
245   case MPI_TAG_UB:
246     *flag=1;
247     *static_cast<int**>(attr_value) = &tag_ub;
248     return MPI_SUCCESS;
249   case MPI_WTIME_IS_GLOBAL:
250     *flag = 1;
251     *static_cast<int**>(attr_value) = &one;
252     return MPI_SUCCESS;
253   default:
254     return comm->attr_get<simgrid::smpi::Comm>(keyval, attr_value, flag);
255   }
256 }
257
258 int PMPI_Attr_put(MPI_Comm comm, int keyval, void* attr_value) {
259   if(keyval == MPI_TAG_UB||keyval == MPI_HOST||keyval == MPI_IO ||keyval == MPI_WTIME_IS_GLOBAL||keyval == MPI_APPNUM
260        ||keyval == MPI_UNIVERSE_SIZE||keyval == MPI_LASTUSEDCODE)
261     return MPI_ERR_ARG;
262   else if (comm==MPI_COMM_NULL)
263     return MPI_ERR_COMM;
264   else
265   return comm->attr_put<simgrid::smpi::Comm>(keyval, attr_value);
266 }