1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
4 * (C) 2001 by Argonne National Laboratory.
5 * See COPYRIGHT in top-level directory.
9 Exercise communicator routines.
11 This C version derived from a Fortran test program from ....
19 int test_communicators(void);
20 int copy_fn(MPI_Comm, int, void *, void *, void *, int *);
21 int delete_fn(MPI_Comm, int, void *, void *);
23 #define FFLUSH fflush(stdout);
28 int main(int argc, char **argv)
31 MTest_Init(&argc, &argv);
33 errs = test_communicators();
39 int copy_fn(MPI_Comm oldcomm, int keyval, void *extra_state,
40 void *attribute_val_in, void *attribute_val_out, int *flag)
42 /* Note that if (sizeof(int) < sizeof(void *), just setting the int
43 * part of attribute_val_out may leave some dirty bits
45 *(MPI_Aint *) attribute_val_out = (MPI_Aint) attribute_val_in;
50 int delete_fn(MPI_Comm comm, int keyval, void *attribute_val, void *extra_state)
53 MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
54 if ((MPI_Aint) attribute_val != (MPI_Aint) world_rank) {
55 printf("incorrect attribute value %d\n", *(int *) attribute_val);
56 MPI_Abort(MPI_COMM_WORLD, 1005);
61 int test_communicators(void)
63 MPI_Comm dup_comm_world, lo_comm, rev_comm, dup_comm, split_comm, world_comm;
64 MPI_Group world_group, lo_group, rev_group;
67 int flag, world_rank, world_size, rank, size, n, key_1, key_3;
68 int color, key, result;
72 MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
73 MPI_Comm_size(MPI_COMM_WORLD, &world_size);
75 if (world_rank == 0) {
76 printf("*** Communicators ***\n");
81 MPI_Comm_dup(MPI_COMM_WORLD, &dup_comm_world);
84 * Exercise Comm_create by creating an equivalent to dup_comm_world
85 * (sans attributes) and a half-world communicator.
89 if (world_rank == 0) {
90 printf(" Comm_create\n");
95 MPI_Comm_group(dup_comm_world, &world_group);
96 MPI_Comm_create(dup_comm_world, world_group, &world_comm);
97 MPI_Comm_rank(world_comm, &rank);
98 if (rank != world_rank) {
100 printf("incorrect rank in world comm: %d\n", rank);
101 MPI_Abort(MPI_COMM_WORLD, 3001);
107 ranges[0][1] = (world_size - n) - 1;
111 printf("world rank = %d before range incl\n", world_rank);
114 MPI_Group_range_incl(world_group, 1, ranges, &lo_group);
116 printf("world rank = %d after range incl\n", world_rank);
119 MPI_Comm_create(world_comm, lo_group, &lo_comm);
121 printf("world rank = %d before group free\n", world_rank);
124 MPI_Group_free(&lo_group);
127 printf("world rank = %d after group free\n", world_rank);
131 if (world_rank < (world_size - n)) {
132 MPI_Comm_rank(lo_comm, &rank);
133 if (rank == MPI_UNDEFINED) {
135 printf("incorrect lo group rank: %d\n", rank);
137 MPI_Abort(MPI_COMM_WORLD, 3002);
140 /* printf("lo in\n");FFLUSH; */
141 MPI_Barrier(lo_comm);
142 /* printf("lo out\n");FFLUSH; */
146 if (lo_comm != MPI_COMM_NULL) {
148 printf("incorrect lo comm:\n");
150 MPI_Abort(MPI_COMM_WORLD, 3003);
155 printf("worldrank = %d\n", world_rank);
158 MPI_Barrier(world_comm);
165 * Check Comm_dup by adding attributes to lo_comm & duplicating
168 if (world_rank == 0) {
169 printf(" Comm_dup\n");
174 if (lo_comm != MPI_COMM_NULL) {
176 MPI_Keyval_create(copy_fn, delete_fn, &key_1, &value);
179 MPI_Keyval_create(MPI_NULL_COPY_FN, MPI_NULL_DELETE_FN, &key_3, &value);
181 /* This may generate a compilation warning; it is, however, an
182 * easy way to cache a value instead of a pointer */
183 /* printf("key1 = %x key3 = %x\n", key_1, key_3); */
184 MPI_Attr_put(lo_comm, key_1, (void *) (MPI_Aint) world_rank);
185 MPI_Attr_put(lo_comm, key_3, (void *) 0);
187 MPI_Comm_dup(lo_comm, &dup_comm);
189 /* Note that if sizeof(int) < sizeof(void *), we can't use
190 * (void **)&value to get the value we passed into Attr_put. To avoid
191 * problems (e.g., alignment errors), we recover the value into
192 * a (void *) and cast to int. Note that this may generate warning
193 * messages from the compiler. */
194 MPI_Attr_get(dup_comm, key_1, (void **) &vvalue, &flag);
195 value = (MPI_Aint) vvalue;
199 printf("dup_comm key_1 not found on %d\n", world_rank);
201 MPI_Abort(MPI_COMM_WORLD, 3004);
204 if (value != world_rank) {
206 printf("dup_comm key_1 value incorrect: %ld, expected %d\n", (long) value, world_rank);
208 MPI_Abort(MPI_COMM_WORLD, 3005);
211 MPI_Attr_get(dup_comm, key_3, (void **) &vvalue, &flag);
212 value = (MPI_Aint) vvalue;
215 printf("dup_comm key_3 found!\n");
217 MPI_Abort(MPI_COMM_WORLD, 3008);
219 MPI_Keyval_free(&key_1);
220 MPI_Keyval_free(&key_3);
223 * Split the world into even & odd communicators with reversed ranks.
226 if (world_rank == 0) {
227 printf(" Comm_split\n");
232 color = world_rank % 2;
233 key = world_size - world_rank;
235 MPI_Comm_split(dup_comm_world, color, key, &split_comm);
236 MPI_Comm_size(split_comm, &size);
237 MPI_Comm_rank(split_comm, &rank);
238 if (rank != ((size - world_rank / 2) - 1)) {
240 printf("incorrect split rank: %d\n", rank);
242 MPI_Abort(MPI_COMM_WORLD, 3009);
245 MPI_Barrier(split_comm);
247 * Test each possible Comm_compare result
250 if (world_rank == 0) {
251 printf(" Comm_compare\n");
256 MPI_Comm_compare(world_comm, world_comm, &result);
257 if (result != MPI_IDENT) {
259 printf("incorrect ident result: %d\n", result);
260 MPI_Abort(MPI_COMM_WORLD, 3010);
263 if (lo_comm != MPI_COMM_NULL) {
264 MPI_Comm_compare(lo_comm, dup_comm, &result);
265 if (result != MPI_CONGRUENT) {
267 printf("incorrect congruent result: %d\n", result);
268 MPI_Abort(MPI_COMM_WORLD, 3011);
272 ranges[0][0] = world_size - 1;
276 MPI_Group_range_incl(world_group, 1, ranges, &rev_group);
277 MPI_Comm_create(world_comm, rev_group, &rev_comm);
279 MPI_Comm_compare(world_comm, rev_comm, &result);
280 if (result != MPI_SIMILAR && world_size != 1) {
282 printf("incorrect similar result: %d\n", result);
283 MPI_Abort(MPI_COMM_WORLD, 3012);
286 if (lo_comm != MPI_COMM_NULL) {
287 MPI_Comm_compare(world_comm, lo_comm, &result);
288 if (result != MPI_UNEQUAL && world_size != 1) {
290 printf("incorrect unequal result: %d\n", result);
291 MPI_Abort(MPI_COMM_WORLD, 3013);
295 * Free all communicators created
299 printf(" Comm_free\n");
302 MPI_Comm_free(&world_comm);
303 MPI_Comm_free(&dup_comm_world);
305 MPI_Comm_free(&rev_comm);
306 MPI_Comm_free(&split_comm);
308 MPI_Group_free(&world_group);
309 MPI_Group_free(&rev_group);
311 if (lo_comm != MPI_COMM_NULL) {
312 MPI_Comm_free(&lo_comm);
313 MPI_Comm_free(&dup_comm);