Logo AND Algorithmique Numérique Distribuée

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