1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
4 * (C) 2001 by Argonne National Laboratory.
5 * See COPYRIGHT in top-level directory.
9 Exercise communicator routines.
11 This C version derived from a Fortran test program from ....
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 * );
23 #define FFLUSH fflush(stdout);
28 int main( int argc, char **argv )
31 MTest_Init( &argc, &argv );
33 errs = test_communicators();
34 MTest_Finalize( errs );
39 int copy_fn( MPI_Comm oldcomm, int keyval, void *extra_state,
40 void *attribute_val_in, void *attribute_val_out, int *flag)
42 /* Note that if (sizeof(int) < sizeof(void *), just setting the int
43 part of attribute_val_out may leave some dirty bits
45 *(MPI_Aint *)attribute_val_out = (MPI_Aint)attribute_val_in;
50 int delete_fn( MPI_Comm comm, int keyval, void *attribute_val,
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 );
63 int test_communicators( void )
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;
70 int flag, world_rank, world_size, rank, size, n, key_1, key_3;
71 int color, key, result;
75 MPI_Comm_rank( MPI_COMM_WORLD, &world_rank );
76 MPI_Comm_size( MPI_COMM_WORLD, &world_size );
78 if (world_rank == 0) {
79 printf( "*** Communicators ***\n" ); fflush(stdout);
83 MPI_Comm_dup( MPI_COMM_WORLD, &dup_comm_world );
86 Exercise Comm_create by creating an equivalent to dup_comm_world
87 (sans attributes) and a half-world communicator.
91 if (world_rank == 0) {
92 printf( " Comm_create\n" ); fflush(stdout);
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) {
101 printf( "incorrect rank in world comm: %d\n", rank );
102 MPI_Abort(MPI_COMM_WORLD, 3001 );
109 ranges[0][1] = (world_size - n) - 1;
113 printf( "world rank = %d before range incl\n", world_rank );FFLUSH;
115 MPI_Group_range_incl(world_group, 1, ranges, &lo_group );
117 printf( "world rank = %d after range incl\n", world_rank );FFLUSH;
119 MPI_Comm_create(world_comm, lo_group, &lo_comm );
121 printf( "world rank = %d before group free\n", world_rank );FFLUSH;
123 MPI_Group_free( &lo_group );
126 printf( "world rank = %d after group free\n", world_rank );FFLUSH;
129 if (world_rank < (world_size - n)) {
130 MPI_Comm_rank(lo_comm, &rank );
131 if (rank == MPI_UNDEFINED) {
133 printf( "incorrect lo group rank: %d\n", rank ); fflush(stdout);
134 MPI_Abort(MPI_COMM_WORLD, 3002 );
138 /* printf( "lo in\n" );FFLUSH; */
139 MPI_Barrier(lo_comm );
140 /* printf( "lo out\n" );FFLUSH; */
144 if (lo_comm != MPI_COMM_NULL) {
146 printf( "rank : %d incorrect lo comm:\n", rank ); fflush(stdout);
147 MPI_Abort(MPI_COMM_WORLD, 3003 );
153 printf( "worldrank = %d\n", world_rank );FFLUSH;
155 MPI_Barrier(world_comm);
158 printf( "bar!\n" );FFLUSH;
161 Check Comm_dup by adding attributes to lo_comm & duplicating
164 if (world_rank == 0) {
165 printf( " Comm_dup\n" );
170 if (lo_comm != MPI_COMM_NULL) {
172 MPI_Keyval_create(copy_fn, delete_fn, &key_1, &value );
175 MPI_Keyval_create(MPI_NULL_COPY_FN, MPI_NULL_DELETE_FN,
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 );
184 MPI_Comm_dup(lo_comm, &dup_comm );
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;
196 printf( "dup_comm key_1 not found on %d\n", world_rank );
198 MPI_Abort(MPI_COMM_WORLD, 3004 );
202 if (value != world_rank) {
204 printf( "dup_comm key_1 value incorrect: %ld, expected %d\n",
205 (long)value, world_rank );
207 MPI_Abort(MPI_COMM_WORLD, 3005 );
211 MPI_Attr_get(dup_comm, key_3, (void **)&vvalue, &flag );
212 value = (MPI_Aint)vvalue;
215 printf( "dup_comm key_3 found!\n" );
217 MPI_Abort(MPI_COMM_WORLD, 3008 );
220 MPI_Keyval_free(&key_1 );
221 MPI_Keyval_free(&key_3 );
224 Split the world into even & odd communicators with reversed ranks.
227 if (world_rank == 0) {
228 printf( " Comm_split\n" );
233 color = world_rank % 2;
234 key = world_size - world_rank;
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)) {
241 printf( "incorrect split rank: %d\n", rank ); fflush(stdout);
242 MPI_Abort(MPI_COMM_WORLD, 3009 );
246 MPI_Barrier(split_comm );
248 Test each possible Comm_compare result
251 if (world_rank == 0) {
252 printf( " Comm_compare\n" );
257 MPI_Comm_compare(world_comm, world_comm, &result );
258 if (result != MPI_IDENT) {
260 printf( "incorrect ident result: %d\n", result );
261 MPI_Abort(MPI_COMM_WORLD, 3010 );
265 if (lo_comm != MPI_COMM_NULL) {
266 MPI_Comm_compare(lo_comm, dup_comm, &result );
267 if (result != MPI_CONGRUENT) {
269 printf( "incorrect congruent result: %d\n", result );
270 MPI_Abort(MPI_COMM_WORLD, 3011 );
275 ranges[0][0] = world_size - 1;
279 MPI_Group_range_incl(world_group, 1, ranges, &rev_group );
280 MPI_Comm_create(world_comm, rev_group, &rev_comm );
282 MPI_Comm_compare(world_comm, rev_comm, &result );
283 if (result != MPI_SIMILAR && world_size != 1) {
285 printf( "incorrect similar result: %d\n", result );
286 MPI_Abort(MPI_COMM_WORLD, 3012 );
290 if (lo_comm != MPI_COMM_NULL) {
291 MPI_Comm_compare(world_comm, lo_comm, &result );
292 if (result != MPI_UNEQUAL && world_size != 1) {
294 printf( "incorrect unequal result: %d\n", result );
295 MPI_Abort(MPI_COMM_WORLD, 3013 );
300 Free all communicators created
304 printf( " Comm_free\n" );
307 MPI_Comm_free( &world_comm );
308 MPI_Comm_free( &dup_comm_world );
310 MPI_Comm_free( &rev_comm );
311 MPI_Comm_free( &split_comm );
313 MPI_Group_free( &world_group );
314 MPI_Group_free( &rev_group );
316 if (lo_comm != MPI_COMM_NULL) {
317 MPI_Comm_free( &lo_comm );
318 MPI_Comm_free( &dup_comm );