44 size_t num_names, MPI_Comm comm_) {
58 1 *
sizeof(*comp_config) +
73 MPI_Group world_group;
79 int * rank_mask =
xmalloc(2 * (
size_t)comm_size *
sizeof(*rank_mask));
80 int * ranks = rank_mask + (size_t)comm_size;
86 char const * comp_name = comp->name;
90 for (
size_t j = 0; (j < num_names) && !
is_local; ++j)
91 is_local = !strcmp(comp_name, names[j]);
96 &
is_local, 1, MPI_INT, rank_mask, 1, MPI_INT, comm), comm);
100 for (
int rank = 0; rank < comm_size; ++rank) {
101 if (rank_mask[rank]) {
102 ranks[rank_count] = rank;
108 MPI_Group comp_group;
111 world_group, rank_count, ranks, &comp_group), comm);
113 comp->group = comp_group;
148 const char ** names,
size_t num_names) {
151 if (num_names == 0)
return MPI_COMM_NULL;
155 "ERROR(yac_component_config_get_comps_comm): too many components (%zu)",
159 int * comp_idxs =
xmalloc(num_names *
sizeof(*comp_idxs));
160 for (
size_t i = 0; i < num_names; ++i)
163 "yac_component_config_get_comps_comm", comp_config, names[i]);
166 qsort(comp_idxs, num_names,
sizeof(*comp_idxs),
compare_int);
169 MPI_Group comps_group = MPI_GROUP_EMPTY;
170 for (
size_t i = 0; i < num_names; ++i) {
171 int comp_idx = comp_idxs[i];
172 MPI_Group comp_group = comp_config->
comps[comp_idx].
group;
173 MPI_Group union_group;
175 MPI_Group_union(comps_group, comp_group, &union_group),
177 if (comps_group != MPI_GROUP_EMPTY)
179 comps_group = union_group;
182 int group_rank, group_size;
186 group_rank != MPI_UNDEFINED,
187 "ERROR(yac_component_config_get_comps_comm): "
188 "local process not included in any component provided to this routine");
191 int group_neigh_ranks[3], neigh_ranks[3];
192 group_neigh_ranks[0] = (group_rank + 1) % group_size;
193 group_neigh_ranks[1] = (group_rank + group_size - 1) % group_size;
194 group_neigh_ranks[2] = group_rank;
195 MPI_Group comp_config_group;
197 MPI_Comm_group(comp_config->
comm, &comp_config_group), comp_config->
comm);
199 MPI_Group_translate_ranks(
200 comps_group, 3, group_neigh_ranks, comp_config_group, neigh_ranks),
202 MPI_Group_free(&comp_config_group);
205 int num_names_buffer = (int)num_names;
208 MPI_Sendrecv_replace(
209 &num_names_buffer, 1, MPI_INT, neigh_ranks[0], tag,
210 neigh_ranks[1], tag, comp_config->
comm, MPI_STATUS_IGNORE),
213 num_names_buffer == (
int)num_names,
214 "ERROR(yac_component_config_get_comps_comm): "
215 "processes do not agree on number of component names "
216 "(rank %d num_names %d != rank %d num_names %zu)",
217 neigh_ranks[1], num_names_buffer, neigh_ranks[2], num_names);
220 int * comp_idxs_recv_buffer =
xmalloc(num_names *
sizeof(*comp_idxs_recv_buffer));
223 comp_idxs, (
int)num_names, MPI_INT, neigh_ranks[0], tag,
224 comp_idxs_recv_buffer, (
int)num_names, MPI_INT, neigh_ranks[1], tag,
225 comp_config->
comm, MPI_STATUS_IGNORE), comp_config->
comm);
226 for (
size_t i = 0; i < num_names; ++i) {
228 comp_idxs[i] == comp_idxs_recv_buffer[i],
229 "ERROR(yac_component_config_get_comps_comm): "
230 "processes do not agree on component indices "
231 "(rank %d comp_idx[%zu] %d != rank %d comp_idx[%zu] %d)",
232 neigh_ranks[1], i, comp_idxs[i],
233 neigh_ranks[2], i, comp_idxs_recv_buffer[i]);
235 free(comp_idxs_recv_buffer);
240 MPI_Comm_create_group(
241 comp_config->
comm, comps_group, tag, &comps_comm), comp_config->
comm);