Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge branch 'v3_8_x'
[simgrid.git] / teshsuite / smpi / mpich-test / context / attrt.c
1 /*
2
3   Exercise communicator routines.
4
5   This C version derived from a Fortran test program from ....
6
7  */
8 #include <stdio.h>
9 #include "mpi.h"
10 #include "test.h"
11
12 int test_communicators ( void );
13 int copy_fn ( MPI_Comm, int, void *, void *, void *, int * );
14 int delete_fn ( MPI_Comm, int, void *, void * );
15
16 int main( int argc, char **argv )
17 {
18     MPI_Init( &argc, &argv );
19     test_communicators();
20     Test_Waitforall( );
21     MPI_Finalize();
22     return 0;
23 }
24
25 int copy_fn( MPI_Comm oldcomm, int keyval, void *extra_state,
26              void *attribute_val_in, void *attribute_val_out, 
27              int *flag)
28 {
29 /* Note that if (sizeof(int) < sizeof(void *), just setting the int
30    part of attribute_val_out may leave some dirty bits
31  */
32 *(MPI_Aint *)attribute_val_out = (MPI_Aint)attribute_val_in;
33 *flag = 1;
34 return MPI_SUCCESS;
35 }
36
37 int delete_fn( MPI_Comm comm, int keyval, void *attribute_val, 
38                void *extra_state)
39 {
40 int world_rank;
41 MPI_Comm_rank( MPI_COMM_WORLD, &world_rank );
42 if ((MPI_Aint)attribute_val != (MPI_Aint)world_rank) {
43     printf( "incorrect attribute value %d\n", *(int*)attribute_val );
44     MPI_Abort(MPI_COMM_WORLD, 1005 );
45     }
46 return MPI_SUCCESS;
47 }
48
49 int test_communicators( void )
50 {
51 MPI_Comm dup_comm_world, lo_comm, rev_comm, dup_comm, split_comm, world_comm;
52 MPI_Group world_group, lo_group, rev_group;
53 void *vvalue;
54 int ranges[1][3];
55 int flag, world_rank, world_size, rank, size, n, key_1, key_3;
56 int color, key, result;
57 /*      integer n, ,
58      .        key_2
59
60   */
61 MPI_Aint value;
62
63 MPI_Comm_rank( MPI_COMM_WORLD, &world_rank );
64 MPI_Comm_size( MPI_COMM_WORLD, &world_size );
65 if (world_rank == 0) {
66     printf( "*** Communicators ***\n" );
67     }
68
69 MPI_Comm_dup( MPI_COMM_WORLD, &dup_comm_world );
70
71 /*
72      Exercise Comm_create by creating an equivalent to dup_comm_world
73      (sans attributes) and a half-world communicator.
74  */
75
76 if (world_rank == 0) 
77     printf( "    Comm_create\n" );
78
79 MPI_Comm_group( dup_comm_world, &world_group );
80 MPI_Comm_create( dup_comm_world, world_group, &world_comm );
81 MPI_Comm_rank( world_comm, &rank );
82 if (rank != world_rank) {
83     printf( "incorrect rank in world comm: %d\n", rank );
84     MPI_Abort(MPI_COMM_WORLD, 3001 );
85     }
86
87 n = world_size / 2;
88
89 ranges[0][0] = 0;
90 ranges[0][1] = (world_size - n) - 1;
91 ranges[0][2] = 1;
92
93 MPI_Group_range_incl(world_group, 1, ranges, &lo_group );
94 MPI_Comm_create(world_comm, lo_group, &lo_comm );
95 MPI_Group_free( &lo_group );
96
97 if (world_rank < (world_size - n)) {
98     MPI_Comm_rank(lo_comm, &rank );
99     if (rank == MPI_UNDEFINED) {
100         printf( "incorrect lo group rank: %d\n", rank );
101         MPI_Abort(MPI_COMM_WORLD, 3002 );
102         }
103     else {
104         MPI_Barrier(lo_comm );
105         }
106     }
107 else {
108     if (lo_comm != MPI_COMM_NULL) {
109         printf( "incorrect lo comm:\n" );
110         MPI_Abort(MPI_COMM_WORLD, 3003 );
111         }
112     }
113       
114 MPI_Barrier(world_comm);
115 /*
116      Check Comm_dup by adding attributes to lo_comm & duplicating
117  */
118 if (world_rank == 0) 
119     printf( "    Comm_dup\n" );
120
121 if (lo_comm != MPI_COMM_NULL) {
122     value = 9;
123     MPI_Keyval_create(copy_fn,     delete_fn,   &key_1, &value );
124     value = 8;
125 /*     MPI_Keyval_create(MPI_DUP_FN,  MPI_NULL_DELETE_FN,
126                               &key_2, &value );  */
127     value = 7;
128     MPI_Keyval_create(MPI_NULL_COPY_FN, MPI_NULL_DELETE_FN,
129                                &key_3, &value ); 
130
131     /* This may generate a compilation warning; it is, however, an
132        easy way to cache a value instead of a pointer */
133     MPI_Attr_put(lo_comm, key_1, (void *)world_rank );
134 /*         MPI_Attr_put(lo_comm, key_2, world_size ) */
135     MPI_Attr_put(lo_comm, key_3, (void *)0 );
136
137     MPI_Comm_dup(lo_comm, &dup_comm );
138
139     /* Note that if sizeof(int) < sizeof(void *), we can't use
140        (void **)&value to get the value we passed into Attr_put.  To avoid 
141        problems (e.g., alignment errors), we recover the value into 
142        a (void *) and cast to int. Note that this may generate warning
143        messages from the compiler.  */
144     MPI_Attr_get(dup_comm, key_1, (void **)&vvalue, &flag );
145     value = (MPI_Aint)vvalue;
146
147     if (! flag) {
148         printf( "dup_comm key_1 not found on %d\n", world_rank );
149         MPI_Abort(MPI_COMM_WORLD, 3004 );
150         }
151
152     if (value != world_rank) {
153         printf( "dup_comm key_1 value incorrect: %ld\n", (long)value );
154         MPI_Abort(MPI_COMM_WORLD, 3005 );
155         }
156
157 /*         MPI_Attr_get(dup_comm, key_2, (int *)&value, &flag ); */
158 /*
159         if (! flag) {
160            printf( "dup_comm key_2 not found\n" );
161            MPI_Abort(MPI_COMM_WORLD, 3006 );
162            }
163
164        if (value != world_size) {
165            printf( "dup_comm key_2 value incorrect: %d\n", value );
166            MPI_Abort(MPI_COMM_WORLD, 3007 );
167            }
168  */
169     MPI_Attr_get(dup_comm, key_3, (void **)&vvalue, &flag );
170     value = (int)vvalue;
171     if (flag) {
172         printf( "dup_comm key_3 found!\n" );
173         MPI_Abort(MPI_COMM_WORLD, 3008 );
174         }
175     MPI_Keyval_free(&key_1 );
176 /* 
177 c        MPI_Keyval_free(&key_2 )
178  */
179     MPI_Keyval_free(&key_3 );
180     }
181 /* 
182      Split the world into even & odd communicators with reversed ranks.
183  */
184       if (world_rank == 0) 
185           printf( "    Comm_split\n" );
186
187       color = world_rank % 2;
188       key   = world_size - world_rank;
189
190       MPI_Comm_split(dup_comm_world, color, key, &split_comm );
191       MPI_Comm_size(split_comm, &size );
192       MPI_Comm_rank(split_comm, &rank );
193       if (rank != ((size - world_rank/2) - 1)) {
194           printf( "incorrect split rank: %d\n", rank );
195           MPI_Abort(MPI_COMM_WORLD, 3009 );
196           }
197
198       MPI_Barrier(split_comm );
199 /*
200      Test each possible Comm_compare result
201  */
202       if (world_rank == 0) 
203          printf( "    Comm_compare\n" );
204
205       MPI_Comm_compare(world_comm, world_comm, &result );
206       if (result != MPI_IDENT) {
207          printf( "incorrect ident result: %d\n", result );
208          MPI_Abort(MPI_COMM_WORLD, 3010 );
209          }
210
211       if (lo_comm != MPI_COMM_NULL) {
212          MPI_Comm_compare(lo_comm, dup_comm, &result );
213          if (result != MPI_CONGRUENT) {
214             printf( "incorrect congruent result: %d\n", result );
215             MPI_Abort(MPI_COMM_WORLD, 3011 );
216             }
217          }
218
219       ranges[0][0] = world_size - 1;
220       ranges[0][1] = 0;
221       ranges[0][2] = -1;
222
223       MPI_Group_range_incl(world_group, 1, ranges, &rev_group );
224       MPI_Comm_create(world_comm, rev_group, &rev_comm );
225       MPI_Comm_compare(world_comm, rev_comm, &result );
226       if (result != MPI_SIMILAR) {
227          printf( "incorrect similar result: %d\n", result );
228          MPI_Abort(MPI_COMM_WORLD, 3012 );
229          }
230
231       if (lo_comm != MPI_COMM_NULL) {
232           MPI_Comm_compare(world_comm, lo_comm, &result );
233           if (result != MPI_UNEQUAL) {
234               printf( "incorrect unequal result: %d\n", result );
235               MPI_Abort(MPI_COMM_WORLD, 3013 );
236               }
237           }
238 /*
239      Free all communicators created
240  */
241     if (world_rank == 0) 
242         printf( "    Comm_free\n" );
243
244      MPI_Comm_free( &world_comm );
245      MPI_Comm_free( &dup_comm_world );
246
247      MPI_Comm_free( &rev_comm );
248      MPI_Comm_free( &split_comm );
249
250      MPI_Group_free( &world_group );
251      MPI_Group_free( &rev_group );
252
253      if (lo_comm != MPI_COMM_NULL) {
254         MPI_Comm_free( &lo_comm );
255         MPI_Comm_free( &dup_comm );
256         }
257
258      return 0;
259 }
260