Logo AND Algorithmique Numérique Distribuée

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