1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
4 * (C) 2003 by Argonne National Laboratory.
5 * See COPYRIGHT in top-level directory.
14 static char MTEST_Descrip[] = "Mix synchronization types";
17 void delay( double time );
18 void delay( double time )
22 while (MPI_Wtime() - t1 < time) ;
25 int main( int argc, char *argv[] )
28 int crank, csize, source, dest, loop;
29 int *buf0, *buf1, *buf2, *inbuf2, count0, count1, count2, count, i;
34 MTest_Init( &argc, &argv );
36 comm = MPI_COMM_WORLD;
42 count = count0 + count1 + count2 + 2;
44 /* Allocate and initialize the local buffers */
45 buf0 = (int *)malloc( count0 * sizeof(int) );
46 buf1 = (int *)malloc( count1 * sizeof(int) );
47 buf2 = (int *)malloc( count2 * sizeof(int) );
48 inbuf2 = (int *)malloc( count2 * sizeof(int) );
49 if (!buf0 || !buf1 || !buf2 || !inbuf2) {
50 fprintf( stderr, "Unable to allocated buf0-2\n" );
51 MPI_Abort( MPI_COMM_WORLD, 1 );
53 for (i=0; i<count0; i++) buf0[i] = i;
54 for (i=0; i<count1; i++) buf1[i] = i + count0;
55 for (i=0; i<count2; i++) buf2[i] = i + count0 + count1;
57 /* Allocate the window buffer and create the memory window. */
58 MPI_Alloc_mem( count*sizeof(int), MPI_INFO_NULL, &winbuf );
60 fprintf( stderr, "Unable to allocate %d words\n", count );
61 MPI_Abort( MPI_COMM_WORLD, 0 );
63 MPI_Win_create( winbuf, count*sizeof(int), sizeof(int), MPI_INFO_NULL,
66 MPI_Comm_size( comm, &csize );
67 MPI_Comm_rank( comm, &crank );
71 for (loop=0; loop<2; loop++) {
72 /* Perform several communication operations, mixing synchronization
73 types. Use multiple communication to avoid the single-operation
74 optimization that may be present. */
75 MTestPrintfMsg( 3, "Beginning loop %d of mixed sync put operations\n",
78 if (crank == source) {
79 MTestPrintfMsg( 3, "About to perform exclusive lock\n" );
80 MPI_Win_lock( MPI_LOCK_EXCLUSIVE, dest, 0, win );
81 MPI_Put( buf0, count0, MPI_INT, dest, 0, count0, MPI_INT, win );
82 MPI_Put( buf1, count1, MPI_INT, dest, count0, count1, MPI_INT,
84 MPI_Put( buf2, count2, MPI_INT, dest, count0+count1, count2,
86 MPI_Win_unlock( dest, win );
87 MTestPrintfMsg( 3, "Released exclusive lock\n" );
89 else if (crank == dest) {
90 /* Just delay a bit */
94 /* The synchronization mode can only be changed when the process
95 memory and public copy are guaranteed to have the same values
96 (See 11.7, Semantics and Correctness). This barrier ensures that
97 the lock/unlock completes before the fence call. */
100 MTestPrintfMsg( 3, "About to start fence\n" );
101 MPI_Win_fence( 0, win );
102 if (crank == source) {
103 MPI_Put( buf0, count0, MPI_INT, dest, 1, count0, MPI_INT, win );
104 MPI_Put( buf1, count1, MPI_INT, dest, 1+count0, count1, MPI_INT,
106 MPI_Put( buf2, count2, MPI_INT, dest, 1+count0+count1, count2,
109 MPI_Win_fence( 0, win );
110 MTestPrintfMsg( 3, "Finished with fence sync\n" );
114 for (i=0; i<count0+count1+count2; i++) {
115 if (winbuf[1+i] != i) {
118 fprintf( stderr, "winbuf[%d] = %d, expected %d\n",
119 1+i, winbuf[1+i], i ); fflush(stderr);
125 /* End of test loop */
128 /* Use mixed put and accumulate */
129 for (loop=0; loop<2; loop++) {
130 /* Perform several communication operations, mixing synchronization
131 types. Use multiple communication to avoid the single-operation
132 optimization that may be present. */
133 MTestPrintfMsg( 3, "Begining loop %d of mixed sync put/acc operations\n",
135 memset( winbuf, 0, count*sizeof(int) );
137 if (crank == source) {
138 MPI_Win_lock( MPI_LOCK_EXCLUSIVE, dest, 0, win );
139 MPI_Accumulate( buf0, count0, MPI_INT, dest, 0, count0, MPI_INT,
141 MPI_Accumulate( buf1, count1, MPI_INT, dest, count0, count1,
142 MPI_INT, MPI_SUM, win );
143 MPI_Put( buf2, count2, MPI_INT, dest, count0+count1, count2,
145 MPI_Win_unlock( dest, win );
147 else if (crank == dest) {
148 /* Just delay a bit */
151 /* See above - the fence should not start until the unlock completes */
153 MPI_Win_fence( 0, win );
154 if (crank == source) {
155 MPI_Accumulate( buf0, count0, MPI_INT, dest, 1, count0, MPI_INT,
157 MPI_Accumulate( buf1, count1, MPI_INT, dest, 1+count0, count1,
158 MPI_INT, MPI_REPLACE, win );
159 MPI_Put( buf2, count2, MPI_INT, dest, 1+count0+count1, count2,
162 MPI_Win_fence( 0, win );
166 for (i=0; i<count0+count1+count2; i++) {
167 if (winbuf[1+i] != i) {
170 fprintf( stderr, "winbuf[%d] = %d, expected %d\n",
171 1+i, winbuf[1+i], i ); fflush(stderr);
177 /* End of test loop */
180 /* Use mixed accumulate and get */
181 for (loop=0; loop<2; loop++) {
182 /* Perform several communication operations, mixing synchronization
183 types. Use multiple communication to avoid the single-operation
184 optimization that may be present. */
185 MTestPrintfMsg( 3, "Begining loop %d of mixed sync put/get/acc operations\n",
188 if (crank == source) {
189 MPI_Win_lock( MPI_LOCK_EXCLUSIVE, dest, 0, win );
190 MPI_Accumulate( buf0, count0, MPI_INT, dest, 0, count0, MPI_INT,
192 MPI_Put( buf1, count1, MPI_INT, dest, count0, count1, MPI_INT,
194 MPI_Get( inbuf2, count2, MPI_INT, dest, count0+count1, count2,
196 MPI_Win_unlock( dest, win );
198 else if (crank == dest) {
199 /* Just delay a bit */
202 /* See above - the fence should not start until the unlock completes */
204 MPI_Win_fence( 0, win );
205 if (crank == source) {
206 MPI_Accumulate( buf0, count0, MPI_INT, dest, 1, count0, MPI_INT,
208 MPI_Put( buf1, count1, MPI_INT, dest, 1+count0, count1, MPI_INT,
210 MPI_Get( inbuf2, count2, MPI_INT, dest, 1+count0+count1, count2,
213 MPI_Win_fence( 0, win );
217 /* Do the put/accumulate parts */
218 for (i=0; i<count0+count1; i++) {
219 if (winbuf[1+i] != i) {
222 fprintf( stderr, "winbuf[%d] = %d, expected %d\n",
223 1+i, winbuf[1+i], i ); fflush(stderr);
229 /* End of test loop */
232 MTestPrintfMsg( 3, "Freeing the window\n" );
234 MPI_Win_free( &win );
235 MPI_Free_mem( winbuf );
241 MTest_Finalize( errs );