Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
first commit to add the mpich-test suite to smpi tesh suite. Obviously all tests...
[simgrid.git] / teshsuite / smpi / mpich-test / context / ictest3.c
1 /* ictest3.c 
2    This is like ictest2.c, but it creates communictors that are valid only
3    at the "leaders"; other members of the local communicator are NOT
4    in the remote communicator.  A peer communicator is constructed that
5    contains both leaders.
6
7    
8  */
9 #include "mpi.h"
10 #include <stdio.h>
11 #include "test.h"
12
13 /* #define DEBUG */
14
15 int verbose = 0;
16
17 int main( int argc, char **argv )
18 {
19   int size, rank, key, lrank, rsize, result;
20   MPI_Comm myFirstComm;
21   MPI_Comm mySecondComm;
22   MPI_Comm newComm, peerComm;
23   MPI_Group rgroup, lgroup, igroup;
24   int errors = 0, sum_errors;
25   int flag;
26   MPI_Status status;
27   
28   /* Initialization */
29   MPI_Init ( &argc, &argv );
30   MPI_Comm_rank ( MPI_COMM_WORLD, &rank);
31   MPI_Comm_size ( MPI_COMM_WORLD, &size);
32
33   /* Only works for 2 or more processes */
34   /* 
35      We create an even and odd communicator, then create an
36      intercommunicator out of them.  For this purpose, we use a 
37      "peer" communicator valid only at one member of each of the odd and
38      even communicators.
39    */
40   if (size >= 2) {
41     MPI_Comm merge1, merge2, merge3, merge4;
42
43     /* Generate membership key in the range [0,1] */
44     key = rank % 2;
45     /* Create the even communicator and odd communicators */
46     MPI_Comm_split ( MPI_COMM_WORLD, key, rank, &newComm );
47
48     MPI_Comm_test_inter( newComm, &flag );
49     if (flag) {
50         errors++;
51         printf( "[%d] got test_inter gave true for intra comm\n", rank );
52         }
53
54     /* Create the "peer" communicator */
55     key = 0;
56     if (rank < 2) key = 1;
57     MPI_Comm_split( MPI_COMM_WORLD, key, rank, &peerComm );
58     if (key == 0) {
59         MPI_Comm_free( &peerComm );
60         }
61 #ifdef DEBUG
62     else {
63         MPI_Comm_rank( peerComm, &lrank );
64         printf( "[%d] lrank in peerComm is %d (color = %d, key=%d)\n", 
65                 rank, lrank, key, rank );
66         }
67 #endif
68
69     /* Check that the leader is who we think he is */
70     MPI_Comm_rank( newComm, &lrank );
71     /* printf( "[%d] local rank is %d\n", rank, lrank );
72     fflush(stdout); */
73     /* Perform the intercomm create and test it */
74     /* Local leader is always the one at rank 0.  */
75     /* If even, the remote leader is rank 1, if odd, the remote leader
76        is rank 0 in the peercomm */
77     MPI_Intercomm_create (newComm, 0, peerComm, !(rank % 2), 1, &myFirstComm );
78 #ifdef DEBUG
79     printf( "[%d] through intercom create\n", rank );
80     fflush( stdout );
81     MPI_Barrier( MPI_COMM_WORLD );
82     printf( "[%d] through barrier at end of intercom create\n", rank );
83 #endif
84     MPI_Comm_test_inter( myFirstComm, &flag );
85     if (!flag) {
86         errors++;
87         printf( "[%d] got test_inter gave false for inter comm\n", rank );
88         }
89
90     /* Try to dup this communicator */
91     MPI_Comm_dup ( myFirstComm, &mySecondComm );
92     MPI_Comm_test_inter( mySecondComm, &flag );
93     if (!flag) {
94         errors++;
95         printf( "[%d] got test_inter gave false for dup of inter comm\n", 
96                 rank );
97         }
98
99 #ifdef DEBUG
100     printf( "[%d] through comm dup\n", rank );
101     fflush( stdout );
102     MPI_Barrier( MPI_COMM_WORLD );
103     printf( "[%d] through barrier at end of comm dup\n", rank );
104 #endif
105
106     /* Each member shares data with his "partner".  */
107     MPI_Comm_rank( mySecondComm, &lrank );
108     MPI_Comm_remote_size( mySecondComm, &rsize );
109
110 #ifdef DEBUG
111     printf( "[%d] lrank in secondcomm is %d and remote size is %d\n", 
112            rank, lrank, rsize );
113     fflush( stdout ); 
114 #endif
115
116     /* Check that the remote group is what we think */
117     MPI_Comm_remote_group( mySecondComm, &rgroup );
118     MPI_Comm_group( newComm, &lgroup );
119     MPI_Group_intersection( rgroup, lgroup, &igroup );
120     MPI_Group_compare( igroup, MPI_GROUP_EMPTY, &flag );
121     if (flag != MPI_IDENT) {
122         errors++;
123         printf( "[%d] intersection of remote and local group is not empty\n",
124                 rank );
125         }
126     MPI_Group_free( &rgroup );
127     MPI_Group_free( &lgroup );
128     MPI_Group_free( &igroup );
129
130     /* Send key * size + rank in communicator */
131     if (lrank < rsize) {
132       int myval, hisval;
133       key = rank % 2;
134       myval   = key * size + lrank;
135       hisval  = -1;
136 #ifdef DEBUG
137       printf( "[%d] exchanging %d with %d in intercomm\n", 
138              rank, myval, lrank );
139       fflush( stdout );
140 #endif
141       MPI_Sendrecv (&myval,  1, MPI_INT, lrank, 0, 
142                     &hisval, 1, MPI_INT, lrank, 0, mySecondComm, &status);
143       if (hisval != (lrank + (!key)*size)) {
144           printf( "[%d] expected %d but got %d\n", rank, lrank + (!key)*size,
145                   hisval );
146           errors++;
147           }
148       }
149     
150     if (errors)
151       printf("[%d] Failed!\n",rank);
152
153     /* Key is 1 for oddComm, 0 for evenComm (note both contain 0 in WORLD) */
154 #ifdef DEBUG
155     printf( "[%d] starting intercom merge\n", rank );
156     fflush( stdout );
157 #endif
158     MPI_Intercomm_merge ( mySecondComm, key, &merge1 );
159     MPI_Intercomm_merge ( mySecondComm, (key+1)%2, &merge2 );
160     MPI_Intercomm_merge ( mySecondComm, 0, &merge3 );
161     MPI_Intercomm_merge ( mySecondComm, 1, &merge4 );
162
163     MPI_Comm_compare( merge1, MPI_COMM_WORLD, &result );
164     if (result != MPI_SIMILAR && size > 2) {
165         printf( "[%d] comparision with merge1 failed\n", rank );
166         errors++;
167         }
168
169     /* Free communicators */
170     if (verbose) printf( "about to free communicators\n" );
171     MPI_Comm_free( &newComm );
172     if (peerComm != MPI_COMM_NULL) MPI_Comm_free( &peerComm );
173     MPI_Comm_free( &myFirstComm );
174     MPI_Comm_free( &mySecondComm );
175     MPI_Comm_free( &merge1 );
176     MPI_Comm_free( &merge2 );
177     MPI_Comm_free( &merge3 );
178     MPI_Comm_free( &merge4 );
179   }
180   else 
181     printf("[%d] Failed - at least 2 nodes must be used\n",rank);
182
183   MPI_Barrier( MPI_COMM_WORLD );
184   MPI_Allreduce( &errors, &sum_errors, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD );
185   if (sum_errors > 0) {
186       printf( "%d errors on process %d\n", errors, rank );
187       }
188   else if (rank == 0) {
189       printf( " No Errors\n" );
190       }
191   /* Finalize and end! */
192
193   MPI_Finalize();
194   return 0;
195 }