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 );
34 while (MTestGetIntercomm( &intercomm, &isLeft, 2 )) {
37 if (intercomm == MPI_COMM_NULL) continue;
39 /* Split this intercomm. The new intercomms contain the
40 processes that had odd (resp even) rank in their local group
41 in the original intercomm */
42 MTestPrintfMsg( 1, "Created intercomm %s\n", MTestGetIntercommName() );
43 MPI_Comm_rank( intercomm, &key );
45 MPI_Comm_split( intercomm, color, key, &newcomm );
46 /* Make sure that the new communicator has the appropriate pieces */
47 if (newcomm != MPI_COMM_NULL) {
48 int orig_rsize, orig_size, new_rsize, new_size;
49 int predicted_size, flag, commok=1;
51 MPI_Comm_test_inter( intercomm, &flag );
54 printf( "Output communicator is not an intercomm\n" );
58 MPI_Comm_remote_size( intercomm, &orig_rsize );
59 MPI_Comm_remote_size( newcomm, &new_rsize );
60 MPI_Comm_size( intercomm, &orig_size );
61 MPI_Comm_size( newcomm, &new_size );
62 /* The local size is 1/2 the original size, +1 if the
63 size was odd and the color was even. More precisely,
64 let n be the orig_size. Then
66 orig size even n/2 n/2
67 orig size odd (n+1)/2 n/2
69 However, since these are integer valued, if n is even,
70 then (n+1)/2 = n/2, so this table is much simpler:
72 orig size even (n+1)/2 n/2
73 orig size odd (n+1)/2 n/2
76 predicted_size = (orig_size + !color) / 2;
77 if (predicted_size != new_size) {
79 printf( "Predicted size = %d but found %d for %s (%d,%d)\n",
80 predicted_size, new_size, MTestGetIntercommName(),
81 orig_size, orig_rsize );
84 predicted_size = (orig_rsize + !color) / 2;
85 if (predicted_size != new_rsize) {
87 printf( "Predicted remote size = %d but found %d for %s (%d,%d)\n",
88 predicted_size, new_rsize, MTestGetIntercommName(),
89 orig_size, orig_rsize );
94 errs += TestIntercomm( newcomm );
99 /* If the newcomm is null, then this means that remote group
100 for this color is of size zero (since all processes in this
101 test have been given colors other than MPI_UNDEFINED).
104 MPI_Comm_remote_size( intercomm, &orig_rsize );
105 if (orig_rsize == 1) {
108 printf( "Returned null intercomm when non-null expected\n" );
112 if (newcomm != MPI_COMM_NULL)
113 MPI_Comm_free( &newcomm );
114 MPI_Comm_free( &intercomm );
116 MTest_Finalize(errs);
123 /* FIXME: This is copied from iccreate. It should be in one place */
124 int TestIntercomm( MPI_Comm comm )
126 int local_size, remote_size, rank, **bufs, *bufmem, rbuf[2], j;
127 int errs = 0, wrank, nsize;
128 char commname[MPI_MAX_OBJECT_NAME+1];
131 MPI_Comm_rank( MPI_COMM_WORLD, &wrank );
132 MPI_Comm_size( comm, &local_size );
133 MPI_Comm_remote_size( comm, &remote_size );
134 MPI_Comm_rank( comm, &rank );
135 MPI_Comm_get_name( comm, commname, &nsize );
137 MTestPrintfMsg( 1, "Testing communication on intercomm %s\n", commname );
139 reqs = (MPI_Request *)malloc( remote_size * sizeof(MPI_Request) );
141 printf( "[%d] Unable to allocated %d requests for testing intercomm %s\n",
142 wrank, remote_size, commname );
146 bufs = (int **) malloc( remote_size * sizeof(int *) );
148 printf( "[%d] Unable to allocated %d int pointers for testing intercomm %s\n",
149 wrank, remote_size, commname );
153 bufmem = (int *) malloc( remote_size * 2 * sizeof(int) );
155 printf( "[%d] Unable to allocated %d int data for testing intercomm %s\n",
156 wrank, 2*remote_size, commname );
161 /* Each process sends a message containing its own rank and the
162 rank of the destination with a nonblocking send. Because we're using
163 nonblocking sends, we need to use different buffers for each isend */
164 for (j=0; j<remote_size; j++) {
165 bufs[j] = &bufmem[2*j];
168 MPI_Isend( bufs[j], 2, MPI_INT, j, 0, comm, &reqs[j] );
171 for (j=0; j<remote_size; j++) {
172 MPI_Recv( rbuf, 2, MPI_INT, j, 0, comm, MPI_STATUS_IGNORE );
174 printf( "[%d] Expected rank %d but saw %d in %s\n",
175 wrank, j, rbuf[0], commname );
178 if (rbuf[1] != rank) {
179 printf( "[%d] Expected target rank %d but saw %d from %d in %s\n",
180 wrank, rank, rbuf[1], j, commname );
186 MPI_Waitall( remote_size, reqs, MPI_STATUSES_IGNORE );