1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
4 * (C) 2007 by Argonne National Laboratory.
5 * See COPYRIGHT in top-level directory.
13 * This program tests that MPI_Comm_split applies to intercommunicators;
14 * this is an extension added in MPI-2
17 int TestIntercomm( MPI_Comm );
19 int main( int argc, char *argv[] )
23 MPI_Comm intercomm, newcomm;
25 MTest_Init( &argc, &argv );
27 MPI_Comm_size( MPI_COMM_WORLD, &size );
29 printf( "This test requires at least 4 processes\n" );
30 MPI_Abort( MPI_COMM_WORLD, 1 );
33 while (MTestGetIntercomm( &intercomm, &isLeft, 2 )) {
36 if (intercomm == MPI_COMM_NULL) continue;
38 /* Split this intercomm. The new intercomms contain the
39 processes that had odd (resp even) rank in their local group
40 in the original intercomm */
41 MTestPrintfMsg( 1, "Created intercomm %s\n", MTestGetIntercommName() );
42 MPI_Comm_rank( intercomm, &key );
44 MPI_Comm_split( intercomm, color, key, &newcomm );
45 /* Make sure that the new communicator has the appropriate pieces */
46 if (newcomm != MPI_COMM_NULL) {
47 int orig_rsize, orig_size, new_rsize, new_size;
48 int predicted_size, flag, commok=1;
50 MPI_Comm_test_inter( intercomm, &flag );
53 printf( "Output communicator is not an intercomm\n" );
57 MPI_Comm_remote_size( intercomm, &orig_rsize );
58 MPI_Comm_remote_size( newcomm, &new_rsize );
59 MPI_Comm_size( intercomm, &orig_size );
60 MPI_Comm_size( newcomm, &new_size );
61 /* The local size is 1/2 the original size, +1 if the
62 size was odd and the color was even. More precisely,
63 let n be the orig_size. Then
65 orig size even n/2 n/2
66 orig size odd (n+1)/2 n/2
68 However, since these are integer valued, if n is even,
69 then (n+1)/2 = n/2, so this table is much simpler:
71 orig size even (n+1)/2 n/2
72 orig size odd (n+1)/2 n/2
75 predicted_size = (orig_size + !color) / 2;
76 if (predicted_size != new_size) {
78 printf( "Predicted size = %d but found %d for %s (%d,%d)\n",
79 predicted_size, new_size, MTestGetIntercommName(),
80 orig_size, orig_rsize );
83 predicted_size = (orig_rsize + !color) / 2;
84 if (predicted_size != new_rsize) {
86 printf( "Predicted remote size = %d but found %d for %s (%d,%d)\n",
87 predicted_size, new_rsize, MTestGetIntercommName(),
88 orig_size, orig_rsize );
93 errs += TestIntercomm( newcomm );
98 /* If the newcomm is null, then this means that remote group
99 for this color is of size zero (since all processes in this
100 test have been given colors other than MPI_UNDEFINED).
103 MPI_Comm_remote_size( intercomm, &orig_rsize );
104 if (orig_rsize == 1) {
107 printf( "Returned null intercomm when non-null expected\n" );
111 if (newcomm != MPI_COMM_NULL)
112 MPI_Comm_free( &newcomm );
113 MPI_Comm_free( &intercomm );
115 MTest_Finalize(errs);
122 /* FIXME: This is copied from iccreate. It should be in one place */
123 int TestIntercomm( MPI_Comm comm )
125 int local_size, remote_size, rank, **bufs, *bufmem, rbuf[2], j;
126 int errs = 0, wrank, nsize;
127 char commname[MPI_MAX_OBJECT_NAME+1];
130 MPI_Comm_rank( MPI_COMM_WORLD, &wrank );
131 MPI_Comm_size( comm, &local_size );
132 MPI_Comm_remote_size( comm, &remote_size );
133 MPI_Comm_rank( comm, &rank );
134 MPI_Comm_get_name( comm, commname, &nsize );
136 MTestPrintfMsg( 1, "Testing communication on intercomm %s\n", commname );
138 reqs = (MPI_Request *)malloc( remote_size * sizeof(MPI_Request) );
140 printf( "[%d] Unable to allocated %d requests for testing intercomm %s\n",
141 wrank, remote_size, commname );
145 bufs = (int **) malloc( remote_size * sizeof(int *) );
147 printf( "[%d] Unable to allocated %d int pointers for testing intercomm %s\n",
148 wrank, remote_size, commname );
152 bufmem = (int *) malloc( remote_size * 2 * sizeof(int) );
154 printf( "[%d] Unable to allocated %d int data for testing intercomm %s\n",
155 wrank, 2*remote_size, commname );
160 /* Each process sends a message containing its own rank and the
161 rank of the destination with a nonblocking send. Because we're using
162 nonblocking sends, we need to use different buffers for each isend */
163 for (j=0; j<remote_size; j++) {
164 bufs[j] = &bufmem[2*j];
167 MPI_Isend( bufs[j], 2, MPI_INT, j, 0, comm, &reqs[j] );
170 for (j=0; j<remote_size; j++) {
171 MPI_Recv( rbuf, 2, MPI_INT, j, 0, comm, MPI_STATUS_IGNORE );
173 printf( "[%d] Expected rank %d but saw %d in %s\n",
174 wrank, j, rbuf[0], commname );
177 if (rbuf[1] != rank) {
178 printf( "[%d] Expected target rank %d but saw %d from %d in %s\n",
179 wrank, rank, rbuf[1], j, commname );
185 MPI_Waitall( remote_size, reqs, MPI_STATUSES_IGNORE );