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));
49 char * rank_str = strtok(rank_list_copy,
",");
50 while (rank_str != NULL) {
51 int curr_rank = atoi(rank_str);
53 curr_rank >= 0,
"ERROR(read_rank_list): \"%s\" is not a valid rank",
55 world_ranks[num_ranks++] = curr_rank;
56 rank_str = strtok(NULL,
",");
61 qsort(world_ranks, num_ranks,
sizeof(*world_ranks),
compare_int);
67 ranks =
xmalloc(num_ranks *
sizeof(ranks));
68 MPI_Group world_group, comm_group;
70 MPI_Comm_group(MPI_COMM_WORLD, &world_group), MPI_COMM_WORLD);
73 MPI_Group_translate_ranks(
74 world_group, (
int)num_ranks, world_ranks,
75 comm_group, ranks), MPI_COMM_WORLD);
77 yac_mpi_call(MPI_Group_free(&world_group), MPI_COMM_WORLD);
81 size_t new_num_ranks = 0;
82 for (
size_t i = 0; i < num_ranks; ++i) {
83 if (ranks[i] != MPI_UNDEFINED) {
84 if (i != new_num_ranks)
85 ranks[new_num_ranks] = ranks[i];
89 num_ranks = new_num_ranks;
92 qsort(ranks, num_ranks,
sizeof(*ranks),
compare_int);
99 ranks =
xrealloc(ranks, num_ranks *
sizeof(*ranks));
101 MPI_Bcast(ranks, (
int)num_ranks, MPI_INT, 0, comm), comm);
111 ranks =
xmalloc(num_ranks *
sizeof(*ranks));
113 MPI_Bcast(ranks, (
int)num_ranks, MPI_INT, 0, comm), comm);
116 *num_ranks_ = num_ranks;
127 MPI_Comm comm,
size_t * num_io_ranks_,
int ** io_ranks_) {
133 int max_num_io_rank_per_node;
141 if ((max_num_io_rank_per_node_str != NULL) &&
142 (max_num_io_rank_per_node_str[0] !=
'\0')) {
144 max_num_io_rank_per_node = atoi(max_num_io_rank_per_node_str);
146 (max_num_io_rank_per_node > 0) || (max_num_io_rank_per_node == -1),
147 "ERROR(check_io_max_num_ranks_per_node): "
148 "\"%s\" is not a valid value for the maximum number of io ranks "
149 "per node", max_num_io_rank_per_node_str);
154 MPI_Bcast(&max_num_io_rank_per_node, 1, MPI_INT, 0, comm), comm);
157 MPI_Bcast(&max_num_io_rank_per_node, 1, MPI_INT, 0, comm), comm);
161 if (max_num_io_rank_per_node == -1)
return;
167 comm, MPI_COMM_TYPE_SHARED, rank, MPI_INFO_NULL, &node_comm), comm);
171 yac_mpi_call(MPI_Comm_rank(node_comm, &node_rank), node_comm);
174 int * node_ranks =
xmalloc(*num_io_ranks_ *
sizeof(*node_ranks));
175 MPI_Group io_group, node_group;
177 yac_mpi_call(MPI_Comm_group(node_comm, &node_group), node_comm);
179 MPI_Group_translate_ranks(
180 io_group, (
int)*num_io_ranks_, *io_ranks_,
181 node_group, node_ranks), comm);
187 size_t num_node_io_ranks = 0;
188 for (
size_t i = 0; i < *num_io_ranks_; ++i) {
189 if (node_ranks[i] != MPI_UNDEFINED) {
190 if (i != num_node_io_ranks)
191 node_ranks[num_node_io_ranks] = node_ranks[i];
197 qsort(node_ranks, num_node_io_ranks,
sizeof(*node_ranks),
compare_int);
200 int local_is_io_rank = 0;
202 (i < num_node_io_ranks) &&
203 (i < (
size_t)max_num_io_rank_per_node) && !local_is_io_rank; ++i)
204 if (node_ranks[i] == node_rank) local_is_io_rank = 1;
208 int * is_io_rank =
xmalloc((
size_t)size *
sizeof(*is_io_rank));
211 &local_is_io_rank, 1, MPI_INT, is_io_rank, 1, MPI_INT, comm), comm);
214 size_t num_io_ranks = 0;
215 for (
int i = 0; i < size; ++i)
216 if (is_io_rank[i]) is_io_rank[num_io_ranks++] = i;
219 *num_io_ranks_ = num_io_ranks;
220 *io_ranks_ =
xrealloc(is_io_rank, num_io_ranks *
sizeof(**io_ranks_));
224 MPI_Comm comm,
size_t * num_io_ranks,
int ** io_ranks) {
229 int max_num_ranks = -1;
237 if ((max_num_ranks_str != NULL) && (max_num_ranks_str[0] !=
'\0')) {
238 max_num_ranks = atoi(max_num_ranks_str);
240 (max_num_ranks > 0) || (max_num_ranks == -1),
241 "ERROR(check_io_max_num_ranks): "
242 "\"%s\" is not a valid value for the maximum number of io ranks",
247 MPI_Bcast(&max_num_ranks, 1, MPI_INT, 0, comm), comm);
250 MPI_Bcast(&max_num_ranks, 1, MPI_INT, 0, comm), comm);
254 if (max_num_ranks == -1)
return;
256 if ((max_num_ranks > 0) && ((
size_t)max_num_ranks < *num_io_ranks)) {
258 xrealloc(*io_ranks, (
size_t)max_num_ranks *
sizeof(**io_ranks));
259 *num_io_ranks = (size_t)max_num_ranks;
264 MPI_Comm comm,
size_t * num_io_ranks,
int ** io_ranks) {
267 size_t num_io_ranks_excluded;
268 int * io_ranks_excluded;
273 if (num_io_ranks_excluded > 0) {
276 qsort(*io_ranks, *num_io_ranks,
sizeof(**io_ranks),
compare_int);
279 size_t new_num_io_ranks = 0;
280 for (
size_t i = 0, j = 0; i < *num_io_ranks; ++i) {
282 while ((j < num_io_ranks_excluded) &&
283 (io_ranks_excluded[j] < (*io_ranks)[i])) ++j;
285 if ((j >= num_io_ranks_excluded) ||
286 ((*io_ranks)[i] != io_ranks_excluded[j])) {
288 if (i != new_num_io_ranks)
289 (*io_ranks)[new_num_io_ranks] = (*io_ranks)[i];
294 if (new_num_io_ranks != *num_io_ranks) {
295 *io_ranks =
xrealloc(*io_ranks, new_num_io_ranks *
sizeof(**io_ranks));
296 *num_io_ranks = new_num_io_ranks;
300 free(io_ranks_excluded);
304 MPI_Comm comm,
int * local_is_io_,
int ** io_ranks_,
int * num_io_ranks_) {
310 size_t num_io_ranks = 0;
311 int * io_ranks = NULL;
317 if (num_io_ranks == 0) {
318 num_io_ranks = (size_t)size;
319 io_ranks =
xmalloc(num_io_ranks *
sizeof(*io_ranks));
320 for (
int i = 0; i < size; ++i) io_ranks[i] = i;
333 num_io_ranks > 0,
"ERROR(yac_get_io_ranks): could not determine io ranks");
336 for (
size_t i = 0; (i < num_io_ranks) && !local_is_io; ++i)
337 if (io_ranks[i] == rank) local_is_io = 1;
339 *local_is_io_ = local_is_io;
340 *io_ranks_ = io_ranks;
341 *num_io_ranks_ = (int)num_io_ranks;