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 "src/smpi/include/smpi_actor.hpp"
13 XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(smpi_pmpi);
15 /* PMPI User level calls */
17 int PMPI_Comm_rank(MPI_Comm comm, int *rank)
19 if (comm == MPI_COMM_NULL) {
21 } else if (rank == nullptr) {
29 int PMPI_Comm_size(MPI_Comm comm, int *size)
31 if (comm == MPI_COMM_NULL) {
33 } else if (size == nullptr) {
41 int PMPI_Comm_get_name (MPI_Comm comm, char* name, int* len)
43 if (comm == MPI_COMM_NULL) {
45 } else if (name == nullptr || len == nullptr) {
48 comm->get_name(name, len);
53 int PMPI_Comm_set_name (MPI_Comm comm, const char* name)
55 if (comm == MPI_COMM_NULL) {
57 } else if (name == nullptr) {
65 int PMPI_Comm_group(MPI_Comm comm, MPI_Group * group)
67 if (comm == MPI_COMM_NULL) {
69 } else if (group == nullptr) {
72 *group = comm->group();
73 if (*group != MPI_COMM_WORLD->group() && *group != MPI_GROUP_NULL && *group != MPI_GROUP_EMPTY)
79 int PMPI_Comm_compare(MPI_Comm comm1, MPI_Comm comm2, int *result)
81 if (comm1 == MPI_COMM_NULL || comm2 == MPI_COMM_NULL) {
83 } else if (result == nullptr) {
86 if (comm1 == comm2) { /* Same communicators means same groups */
89 *result = comm1->group()->compare(comm2->group());
90 if (*result == MPI_IDENT) {
91 *result = MPI_CONGRUENT;
98 int PMPI_Comm_dup(MPI_Comm comm, MPI_Comm * newcomm)
100 if (comm == MPI_COMM_NULL) {
102 } else if (newcomm == nullptr) {
105 return comm->dup(newcomm);
109 int PMPI_Comm_dup_with_info(MPI_Comm comm, MPI_Info info, MPI_Comm * newcomm)
111 if (comm == MPI_COMM_NULL) {
113 } else if (newcomm == nullptr) {
116 comm->dup_with_info(info, newcomm);
121 int PMPI_Comm_create(MPI_Comm comm, MPI_Group group, MPI_Comm * newcomm)
123 if (comm == MPI_COMM_NULL) {
125 } else if (group == MPI_GROUP_NULL) {
126 return MPI_ERR_GROUP;
127 } else if (newcomm == nullptr) {
129 } else if (group->rank(simgrid::s4u::this_actor::get_pid()) == MPI_UNDEFINED) {
130 *newcomm= MPI_COMM_NULL;
134 *newcomm = new simgrid::smpi::Comm(group, nullptr);
139 int PMPI_Comm_free(MPI_Comm * comm)
141 if (comm == nullptr) {
143 } else if (*comm == MPI_COMM_NULL) {
146 simgrid::smpi::Comm::destroy(*comm);
147 *comm = MPI_COMM_NULL;
152 int PMPI_Comm_disconnect(MPI_Comm * comm)
154 /* TODO: wait until all communication in comm are done */
155 if (comm == nullptr) {
157 } else if (*comm == MPI_COMM_NULL) {
160 simgrid::smpi::Comm::destroy(*comm);
161 *comm = MPI_COMM_NULL;
166 int PMPI_Comm_split(MPI_Comm comm, int color, int key, MPI_Comm* comm_out)
171 if (comm_out == nullptr) {
172 retval = MPI_ERR_ARG;
173 } else if (comm == MPI_COMM_NULL) {
174 retval = MPI_ERR_COMM;
176 *comm_out = comm->split(color, key);
177 retval = MPI_SUCCESS;
184 int PMPI_Comm_split_type(MPI_Comm comm, int split_type, int key, MPI_Info info, MPI_Comm *newcomm)
189 if (newcomm == nullptr) {
190 retval = MPI_ERR_ARG;
191 } else if (comm == MPI_COMM_NULL) {
192 retval = MPI_ERR_COMM;
194 *newcomm = comm->split_type(split_type, key, info);
195 retval = MPI_SUCCESS;
202 int PMPI_Comm_create_group(MPI_Comm comm, MPI_Group group, int, MPI_Comm* comm_out)
207 if (comm_out == nullptr) {
208 retval = MPI_ERR_ARG;
209 } else if (comm == MPI_COMM_NULL) {
210 retval = MPI_ERR_COMM;
212 retval = MPI_Comm_create(comm, group, comm_out);
219 MPI_Comm PMPI_Comm_f2c(MPI_Fint comm){
221 return MPI_COMM_NULL;
222 return static_cast<MPI_Comm>(simgrid::smpi::Comm::f2c(comm));
225 MPI_Fint PMPI_Comm_c2f(MPI_Comm comm){
226 if(comm==MPI_COMM_NULL)
231 int PMPI_Comm_get_attr (MPI_Comm comm, int comm_keyval, void *attribute_val, int *flag)
233 return PMPI_Attr_get(comm, comm_keyval, attribute_val,flag);
236 int PMPI_Comm_set_attr (MPI_Comm comm, int comm_keyval, void *attribute_val)
238 return PMPI_Attr_put(comm, comm_keyval, attribute_val);
241 int PMPI_Comm_get_info(MPI_Comm comm, MPI_Info* info)
243 if (comm == MPI_COMM_NULL) {
246 *info = comm->info();
251 int PMPI_Comm_set_info(MPI_Comm comm, MPI_Info info)
253 if (comm == MPI_COMM_NULL) {
256 comm->set_info(info);
261 int PMPI_Comm_delete_attr (MPI_Comm comm, int comm_keyval)
263 return PMPI_Attr_delete(comm, comm_keyval);
266 int PMPI_Comm_create_keyval(MPI_Comm_copy_attr_function* copy_fn, MPI_Comm_delete_attr_function* delete_fn, int* keyval,
269 return PMPI_Keyval_create(copy_fn, delete_fn, keyval, extra_state);
272 int PMPI_Comm_free_keyval(int* keyval) {
273 return PMPI_Keyval_free(keyval);
276 int PMPI_Attr_delete(MPI_Comm comm, int keyval) {
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)
280 else if (comm==MPI_COMM_NULL)
283 return comm->attr_delete<simgrid::smpi::Comm>(keyval);
286 int PMPI_Attr_get(MPI_Comm comm, int keyval, void* attr_value, int* flag) {
289 static int tag_ub = INT_MAX;
290 static int last_used_code = MPI_ERR_LASTCODE;
292 if (comm==MPI_COMM_NULL){
302 *static_cast<int**>(attr_value) = &zero;
304 case MPI_UNIVERSE_SIZE:
306 *static_cast<int**>(attr_value) = &smpi_universe_size;
308 case MPI_LASTUSEDCODE:
310 *static_cast<int**>(attr_value) = &last_used_code;
314 *static_cast<int**>(attr_value) = &tag_ub;
316 case MPI_WTIME_IS_GLOBAL:
318 *static_cast<int**>(attr_value) = &one;
321 return comm->attr_get<simgrid::smpi::Comm>(keyval, attr_value, flag);
325 int PMPI_Attr_put(MPI_Comm comm, int keyval, void* attr_value) {
326 if(keyval == MPI_TAG_UB||keyval == MPI_HOST||keyval == MPI_IO ||keyval == MPI_WTIME_IS_GLOBAL||keyval == MPI_APPNUM
327 ||keyval == MPI_UNIVERSE_SIZE||keyval == MPI_LASTUSEDCODE)
329 else if (comm==MPI_COMM_NULL)
332 return comm->attr_put<simgrid::smpi::Comm>(keyval, attr_value);