24 char const * env_name, MPI_Comm comm,
size_t * num_ranks_,
int ** ranks_) {
37 char * rank_list_str = getenv(env_name);
38 if ((rank_list_str != NULL) && (rank_list_str[0] !=
'\0')) {
40 int temp_num_ranks = 1;
41 for (
char * curr_char = rank_list_str + 1; *curr_char !=
'\0'; ++curr_char)
42 if (*curr_char ==
',') ++temp_num_ranks;
44 char * rank_list_copy = strdup(rank_list_str);
46 int * world_ranks =
xmalloc(temp_num_ranks *
sizeof(*world_ranks));
48 yac_mpi_call(MPI_Comm_size(MPI_COMM_WORLD, &world_size), MPI_COMM_WORLD);
51 char * rank_str = strtok(rank_list_copy,
",");
52 while (rank_str != NULL) {
53 int curr_rank = atoi(rank_str);
55 curr_rank >= 0,
"ERROR(read_rank_list): \"%s\" is not a valid rank",
58 curr_rank < world_size,
59 "ERROR(read_rank_list): rank %d exceeds size of MPI_COMM_WORLD (%d)",
60 curr_rank, world_size);
61 world_ranks[num_ranks++] = curr_rank;
62 rank_str = strtok(NULL,
",");
67 qsort(world_ranks, num_ranks,
sizeof(*world_ranks),
compare_int);
73 ranks =
xmalloc(num_ranks *
sizeof(ranks));
74 MPI_Group world_group, comm_group;
76 MPI_Comm_group(MPI_COMM_WORLD, &world_group), MPI_COMM_WORLD);
79 MPI_Group_translate_ranks(
80 world_group, (
int)num_ranks, world_ranks,
81 comm_group, ranks), MPI_COMM_WORLD);
83 yac_mpi_call(MPI_Group_free(&world_group), MPI_COMM_WORLD);
87 size_t new_num_ranks = 0;
88 for (
size_t i = 0; i < num_ranks; ++i) {
89 if (ranks[i] != MPI_UNDEFINED) {
90 if (i != new_num_ranks)
91 ranks[new_num_ranks] = ranks[i];
95 num_ranks = new_num_ranks;
98 qsort(ranks, num_ranks,
sizeof(*ranks),
compare_int);
105 ranks =
xrealloc(ranks, num_ranks *
sizeof(*ranks));
107 MPI_Bcast(ranks, (
int)num_ranks, MPI_INT, 0, comm), comm);
117 ranks =
xmalloc(num_ranks *
sizeof(*ranks));
119 MPI_Bcast(ranks, (
int)num_ranks, MPI_INT, 0, comm), comm);
122 *num_ranks_ = num_ranks;
133 MPI_Comm comm,
size_t * num_io_ranks_,
int ** io_ranks_) {
139 int max_num_io_rank_per_node;
147 if ((max_num_io_rank_per_node_str != NULL) &&
148 (max_num_io_rank_per_node_str[0] !=
'\0')) {
150 max_num_io_rank_per_node = atoi(max_num_io_rank_per_node_str);
152 (max_num_io_rank_per_node > 0) || (max_num_io_rank_per_node == -1),
153 "ERROR(check_io_max_num_ranks_per_node): "
154 "\"%s\" is not a valid value for the maximum number of io ranks "
155 "per node", max_num_io_rank_per_node_str);
160 MPI_Bcast(&max_num_io_rank_per_node, 1, MPI_INT, 0, comm), comm);
163 MPI_Bcast(&max_num_io_rank_per_node, 1, MPI_INT, 0, comm), comm);
167 if (max_num_io_rank_per_node == -1)
return;
173 comm, MPI_COMM_TYPE_SHARED, rank, MPI_INFO_NULL, &node_comm), comm);
177 yac_mpi_call(MPI_Comm_rank(node_comm, &node_rank), node_comm);
180 int * node_ranks =
xmalloc(*num_io_ranks_ *
sizeof(*node_ranks));
181 MPI_Group io_group, node_group;
183 yac_mpi_call(MPI_Comm_group(node_comm, &node_group), node_comm);
185 MPI_Group_translate_ranks(
186 io_group, (
int)*num_io_ranks_, *io_ranks_,
187 node_group, node_ranks), comm);
193 size_t num_node_io_ranks = 0;
194 for (
size_t i = 0; i < *num_io_ranks_; ++i) {
195 if (node_ranks[i] != MPI_UNDEFINED) {
196 if (i != num_node_io_ranks)
197 node_ranks[num_node_io_ranks] = node_ranks[i];
203 qsort(node_ranks, num_node_io_ranks,
sizeof(*node_ranks),
compare_int);
206 int local_is_io_rank = 0;
208 (i < num_node_io_ranks) &&
209 (i < (
size_t)max_num_io_rank_per_node) && !local_is_io_rank; ++i)
210 if (node_ranks[i] == node_rank) local_is_io_rank = 1;
214 int * is_io_rank =
xmalloc((
size_t)size *
sizeof(*is_io_rank));
217 &local_is_io_rank, 1, MPI_INT, is_io_rank, 1, MPI_INT, comm), comm);
220 size_t num_io_ranks = 0;
221 for (
int i = 0; i < size; ++i)
222 if (is_io_rank[i]) is_io_rank[num_io_ranks++] = i;
225 *num_io_ranks_ = num_io_ranks;
226 *io_ranks_ =
xrealloc(is_io_rank, num_io_ranks *
sizeof(**io_ranks_));
230 MPI_Comm comm,
size_t * num_io_ranks,
int ** io_ranks) {
235 int max_num_ranks = -1;
243 if ((max_num_ranks_str != NULL) && (max_num_ranks_str[0] !=
'\0')) {
244 max_num_ranks = atoi(max_num_ranks_str);
246 (max_num_ranks > 0) || (max_num_ranks == -1),
247 "ERROR(check_io_max_num_ranks): "
248 "\"%s\" is not a valid value for the maximum number of io ranks",
253 MPI_Bcast(&max_num_ranks, 1, MPI_INT, 0, comm), comm);
256 MPI_Bcast(&max_num_ranks, 1, MPI_INT, 0, comm), comm);
260 if (max_num_ranks == -1)
return;
262 if ((max_num_ranks > 0) && ((
size_t)max_num_ranks < *num_io_ranks)) {
264 xrealloc(*io_ranks, (
size_t)max_num_ranks *
sizeof(**io_ranks));
265 *num_io_ranks = (size_t)max_num_ranks;
270 MPI_Comm comm,
size_t * num_io_ranks,
int ** io_ranks) {
273 size_t num_io_ranks_excluded;
274 int * io_ranks_excluded;
279 if (num_io_ranks_excluded > 0) {
282 qsort(*io_ranks, *num_io_ranks,
sizeof(**io_ranks),
compare_int);
285 size_t new_num_io_ranks = 0;
286 for (
size_t i = 0, j = 0; i < *num_io_ranks; ++i) {
288 while ((j < num_io_ranks_excluded) &&
289 (io_ranks_excluded[j] < (*io_ranks)[i])) ++j;
291 if ((j >= num_io_ranks_excluded) ||
292 ((*io_ranks)[i] != io_ranks_excluded[j])) {
294 if (i != new_num_io_ranks)
295 (*io_ranks)[new_num_io_ranks] = (*io_ranks)[i];
300 if (new_num_io_ranks != *num_io_ranks) {
301 *io_ranks =
xrealloc(*io_ranks, new_num_io_ranks *
sizeof(**io_ranks));
302 *num_io_ranks = new_num_io_ranks;
306 free(io_ranks_excluded);
310 MPI_Comm comm,
int * local_is_io_,
int ** io_ranks_,
int * num_io_ranks_) {
316 size_t num_io_ranks = 0;
317 int * io_ranks = NULL;
323 if (num_io_ranks == 0) {
324 num_io_ranks = (size_t)size;
325 io_ranks =
xmalloc(num_io_ranks *
sizeof(*io_ranks));
326 for (
int i = 0; i < size; ++i) io_ranks[i] = i;
339 num_io_ranks > 0,
"ERROR(yac_get_io_ranks): could not determine io ranks");
342 for (
size_t i = 0; (i < num_io_ranks) && !local_is_io; ++i)
343 if (io_ranks[i] == rank) local_is_io = 1;
345 *local_is_io_ = local_is_io;
346 *io_ranks_ = io_ranks;
347 *num_io_ranks_ = (int)num_io_ranks;