1 /* Copyright (c) 2007-2017. 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_process.hpp"
12 XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(smpi_pmpi);
14 /* PMPI User level calls */
15 extern "C" { // Obviously, the C MPI interface should use the C linkage
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_group(MPI_Comm comm, MPI_Group * group)
55 if (comm == MPI_COMM_NULL) {
57 } else if (group == nullptr) {
60 *group = comm->group();
61 if (*group != MPI_COMM_WORLD->group() && *group != MPI_GROUP_NULL && *group != MPI_GROUP_EMPTY)
67 int PMPI_Comm_compare(MPI_Comm comm1, MPI_Comm comm2, int *result)
69 if (comm1 == MPI_COMM_NULL || comm2 == MPI_COMM_NULL) {
71 } else if (result == nullptr) {
74 if (comm1 == comm2) { /* Same communicators means same groups */
77 *result = comm1->group()->compare(comm2->group());
78 if (*result == MPI_IDENT) {
79 *result = MPI_CONGRUENT;
86 int PMPI_Comm_dup(MPI_Comm comm, MPI_Comm * newcomm)
88 if (comm == MPI_COMM_NULL) {
90 } else if (newcomm == nullptr) {
93 return comm->dup(newcomm);
97 int PMPI_Comm_create(MPI_Comm comm, MPI_Group group, MPI_Comm * newcomm)
99 if (comm == MPI_COMM_NULL) {
101 } else if (group == MPI_GROUP_NULL) {
102 return MPI_ERR_GROUP;
103 } else if (newcomm == nullptr) {
105 } else if(group->rank(smpi_process()->index())==MPI_UNDEFINED){
106 *newcomm= MPI_COMM_NULL;
110 *newcomm = new simgrid::smpi::Comm(group, nullptr);
115 int PMPI_Comm_free(MPI_Comm * comm)
117 if (comm == nullptr) {
119 } else if (*comm == MPI_COMM_NULL) {
122 simgrid::smpi::Comm::destroy(*comm);
123 *comm = MPI_COMM_NULL;
128 int PMPI_Comm_disconnect(MPI_Comm * comm)
130 /* TODO: wait until all communication in comm are done */
131 if (comm == nullptr) {
133 } else if (*comm == MPI_COMM_NULL) {
136 simgrid::smpi::Comm::destroy(*comm);
137 *comm = MPI_COMM_NULL;
142 int PMPI_Comm_split(MPI_Comm comm, int color, int key, MPI_Comm* comm_out)
147 if (comm_out == nullptr) {
148 retval = MPI_ERR_ARG;
149 } else if (comm == MPI_COMM_NULL) {
150 retval = MPI_ERR_COMM;
152 *comm_out = comm->split(color, key);
153 retval = MPI_SUCCESS;
160 int PMPI_Comm_create_group(MPI_Comm comm, MPI_Group group, int, MPI_Comm* comm_out)
165 if (comm_out == nullptr) {
166 retval = MPI_ERR_ARG;
167 } else if (comm == MPI_COMM_NULL) {
168 retval = MPI_ERR_COMM;
170 retval = MPI_Comm_create(comm, group, comm_out);
177 MPI_Comm PMPI_Comm_f2c(MPI_Fint comm){
178 return static_cast<MPI_Comm>(simgrid::smpi::Comm::f2c(comm));
181 MPI_Fint PMPI_Comm_c2f(MPI_Comm comm){
185 int PMPI_Comm_get_attr (MPI_Comm comm, int comm_keyval, void *attribute_val, int *flag)
187 return PMPI_Attr_get(comm, comm_keyval, attribute_val,flag);
190 int PMPI_Comm_set_attr (MPI_Comm comm, int comm_keyval, void *attribute_val)
192 return PMPI_Attr_put(comm, comm_keyval, attribute_val);
195 int PMPI_Comm_delete_attr (MPI_Comm comm, int comm_keyval)
197 return PMPI_Attr_delete(comm, comm_keyval);
200 int PMPI_Comm_create_keyval(MPI_Comm_copy_attr_function* copy_fn, MPI_Comm_delete_attr_function* delete_fn, int* keyval,
203 return PMPI_Keyval_create(copy_fn, delete_fn, keyval, extra_state);
206 int PMPI_Comm_free_keyval(int* keyval) {
207 return PMPI_Keyval_free(keyval);
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)
214 else if (comm==MPI_COMM_NULL)
217 return comm->attr_delete<simgrid::smpi::Comm>(keyval);
220 int PMPI_Attr_get(MPI_Comm comm, int keyval, void* attr_value, int* flag) {
223 static int tag_ub = INT_MAX;
224 static int last_used_code = MPI_ERR_LASTCODE;
226 if (comm==MPI_COMM_NULL){
236 *static_cast<int**>(attr_value) = &zero;
238 case MPI_UNIVERSE_SIZE:
240 *static_cast<int**>(attr_value) = &smpi_universe_size;
242 case MPI_LASTUSEDCODE:
244 *static_cast<int**>(attr_value) = &last_used_code;
248 *static_cast<int**>(attr_value) = &tag_ub;
250 case MPI_WTIME_IS_GLOBAL:
252 *static_cast<int**>(attr_value) = &one;
255 return comm->attr_get<simgrid::smpi::Comm>(keyval, attr_value, flag);
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)
263 else if (comm==MPI_COMM_NULL)
266 return comm->attr_put<simgrid::smpi::Comm>(keyval, attr_value);