YAC 3.13.0
Yet Another Coupler
Loading...
Searching...
No Matches
test_io_config.c
Go to the documentation of this file.
1// Copyright (c) 2024 The YAC Authors
2//
3// SPDX-License-Identifier: BSD-3-Clause
4
5#include <stdio.h>
6#include <stdlib.h>
7
8#include <mpi.h>
9
10#include "tests.h"
11#include "test_common.h"
12#include "io_utils.h"
13
20static void utest_check_io_config(
21 MPI_Comm comm, int ref_local_is_io, int * ref_io_ranks, int ref_num_io_ranks);
22static void utest_generate_node_wise_ref_data(
23 MPI_Comm comm, int num_io_ranks_per_node,
24 int ** ref_io_ranks, int * ref_num_io_ranks, int * ref_local_is_io);
25
26int main(void) {
27
28 MPI_Init(NULL, NULL);
29
30 int comm_rank, comm_size;
31 MPI_Comm_rank(MPI_COMM_WORLD, &comm_rank);
32 MPI_Comm_size(MPI_COMM_WORLD, &comm_size);
33
34 if (comm_size != 12) {
35 PUT_ERR("ERROR: wrong number of processes");
36 MPI_Finalize();
37 return TEST_EXIT_CODE;
38 }
39
40 { // rank list
41
42 // clear environment
44
45 setenv("YAC_IO_RANK_LIST", "1,3,5,7,9,11", 1);
46 setenv("YAC_IO_MAX_NUM_RANKS_PER_NODE", "12", 1);
47
48 int ref_local_is_io = comm_rank & 1;
49 int ref_io_ranks[] = {1,3,5,7,9,11};
50 int ref_num_io_ranks = (int)(sizeof(ref_io_ranks) / sizeof(ref_io_ranks[0]));
51
52 utest_check_io_config(
53 MPI_COMM_WORLD, ref_local_is_io, ref_io_ranks, ref_num_io_ranks);
54 }
55
56 { // rank list (order of processes in reversed compared to MPI_COMM_WORLD)
57
58 // clear environment
60
61 setenv("YAC_IO_RANK_LIST", "0,1,4,7", 1);
62 setenv("YAC_IO_MAX_NUM_RANKS_PER_NODE", "12", 1);
63
64 MPI_Comm reverse_world_comm;
65 MPI_Comm_split(
66 MPI_COMM_WORLD, 1, comm_size - comm_rank, &reverse_world_comm);
67
68 int ref_local_is_io = (comm_rank == 0) || (comm_rank == 1) ||
69 (comm_rank == 4) || (comm_rank == 7);
70 int ref_io_ranks[] = {4,7,10,11};
71 int ref_num_io_ranks = (int)(sizeof(ref_io_ranks) / sizeof(ref_io_ranks[0]));
72
73 utest_check_io_config(
74 reverse_world_comm, ref_local_is_io, ref_io_ranks, ref_num_io_ranks);
75
76 MPI_Comm_free(&reverse_world_comm);
77 }
78
79 { // rank list (comm contains only a subset of MPI_COMM_WORLD)
80
81 // clear environment
83
84 setenv("YAC_IO_RANK_LIST", "1,4,7,10", 1);
85 setenv("YAC_IO_MAX_NUM_RANKS_PER_NODE", "12", 1);
86
87 int is_in_subgroup = (comm_rank >= 4) && (comm_rank <= 7);
88 MPI_Comm sub_world_comm;
89 MPI_Comm_split(
90 MPI_COMM_WORLD, is_in_subgroup, comm_rank, &sub_world_comm);
91
92 int ref_local_is_io = (comm_rank == 4) || (comm_rank == 7);
93 int ref_io_ranks[] = {0,3};
94 int ref_num_io_ranks = (int)(sizeof(ref_io_ranks) / sizeof(ref_io_ranks[0]));
95
96 if (is_in_subgroup)
97 utest_check_io_config(
98 sub_world_comm, ref_local_is_io, ref_io_ranks, ref_num_io_ranks);
99
100 MPI_Comm_free(&sub_world_comm);
101 }
102
103 { // rank list + maximum number of io ranks
104
105 // clear environment
107
108 setenv("YAC_IO_RANK_LIST", "1,3,5,7,9,11", 1);
109 setenv("YAC_IO_MAX_NUM_RANKS", "3", 1);
110 setenv("YAC_IO_MAX_NUM_RANKS_PER_NODE", "12", 1);
111
112 int ref_local_is_io = (comm_rank == 1) || (comm_rank == 3) ||
113 (comm_rank == 5);
114 int ref_io_ranks[] = {1,3,5};
115 int ref_num_io_ranks = (int)(sizeof(ref_io_ranks) / sizeof(ref_io_ranks[0]));
116
117 utest_check_io_config(
118 MPI_COMM_WORLD, ref_local_is_io, ref_io_ranks, ref_num_io_ranks);
119 }
120
121 { // rank list + rank exclude list
122
123 // clear environment
125
126 setenv("YAC_IO_RANK_LIST", "0,1,2,3,4,5,6,7,8,9,10,11", 1);
127 setenv("YAC_IO_RANK_EXCLUDE_LIST", "0,2,4,6,8,10", 1);
128 setenv("YAC_IO_MAX_NUM_RANKS_PER_NODE", "12", 1);
129
130 int ref_local_is_io = comm_rank & 1;
131 int ref_io_ranks[] = {1,3,5,7,9,11};
132 int ref_num_io_ranks = (int)(sizeof(ref_io_ranks) / sizeof(ref_io_ranks[0]));
133
134 utest_check_io_config(
135 MPI_COMM_WORLD, ref_local_is_io, ref_io_ranks, ref_num_io_ranks);
136 }
137
138 { // rank list + rank exclude list + sub-communicator
139
140 // clear environment
142
143 setenv("YAC_IO_RANK_LIST", "0,1,2,3,4,5,6,7,8,9,10,11", 1);
144 setenv("YAC_IO_RANK_EXCLUDE_LIST", "0,2,4,6,8,10", 1);
145 setenv("YAC_IO_MAX_NUM_RANKS_PER_NODE", "12", 1);
146
147 int is_in_subgroup = (comm_rank >= 4) && (comm_rank <= 7);
148 MPI_Comm sub_world_comm;
149 MPI_Comm_split(
150 MPI_COMM_WORLD, is_in_subgroup, comm_rank, &sub_world_comm);
151
152 int ref_local_is_io = (comm_rank & 1) && is_in_subgroup;
153 int ref_io_ranks[] = {1,3};
154 int ref_num_io_ranks = (int)(sizeof(ref_io_ranks) / sizeof(ref_io_ranks[0]));
155
156 if (is_in_subgroup)
157 utest_check_io_config(
158 sub_world_comm, ref_local_is_io, ref_io_ranks, ref_num_io_ranks);
159
160 MPI_Comm_free(&sub_world_comm);
161 }
162
163 { // limited number of ranks per node
164
165 // clear environment
167
168 setenv("YAC_IO_MAX_NUM_RANKS_PER_NODE", "1", 1);
169
170 int ref_local_is_io;
171 int * ref_io_ranks;
172 int ref_num_io_ranks;
173
174 utest_generate_node_wise_ref_data(
175 MPI_COMM_WORLD, 1, &ref_io_ranks, &ref_num_io_ranks, &ref_local_is_io);
176
177 utest_check_io_config(
178 MPI_COMM_WORLD, ref_local_is_io, ref_io_ranks, ref_num_io_ranks);
179
180 free(ref_io_ranks);
181 }
182
183 MPI_Finalize();
184
185 return TEST_EXIT_CODE;
186}
187
188static void utest_check_io_config(
189 MPI_Comm comm, int ref_local_is_io, int * ref_io_ranks, int ref_num_io_ranks) {
190
191 int local_is_io;
192 int * io_ranks;
193 int num_io_ranks;
194 yac_get_io_ranks(comm, &local_is_io, &io_ranks, &num_io_ranks);
195
196 int comm_size;
197 MPI_Comm_size(comm, &comm_size);
198
199 int * flag = calloc((size_t)comm_size, sizeof(*flag));
200
201 if (ref_local_is_io != local_is_io)
202 PUT_ERR("wrong local_is_io");
203 if (ref_num_io_ranks != num_io_ranks)
204 PUT_ERR("wrong num io ranks");
205
206 for (int i = 0; i < num_io_ranks; ++i) {
207 if (flag[io_ranks[i]])
208 PUT_ERR("duplicated entry in io_ranks");
209 flag[io_ranks[i]] = 1;
210 }
211
212 for (int i = 0; i < ref_num_io_ranks; ++i)
213 if (!flag[ref_io_ranks[i]])
214 PUT_ERR("wrong io_ranks");
215
216 free(flag);
217 free(io_ranks);
218}
219
220static void utest_generate_node_wise_ref_data(
221 MPI_Comm comm, int num_io_ranks_per_node,
222 int ** ref_io_ranks, int * ref_num_io_ranks, int * ref_local_is_io) {
223
224 int comm_rank, comm_size;
225 MPI_Comm_rank(comm, &comm_rank);
226 MPI_Comm_size(comm, &comm_size);
227
228 MPI_Comm split_comm;
229 MPI_Comm_split_type(
230 comm, MPI_COMM_TYPE_SHARED, comm_rank, MPI_INFO_NULL, &split_comm);
231
232 int split_comm_rank;
233 MPI_Comm_rank(split_comm, &split_comm_rank);
234
235 *ref_local_is_io = split_comm_rank < num_io_ranks_per_node;
236
237 int * is_io_rank = xmalloc((size_t)comm_size * sizeof(*is_io_rank));
238 MPI_Allgather(
239 ref_local_is_io, 1, MPI_INT, is_io_rank, 1, MPI_INT, comm);
240
241 int num_io_ranks = 0;
242 for (int i = 0; i < comm_size; ++i)
243 if (is_io_rank[i])
244 is_io_rank[num_io_ranks++] = i;
245
246 *ref_io_ranks =
247 xrealloc(is_io_rank, (size_t)num_io_ranks * sizeof(**ref_io_ranks));
248 *ref_num_io_ranks = num_io_ranks;
249}
void yac_get_io_ranks(MPI_Comm comm, int *local_is_io_, int **io_ranks_, int *num_io_ranks_)
Definition io_utils.c:309
#define xrealloc(ptr, size)
Definition ppm_xfuncs.h:67
#define xmalloc(size)
Definition ppm_xfuncs.h:66
void clear_yac_io_env()
static MPI_Comm split_comm
#define TEST_EXIT_CODE
Definition tests.h:14
#define PUT_ERR(string)
Definition tests.h:10