1 /* Copyright (c) 2007-2019. The SimGrid Team. All rights reserved. */
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. */
9 #include "smpi_comm.hpp"
10 #include "smpi_info.hpp"
11 #include "smpi_errhandler.hpp"
12 #include "src/smpi/include/smpi_actor.hpp"
14 XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(smpi_pmpi);
16 /* PMPI User level calls */
18 int PMPI_Comm_rank(MPI_Comm comm, int *rank)
20 if (comm == MPI_COMM_NULL) {
22 } else if (rank == nullptr) {
30 int PMPI_Comm_size(MPI_Comm comm, int *size)
32 if (comm == MPI_COMM_NULL) {
34 } else if (size == nullptr) {
42 int PMPI_Comm_get_name (MPI_Comm comm, char* name, int* len)
44 if (comm == MPI_COMM_NULL) {
46 } else if (name == nullptr || len == nullptr) {
49 comm->get_name(name, len);
54 int PMPI_Comm_set_name (MPI_Comm comm, const char* name)
56 if (comm == MPI_COMM_NULL) {
58 } else if (name == nullptr) {
66 int PMPI_Comm_group(MPI_Comm comm, MPI_Group * group)
68 if (comm == MPI_COMM_NULL) {
70 } else if (group == nullptr) {
73 *group = comm->group();
74 if (*group != MPI_COMM_WORLD->group() && *group != MPI_GROUP_NULL && *group != MPI_GROUP_EMPTY)
80 int PMPI_Comm_compare(MPI_Comm comm1, MPI_Comm comm2, int *result)
82 if (comm1 == MPI_COMM_NULL || comm2 == MPI_COMM_NULL) {
84 } else if (result == nullptr) {
87 if (comm1 == comm2) { /* Same communicators means same groups */
90 *result = comm1->group()->compare(comm2->group());
91 if (*result == MPI_IDENT) {
92 *result = MPI_CONGRUENT;
99 int PMPI_Comm_dup(MPI_Comm comm, MPI_Comm * newcomm)
101 if (comm == MPI_COMM_NULL) {
103 } else if (newcomm == nullptr) {
106 return comm->dup(newcomm);
110 int PMPI_Comm_dup_with_info(MPI_Comm comm, MPI_Info info, MPI_Comm * newcomm)
112 if (comm == MPI_COMM_NULL) {
114 } else if (newcomm == nullptr) {
117 comm->dup_with_info(info, newcomm);
122 int PMPI_Comm_create(MPI_Comm comm, MPI_Group group, MPI_Comm * newcomm)
124 if (comm == MPI_COMM_NULL) {
126 } else if (group == MPI_GROUP_NULL) {
127 return MPI_ERR_GROUP;
128 } else if (newcomm == nullptr) {
130 } else if (group->rank(simgrid::s4u::this_actor::get_pid()) == MPI_UNDEFINED) {
131 *newcomm= MPI_COMM_NULL;
135 *newcomm = new simgrid::smpi::Comm(group, nullptr);
140 int PMPI_Comm_free(MPI_Comm * comm)
142 if (comm == nullptr) {
144 } else if (*comm == MPI_COMM_NULL) {
147 simgrid::smpi::Comm::destroy(*comm);
148 *comm = MPI_COMM_NULL;
153 int PMPI_Comm_disconnect(MPI_Comm * comm)
155 /* TODO: wait until all communication in comm are done */
156 if (comm == nullptr) {
158 } else if (*comm == MPI_COMM_NULL) {
161 simgrid::smpi::Comm::destroy(*comm);
162 *comm = MPI_COMM_NULL;
167 int PMPI_Comm_split(MPI_Comm comm, int color, int key, MPI_Comm* comm_out)
172 if (comm_out == nullptr) {
173 retval = MPI_ERR_ARG;
174 } else if (comm == MPI_COMM_NULL) {
175 retval = MPI_ERR_COMM;
177 *comm_out = comm->split(color, key);
178 retval = MPI_SUCCESS;
185 int PMPI_Comm_split_type(MPI_Comm comm, int split_type, int key, MPI_Info info, MPI_Comm *newcomm)
190 if (newcomm == nullptr) {
191 retval = MPI_ERR_ARG;
192 } else if (comm == MPI_COMM_NULL) {
193 retval = MPI_ERR_COMM;
195 *newcomm = comm->split_type(split_type, key, info);
196 retval = MPI_SUCCESS;
203 int PMPI_Comm_create_group(MPI_Comm comm, MPI_Group group, int, MPI_Comm* comm_out)
208 if (comm_out == nullptr) {
209 retval = MPI_ERR_ARG;
210 } else if (comm == MPI_COMM_NULL) {
211 retval = MPI_ERR_COMM;
213 retval = MPI_Comm_create(comm, group, comm_out);
220 MPI_Comm PMPI_Comm_f2c(MPI_Fint comm){
222 return MPI_COMM_NULL;
223 return static_cast<MPI_Comm>(simgrid::smpi::Comm::f2c(comm));
226 MPI_Fint PMPI_Comm_c2f(MPI_Comm comm){
227 if(comm==MPI_COMM_NULL)
232 int PMPI_Comm_get_attr (MPI_Comm comm, int comm_keyval, void *attribute_val, int *flag)
234 return PMPI_Attr_get(comm, comm_keyval, attribute_val,flag);
237 int PMPI_Comm_set_attr (MPI_Comm comm, int comm_keyval, void *attribute_val)
239 return PMPI_Attr_put(comm, comm_keyval, attribute_val);
242 int PMPI_Comm_get_info(MPI_Comm comm, MPI_Info* info)
244 if (comm == MPI_COMM_NULL) {
247 *info = comm->info();
252 int PMPI_Comm_set_info(MPI_Comm comm, MPI_Info info)
254 if (comm == MPI_COMM_NULL) {
257 comm->set_info(info);
262 int PMPI_Comm_delete_attr (MPI_Comm comm, int comm_keyval)
264 return PMPI_Attr_delete(comm, comm_keyval);
267 int PMPI_Comm_create_keyval(MPI_Comm_copy_attr_function* copy_fn, MPI_Comm_delete_attr_function* delete_fn, int* keyval,
270 return PMPI_Keyval_create(copy_fn, delete_fn, keyval, extra_state);
273 int PMPI_Comm_free_keyval(int* keyval) {
274 return PMPI_Keyval_free(keyval);
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)
281 else if (comm==MPI_COMM_NULL)
284 return comm->attr_delete<simgrid::smpi::Comm>(keyval);
287 int PMPI_Attr_get(MPI_Comm comm, int keyval, void* attr_value, int* flag) {
290 static int tag_ub = INT_MAX;
291 static int last_used_code = MPI_ERR_LASTCODE;
292 static int universe_size;
294 if (comm==MPI_COMM_NULL){
304 *static_cast<int**>(attr_value) = &zero;
306 case MPI_UNIVERSE_SIZE:
308 universe_size = smpi_get_universe_size();
309 *static_cast<int**>(attr_value) = &universe_size;
311 case MPI_LASTUSEDCODE:
313 *static_cast<int**>(attr_value) = &last_used_code;
317 *static_cast<int**>(attr_value) = &tag_ub;
319 case MPI_WTIME_IS_GLOBAL:
321 *static_cast<int**>(attr_value) = &one;
324 return comm->attr_get<simgrid::smpi::Comm>(keyval, attr_value, flag);
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)
332 else if (comm==MPI_COMM_NULL)
335 return comm->attr_put<simgrid::smpi::Comm>(keyval, attr_value);
338 int PMPI_Errhandler_free(MPI_Errhandler* errhandler){
339 if (errhandler==nullptr){
342 simgrid::smpi::Errhandler::unref(*errhandler);
346 int PMPI_Errhandler_create(MPI_Handler_function* function, MPI_Errhandler* errhandler){
347 *errhandler=new simgrid::smpi::Errhandler(function);
351 int PMPI_Errhandler_get(MPI_Comm comm, MPI_Errhandler* errhandler){
352 if (comm == nullptr) {
354 } else if (errhandler==nullptr){
357 *errhandler=comm->errhandler();
361 int PMPI_Errhandler_set(MPI_Comm comm, MPI_Errhandler errhandler){
362 if (comm == nullptr) {
364 } else if (errhandler==nullptr){
367 comm->set_errhandler(errhandler);
371 int PMPI_Comm_call_errhandler(MPI_Comm comm,int errorcode){
372 if (comm == nullptr) {
375 comm->errhandler()->call(comm, errorcode);
379 int PMPI_Comm_create_errhandler( MPI_Comm_errhandler_fn *function, MPI_Errhandler *errhandler){
380 return MPI_Errhandler_create(function, errhandler);
382 int PMPI_Comm_get_errhandler(MPI_Comm comm, MPI_Errhandler* errhandler){
383 return PMPI_Errhandler_get(comm, errhandler);
385 int PMPI_Comm_set_errhandler(MPI_Comm comm, MPI_Errhandler errhandler){
386 return PMPI_Errhandler_set(comm, errhandler);