3 Exercise communicator routines.
5 This C version derived from a Fortran test program from ....
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 * );
16 int main( int argc, char **argv )
18 MPI_Init( &argc, &argv );
25 int copy_fn( MPI_Comm oldcomm, int keyval, void *extra_state,
26 void *attribute_val_in, void *attribute_val_out,
29 /* Note that if (sizeof(int) < sizeof(void *), just setting the int
30 part of attribute_val_out may leave some dirty bits
32 *(MPI_Aint *)attribute_val_out = (MPI_Aint)attribute_val_in;
37 int delete_fn( MPI_Comm comm, int keyval, void *attribute_val,
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 );
49 int test_communicators( void )
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;
55 int flag, world_rank, world_size, rank, size, n, key_1, key_3;
56 int color, key, result;
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" );
69 MPI_Comm_dup( MPI_COMM_WORLD, &dup_comm_world );
72 Exercise Comm_create by creating an equivalent to dup_comm_world
73 (sans attributes) and a half-world communicator.
77 printf( " Comm_create\n" );
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 );
90 ranges[0][1] = (world_size - n) - 1;
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 );
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 );
104 MPI_Barrier(lo_comm );
108 if (lo_comm != MPI_COMM_NULL) {
109 printf( "incorrect lo comm:\n" );
110 MPI_Abort(MPI_COMM_WORLD, 3003 );
114 MPI_Barrier(world_comm);
116 Check Comm_dup by adding attributes to lo_comm & duplicating
119 printf( " Comm_dup\n" );
121 if (lo_comm != MPI_COMM_NULL) {
123 MPI_Keyval_create(copy_fn, delete_fn, &key_1, &value );
125 /* MPI_Keyval_create(MPI_DUP_FN, MPI_NULL_DELETE_FN,
128 MPI_Keyval_create(MPI_NULL_COPY_FN, MPI_NULL_DELETE_FN,
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 );
137 MPI_Comm_dup(lo_comm, &dup_comm );
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;
148 printf( "dup_comm key_1 not found on %d\n", world_rank );
149 MPI_Abort(MPI_COMM_WORLD, 3004 );
152 if (value != world_rank) {
153 printf( "dup_comm key_1 value incorrect: %ld\n", (long)value );
154 MPI_Abort(MPI_COMM_WORLD, 3005 );
157 /* MPI_Attr_get(dup_comm, key_2, (int *)&value, &flag ); */
160 printf( "dup_comm key_2 not found\n" );
161 MPI_Abort(MPI_COMM_WORLD, 3006 );
164 if (value != world_size) {
165 printf( "dup_comm key_2 value incorrect: %d\n", value );
166 MPI_Abort(MPI_COMM_WORLD, 3007 );
169 MPI_Attr_get(dup_comm, key_3, (void **)&vvalue, &flag );
172 printf( "dup_comm key_3 found!\n" );
173 MPI_Abort(MPI_COMM_WORLD, 3008 );
175 MPI_Keyval_free(&key_1 );
177 c MPI_Keyval_free(&key_2 )
179 MPI_Keyval_free(&key_3 );
182 Split the world into even & odd communicators with reversed ranks.
185 printf( " Comm_split\n" );
187 color = world_rank % 2;
188 key = world_size - world_rank;
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 );
198 MPI_Barrier(split_comm );
200 Test each possible Comm_compare result
203 printf( " Comm_compare\n" );
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 );
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 );
219 ranges[0][0] = world_size - 1;
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 );
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 );
239 Free all communicators created
242 printf( " Comm_free\n" );
244 MPI_Comm_free( &world_comm );
245 MPI_Comm_free( &dup_comm_world );
247 MPI_Comm_free( &rev_comm );
248 MPI_Comm_free( &split_comm );
250 MPI_Group_free( &world_group );
251 MPI_Group_free( &rev_group );
253 if (lo_comm != MPI_COMM_NULL) {
254 MPI_Comm_free( &lo_comm );
255 MPI_Comm_free( &dup_comm );