44 MPI_Comm_rank(comm, &
rank);
46 char error_string[MPI_MAX_ERROR_STRING];
47 int length_of_error_string, error_class;
49 MPI_Error_class(error_code, &error_class);
50 MPI_Error_string(error_class, error_string, &length_of_error_string);
51 fprintf(stderr,
"%3d: %s\n",
rank, error_string);
52 MPI_Abort(comm, error_code);
79void mpi_handshake(
char const **group_names, MPI_Comm *group_comms,
size_t n,
84 mh_mpi_call(MPI_Comm_test_inter(comm, &is_intercomm), comm);
86 "ERROR(mpi_handshake): inter-communicators are not supported",
90 enum { MPI_HANDSHAKE_VERSION = 1 };
91 int mh_version = MPI_HANDSHAKE_VERSION;
93 MPI_Allreduce(MPI_IN_PLACE, &mh_version, 1, MPI_INT, MPI_MIN, comm),
95 mh_assert(mh_version == MPI_HANDSHAKE_VERSION,
96 "ERROR(mpi_handshake): version mismatch."
97 "This implementation of the MPI handshake only supports version 1",
102 MPI_Comm_rank(comm, &
rank);
103 MPI_Comm_size(comm, &size);
104 for (
size_t i = 0; i < n; ++i)
105 group_comms[i] = MPI_COMM_NULL;
109 size_t group_idx = SIZE_MAX;
110 for (
size_t i = 0; (i < n) && (group_idx == SIZE_MAX); ++i)
111 if (group_comms[i] == MPI_COMM_NULL)
113 int broadcasting_rank = group_idx != SIZE_MAX ?
rank : size;
114 mh_mpi_call(MPI_Allreduce(MPI_IN_PLACE, &broadcasting_rank, 1, MPI_INT,
117 mh_assert(broadcasting_rank >= 0 && broadcasting_rank <= size,
118 "ERROR(mpi_handshake): "
119 "broadcasting rank cannot be negativ or greater than "
120 "communicator size.",
122 if (broadcasting_rank == size)
126 int group_name_buffer_size = 0;
127 if (broadcasting_rank ==
rank) {
128 size_t len = strlen(group_names[group_idx]);
130 "ERROR(yac_mpi_handshake): group name is too long", comm);
131 group_name_buffer_size = (int)len;
133 MPI_Bcast(&group_name_buffer_size, 1, MPI_INT, broadcasting_rank, comm);
134 char *group_name_buffer =
135 malloc((group_name_buffer_size + 1) *
sizeof(*group_name_buffer));
137 "ERROR(mpi_handshake): failed to allocate group name buffer",
139 if (broadcasting_rank ==
rank)
140 strcpy(group_name_buffer, group_names[group_idx]);
141 mh_mpi_call(MPI_Bcast(group_name_buffer, group_name_buffer_size, MPI_CHAR,
142 broadcasting_rank, comm),
144 group_name_buffer[group_name_buffer_size] =
'\0';
147 group_idx = SIZE_MAX;
148 for (
size_t i = 0; (i < n) && (group_idx == SIZE_MAX); ++i)
149 if (!strcmp(group_name_buffer, group_names[i])) {
150 mh_assert(group_comms[i] == MPI_COMM_NULL,
151 "ERROR(yac_mpi_handshake): "
152 "Group communicator for a group that was already created "
153 "was broadcasted again.",
157 free(group_name_buffer);
160 (group_idx != SIZE_MAX) ? 0 : MPI_UNDEFINED,
163 if (group_idx != SIZE_MAX) {
164 group_comms[group_idx] = group_comm;
171 MPI_Comm comm_c = MPI_Comm_f2c(comm);
172 MPI_Comm *group_comms_c = malloc(n *
sizeof(*group_comms_c));
174 for (
int i = 0; i < n; ++i)
175 group_comms[i] = MPI_Comm_c2f(group_comms_c[i]);