Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Add mpich3 test suite, to replace older one.
[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, 
51                void *extra_state)
52 {
53     int world_rank;
54     MPI_Comm_rank( MPI_COMM_WORLD, &world_rank );
55     if ((MPI_Aint)attribute_val != (MPI_Aint)world_rank) {
56         printf( "incorrect attribute value %d\n", *(int*)attribute_val );
57         MPI_Abort(MPI_COMM_WORLD, 1005 );
58     }
59     return MPI_SUCCESS;
60 }
61
62 int test_communicators( void )
63 {
64     MPI_Comm dup_comm_world, lo_comm, rev_comm, dup_comm, 
65         split_comm, world_comm;
66     MPI_Group world_group, lo_group, rev_group;
67     void *vvalue;
68     int ranges[1][3];
69     int flag, world_rank, world_size, rank, size, n, key_1, key_3;
70     int color, key, result;
71     int errs = 0;
72     MPI_Aint value;
73
74     MPI_Comm_rank( MPI_COMM_WORLD, &world_rank );
75     MPI_Comm_size( MPI_COMM_WORLD, &world_size );
76 #ifdef DEBUG
77     if (world_rank == 0) {
78         printf( "*** Communicators ***\n" ); fflush(stdout);
79     }
80 #endif
81
82     MPI_Comm_dup( MPI_COMM_WORLD, &dup_comm_world );
83
84     /*
85       Exercise Comm_create by creating an equivalent to dup_comm_world
86       (sans attributes) and a half-world communicator.
87     */
88
89 #ifdef DEBUG
90     if (world_rank == 0) {
91         printf( "    Comm_create\n" ); 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 );FFLUSH;
112 #endif
113     MPI_Group_range_incl(world_group, 1, ranges, &lo_group );
114 #ifdef DEBUG
115     printf( "world rank = %d after range incl\n", world_rank );FFLUSH;
116 #endif
117     MPI_Comm_create(world_comm, lo_group, &lo_comm );
118 #ifdef DEBUG
119     printf( "world rank = %d before group free\n", world_rank );FFLUSH;
120 #endif
121     MPI_Group_free( &lo_group );
122
123 #ifdef DEBUG
124     printf( "world rank = %d after group free\n", world_rank );FFLUSH;
125 #endif
126
127     if (world_rank < (world_size - n)) {
128         MPI_Comm_rank(lo_comm, &rank );
129         if (rank == MPI_UNDEFINED) {
130             errs++;
131             printf( "incorrect lo group rank: %d\n", rank ); fflush(stdout);
132             MPI_Abort(MPI_COMM_WORLD, 3002 );
133         }
134         else {
135             /* printf( "lo in\n" );FFLUSH; */
136             MPI_Barrier(lo_comm );
137             /* printf( "lo out\n" );FFLUSH; */
138         }
139     }
140     else {
141         if (lo_comm != MPI_COMM_NULL) {
142             errs++;
143             printf( "rank : %d incorrect lo comm:\n", rank ); fflush(stdout);
144             MPI_Abort(MPI_COMM_WORLD, 3003 );
145         }
146     }
147
148 #ifdef DEBUG
149     printf( "worldrank = %d\n", world_rank );FFLUSH;
150 #endif
151     MPI_Barrier(world_comm);
152
153 #ifdef DEBUG
154     printf( "bar!\n" );FFLUSH;
155 #endif
156     /*
157       Check Comm_dup by adding attributes to lo_comm & duplicating
158     */
159 #ifdef DEBUG
160     if (world_rank == 0) {
161         printf( "    Comm_dup\n" );
162         fflush(stdout);
163     }
164 #endif
165     
166     if (lo_comm != MPI_COMM_NULL) {
167         value = 9;
168         MPI_Keyval_create(copy_fn,     delete_fn,   &key_1, &value );
169         value = 8;
170         value = 7;
171         MPI_Keyval_create(MPI_NULL_COPY_FN, MPI_NULL_DELETE_FN,
172                           &key_3, &value ); 
173
174         /* This may generate a compilation warning; it is, however, an
175            easy way to cache a value instead of a pointer */
176         /* printf( "key1 = %x key3 = %x\n", key_1, key_3 ); */
177         MPI_Attr_put(lo_comm, key_1, (void *) (MPI_Aint) world_rank );
178         MPI_Attr_put(lo_comm, key_3, (void *)0 );
179         
180         MPI_Comm_dup(lo_comm, &dup_comm );
181
182         /* Note that if sizeof(int) < sizeof(void *), we can't use
183            (void **)&value to get the value we passed into Attr_put.  To avoid 
184            problems (e.g., alignment errors), we recover the value into 
185            a (void *) and cast to int. Note that this may generate warning
186            messages from the compiler.  */
187         MPI_Attr_get(dup_comm, key_1, (void **)&vvalue, &flag );
188         value = (MPI_Aint)vvalue;
189         
190         if (! flag) {
191             errs++;
192             printf( "dup_comm key_1 not found on %d\n", world_rank );
193             fflush( stdout );
194             MPI_Abort(MPI_COMM_WORLD, 3004 );
195         }
196         
197         if (value != world_rank) {
198             errs++;
199             printf( "dup_comm key_1 value incorrect: %ld, expected %d\n", 
200                     (long)value, world_rank );
201             fflush( stdout );
202             MPI_Abort(MPI_COMM_WORLD, 3005 );
203         }
204
205         MPI_Attr_get(dup_comm, key_3, (void **)&vvalue, &flag );
206         value = (MPI_Aint)vvalue;
207         if (flag) {
208             errs++;
209             printf( "dup_comm key_3 found!\n" );
210             fflush( stdout );
211             MPI_Abort(MPI_COMM_WORLD, 3008 );
212         }
213         MPI_Keyval_free(&key_1 );
214         MPI_Keyval_free(&key_3 );
215     }
216     /* 
217        Split the world into even & odd communicators with reversed ranks.
218     */
219 #ifdef DEBUG
220     if (world_rank == 0) {
221         printf( "    Comm_split\n" );
222         fflush(stdout);
223     }
224 #endif
225     
226     color = world_rank % 2;
227     key   = world_size - world_rank;
228     
229     MPI_Comm_split(dup_comm_world, color, key, &split_comm );
230     MPI_Comm_size(split_comm, &size );
231     MPI_Comm_rank(split_comm, &rank );
232     if (rank != ((size - world_rank/2) - 1)) {
233         errs++;
234         printf( "incorrect split rank: %d\n", rank ); fflush(stdout);
235         MPI_Abort(MPI_COMM_WORLD, 3009 );
236     }
237     
238     MPI_Barrier(split_comm );
239     /*
240       Test each possible Comm_compare result
241     */
242 #ifdef DEBUG
243     if (world_rank == 0) {
244         printf( "    Comm_compare\n" );
245         fflush(stdout);
246     }
247 #endif
248     
249     MPI_Comm_compare(world_comm, world_comm, &result );
250     if (result != MPI_IDENT) {
251         errs++;
252         printf( "incorrect ident result: %d\n", result );
253         MPI_Abort(MPI_COMM_WORLD, 3010 );
254     }
255     
256     if (lo_comm != MPI_COMM_NULL) {
257         MPI_Comm_compare(lo_comm, dup_comm, &result );
258         if (result != MPI_CONGRUENT) {
259             errs++;
260             printf( "incorrect congruent result: %d\n", result );
261             MPI_Abort(MPI_COMM_WORLD, 3011 );
262         }
263     }
264     
265     ranges[0][0] = world_size - 1;
266     ranges[0][1] = 0;
267     ranges[0][2] = -1;
268
269     MPI_Group_range_incl(world_group, 1, ranges, &rev_group );
270     MPI_Comm_create(world_comm, rev_group, &rev_comm );
271
272     MPI_Comm_compare(world_comm, rev_comm, &result );
273     if (result != MPI_SIMILAR && world_size != 1) {
274         errs++;
275         printf( "incorrect similar result: %d\n", result );
276         MPI_Abort(MPI_COMM_WORLD, 3012 );
277     }
278     
279     if (lo_comm != MPI_COMM_NULL) {
280         MPI_Comm_compare(world_comm, lo_comm, &result );
281         if (result != MPI_UNEQUAL && world_size != 1) {
282             errs++;
283             printf( "incorrect unequal result: %d\n", result );
284             MPI_Abort(MPI_COMM_WORLD, 3013 );
285         }
286     }
287     /*
288       Free all communicators created
289     */
290 #ifdef DEBUG
291     if (world_rank == 0) 
292         printf( "    Comm_free\n" );
293 #endif
294     
295     MPI_Comm_free( &world_comm );
296     MPI_Comm_free( &dup_comm_world );
297     
298     MPI_Comm_free( &rev_comm );
299     MPI_Comm_free( &split_comm );
300     
301     MPI_Group_free( &world_group );
302     MPI_Group_free( &rev_group );
303     
304     if (lo_comm != MPI_COMM_NULL) {
305         MPI_Comm_free( &lo_comm );
306         MPI_Comm_free( &dup_comm );
307     }
308     
309     return errs;
310 }
311