40 size_t num_names, MPI_Comm comm_) {
43 size_t num_global_components =
54 1 *
sizeof(*comp_config) +
57 comp_config->
num_comps = num_global_components;
58 for (
size_t i = 0; i < num_global_components; ++i)
65 comp_config->
comps, num_global_components,
69 MPI_Group world_group;
75 int * rank_mask =
xmalloc(2 * (
size_t)comm_size *
sizeof(*rank_mask));
76 int * ranks = rank_mask + (size_t)comm_size;
79 for (
size_t i = 0; i < num_global_components; ++i) {
82 char const * comp_name = comp->name;
86 for (
size_t j = 0; (j < num_names) && !
is_local; ++j)
87 is_local = !strcmp(comp_name, names[j]);
92 &
is_local, 1, MPI_INT, rank_mask, 1, MPI_INT, comm), comm);
96 for (
int rank = 0; rank < comm_size; ++rank) {
97 if (rank_mask[rank]) {
98 ranks[rank_count] = rank;
104 MPI_Group comp_group;
107 world_group, rank_count, ranks, &comp_group), comm);
109 comp->group = comp_group;
144 const char ** names,
size_t num_names) {
147 if (num_names == 0)
return MPI_COMM_NULL;
151 "ERROR(yac_component_config_get_comps_comm): too many components (%zu)",
155 int * comp_idxs =
xmalloc(num_names *
sizeof(*comp_idxs));
156 for (
size_t i = 0; i < num_names; ++i)
159 "yac_component_config_get_comps_comm", comp_config, names[i]);
162 qsort(comp_idxs, num_names,
sizeof(*comp_idxs),
compare_int);
165 MPI_Group comps_group = MPI_GROUP_EMPTY;
166 for (
size_t i = 0; i < num_names; ++i) {
167 int comp_idx = comp_idxs[i];
168 MPI_Group comp_group = comp_config->
comps[comp_idx].
group;
169 MPI_Group union_group;
171 MPI_Group_union(comps_group, comp_group, &union_group),
173 if (comps_group != MPI_GROUP_EMPTY)
175 comps_group = union_group;
178 int group_rank, group_size;
182 group_rank != MPI_UNDEFINED,
183 "ERROR(yac_component_config_get_comps_comm): "
184 "local process not included in any component provided to this routine");
187 int group_neigh_ranks[3], neigh_ranks[3];
188 group_neigh_ranks[0] = (group_rank + 1) % group_size;
189 group_neigh_ranks[1] = (group_rank + group_size - 1) % group_size;
190 group_neigh_ranks[2] = group_rank;
191 MPI_Group comp_config_group;
193 MPI_Comm_group(comp_config->
comm, &comp_config_group), comp_config->
comm);
195 MPI_Group_translate_ranks(
196 comps_group, 3, group_neigh_ranks, comp_config_group, neigh_ranks),
198 MPI_Group_free(&comp_config_group);
201 int num_names_buffer = (int)num_names;
204 MPI_Sendrecv_replace(
205 &num_names_buffer, 1, MPI_INT, neigh_ranks[0], tag,
206 neigh_ranks[1], tag, comp_config->
comm, MPI_STATUS_IGNORE),
209 num_names_buffer == (
int)num_names,
210 "ERROR(yac_component_config_get_comps_comm): "
211 "processes do not agree on number of component names "
212 "(rank %d num_names %d != rank %d num_names %zu)",
213 neigh_ranks[1], num_names_buffer, neigh_ranks[2], num_names);
216 int * comp_idxs_recv_buffer =
xmalloc(num_names *
sizeof(*comp_idxs_recv_buffer));
219 comp_idxs, (
int)num_names, MPI_INT, neigh_ranks[0], tag,
220 comp_idxs_recv_buffer, (
int)num_names, MPI_INT, neigh_ranks[1], tag,
221 comp_config->
comm, MPI_STATUS_IGNORE), comp_config->
comm);
222 for (
size_t i = 0; i < num_names; ++i) {
224 comp_idxs[i] == comp_idxs_recv_buffer[i],
225 "ERROR(yac_component_config_get_comps_comm): "
226 "processes do not agree on component indices "
227 "(rank %d comp_idx[%zu] %d != rank %d comp_idx[%zu] %d)",
228 neigh_ranks[1], i, comp_idxs[i],
229 neigh_ranks[2], i, comp_idxs_recv_buffer[i]);
231 free(comp_idxs_recv_buffer);
236 MPI_Comm_create_group(
237 comp_config->
comm, comps_group, tag, &comps_comm), comp_config->
comm);