Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Add new entry in Release_Notes.
[simgrid.git] / teshsuite / smpi / mpich3-test / attr / attrt.c
1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
2 /*
3  *
4  *  (C) 2001 by Argonne National Laboratory.
5  *      See COPYRIGHT in top-level directory.
6  */
7 /*
8
9   Exercise communicator routines.
10
11   This C version derived from a Fortran test program from ....
12
13  */
14 #include <stdio.h>
15 #include "mpi.h"
16 #include "mpitest.h"
17
18 /* #define DEBUG */
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 *);
22 #ifdef DEBUG
23 #define FFLUSH fflush(stdout);
24 #else
25 #define FFLUSH
26 #endif
27
28 int main(int argc, char **argv)
29 {
30     int errs = 0;
31     MTest_Init(&argc, &argv);
32
33     errs = test_communicators();
34     MTest_Finalize(errs);
35     MPI_Finalize();
36     return 0;
37 }
38
39 int copy_fn(MPI_Comm oldcomm, int keyval, void *extra_state,
40             void *attribute_val_in, void *attribute_val_out, int *flag)
41 {
42     /* Note that if (sizeof(int) < sizeof(void *), just setting the int
43      * part of attribute_val_out may leave some dirty bits
44      */
45     *(MPI_Aint *) attribute_val_out = (MPI_Aint) attribute_val_in;
46     *flag = 1;
47     return MPI_SUCCESS;
48 }
49
50 int delete_fn(MPI_Comm comm, int keyval, void *attribute_val, void *extra_state)
51 {
52     int world_rank;
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);
57     }
58     return MPI_SUCCESS;
59 }
60
61 int test_communicators(void)
62 {
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;
65     void *vvalue;
66     int ranges[1][3];
67     int flag, world_rank, world_size, rank, size, n, key_1, key_3;
68     int color, key, result;
69     int errs = 0;
70     MPI_Aint value;
71
72     MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
73     MPI_Comm_size(MPI_COMM_WORLD, &world_size);
74 #ifdef DEBUG
75     if (world_rank == 0) {
76         printf("*** Communicators ***\n");
77         fflush(stdout);
78     }
79 #endif
80
81     MPI_Comm_dup(MPI_COMM_WORLD, &dup_comm_world);
82
83     /*
84      * Exercise Comm_create by creating an equivalent to dup_comm_world
85      * (sans attributes) and a half-world communicator.
86      */
87
88 #ifdef DEBUG
89     if (world_rank == 0) {
90         printf("    Comm_create\n");
91         fflush(stdout);
92     }
93 #endif
94
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) {
99         errs++;
100         printf("incorrect rank in world comm: %d\n", rank);
101         MPI_Abort(MPI_COMM_WORLD, 3001);
102     }
103
104     n = world_size / 2;
105
106     ranges[0][0] = 0;
107     ranges[0][1] = (world_size - n) - 1;
108     ranges[0][2] = 1;
109
110 #ifdef DEBUG
111     printf("world rank = %d before range incl\n", world_rank);
112     FFLUSH;
113 #endif
114     MPI_Group_range_incl(world_group, 1, ranges, &lo_group);
115 #ifdef DEBUG
116     printf("world rank = %d after range incl\n", world_rank);
117     FFLUSH;
118 #endif
119     MPI_Comm_create(world_comm, lo_group, &lo_comm);
120 #ifdef DEBUG
121     printf("world rank = %d before group free\n", world_rank);
122     FFLUSH;
123 #endif
124     MPI_Group_free(&lo_group);
125
126 #ifdef DEBUG
127     printf("world rank = %d after group free\n", world_rank);
128     FFLUSH;
129 #endif
130
131     if (world_rank < (world_size - n)) {
132         MPI_Comm_rank(lo_comm, &rank);
133         if (rank == MPI_UNDEFINED) {
134             errs++;
135             printf("incorrect lo group rank: %d\n", rank);
136             fflush(stdout);
137             MPI_Abort(MPI_COMM_WORLD, 3002);
138         }
139         else {
140             /* printf("lo in\n");FFLUSH; */
141             MPI_Barrier(lo_comm);
142             /* printf("lo out\n");FFLUSH; */
143         }
144     }
145     else {
146         if (lo_comm != MPI_COMM_NULL) {
147             errs++;
148             printf("incorrect lo comm:\n");
149             fflush(stdout);
150             MPI_Abort(MPI_COMM_WORLD, 3003);
151         }
152     }
153
154 #ifdef DEBUG
155     printf("worldrank = %d\n", world_rank);
156     FFLUSH;
157 #endif
158     MPI_Barrier(world_comm);
159
160 #ifdef DEBUG
161     printf("bar!\n");
162     FFLUSH;
163 #endif
164     /*
165      * Check Comm_dup by adding attributes to lo_comm & duplicating
166      */
167 #ifdef DEBUG
168     if (world_rank == 0) {
169         printf("    Comm_dup\n");
170         fflush(stdout);
171     }
172 #endif
173
174     if (lo_comm != MPI_COMM_NULL) {
175         value = 9;
176         MPI_Keyval_create(copy_fn, delete_fn, &key_1, &value);
177         value = 8;
178         value = 7;
179         MPI_Keyval_create(MPI_NULL_COPY_FN, MPI_NULL_DELETE_FN, &key_3, &value);
180
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);
186
187         MPI_Comm_dup(lo_comm, &dup_comm);
188
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;
196
197         if (!flag) {
198             errs++;
199             printf("dup_comm key_1 not found on %d\n", world_rank);
200             fflush(stdout);
201             MPI_Abort(MPI_COMM_WORLD, 3004);
202         }
203
204         if (value != world_rank) {
205             errs++;
206             printf("dup_comm key_1 value incorrect: %ld, expected %d\n", (long) value, world_rank);
207             fflush(stdout);
208             MPI_Abort(MPI_COMM_WORLD, 3005);
209         }
210
211         MPI_Attr_get(dup_comm, key_3, (void **) &vvalue, &flag);
212         value = (MPI_Aint) vvalue;
213         if (flag) {
214             errs++;
215             printf("dup_comm key_3 found!\n");
216             fflush(stdout);
217             MPI_Abort(MPI_COMM_WORLD, 3008);
218         }
219         MPI_Keyval_free(&key_1);
220         MPI_Keyval_free(&key_3);
221     }
222     /*
223      * Split the world into even & odd communicators with reversed ranks.
224      */
225 #ifdef DEBUG
226     if (world_rank == 0) {
227         printf("    Comm_split\n");
228         fflush(stdout);
229     }
230 #endif
231
232     color = world_rank % 2;
233     key = world_size - world_rank;
234
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)) {
239         errs++;
240         printf("incorrect split rank: %d\n", rank);
241         fflush(stdout);
242         MPI_Abort(MPI_COMM_WORLD, 3009);
243     }
244
245     MPI_Barrier(split_comm);
246     /*
247      * Test each possible Comm_compare result
248      */
249 #ifdef DEBUG
250     if (world_rank == 0) {
251         printf("    Comm_compare\n");
252         fflush(stdout);
253     }
254 #endif
255
256     MPI_Comm_compare(world_comm, world_comm, &result);
257     if (result != MPI_IDENT) {
258         errs++;
259         printf("incorrect ident result: %d\n", result);
260         MPI_Abort(MPI_COMM_WORLD, 3010);
261     }
262
263     if (lo_comm != MPI_COMM_NULL) {
264         MPI_Comm_compare(lo_comm, dup_comm, &result);
265         if (result != MPI_CONGRUENT) {
266             errs++;
267             printf("incorrect congruent result: %d\n", result);
268             MPI_Abort(MPI_COMM_WORLD, 3011);
269         }
270     }
271
272     ranges[0][0] = world_size - 1;
273     ranges[0][1] = 0;
274     ranges[0][2] = -1;
275
276     MPI_Group_range_incl(world_group, 1, ranges, &rev_group);
277     MPI_Comm_create(world_comm, rev_group, &rev_comm);
278
279     MPI_Comm_compare(world_comm, rev_comm, &result);
280     if (result != MPI_SIMILAR && world_size != 1) {
281         errs++;
282         printf("incorrect similar result: %d\n", result);
283         MPI_Abort(MPI_COMM_WORLD, 3012);
284     }
285
286     if (lo_comm != MPI_COMM_NULL) {
287         MPI_Comm_compare(world_comm, lo_comm, &result);
288         if (result != MPI_UNEQUAL && world_size != 1) {
289             errs++;
290             printf("incorrect unequal result: %d\n", result);
291             MPI_Abort(MPI_COMM_WORLD, 3013);
292         }
293     }
294     /*
295      * Free all communicators created
296      */
297 #ifdef DEBUG
298     if (world_rank == 0)
299         printf("    Comm_free\n");
300 #endif
301
302     MPI_Comm_free(&world_comm);
303     MPI_Comm_free(&dup_comm_world);
304
305     MPI_Comm_free(&rev_comm);
306     MPI_Comm_free(&split_comm);
307
308     MPI_Group_free(&world_group);
309     MPI_Group_free(&rev_group);
310
311     if (lo_comm != MPI_COMM_NULL) {
312         MPI_Comm_free(&lo_comm);
313         MPI_Comm_free(&dup_comm);
314     }
315
316     return errs;
317 }