Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge branch 'master' of https://github.com/mpoquet/simgrid
[simgrid.git] / teshsuite / smpi / mpich3-test / rma / mixedsync.c
1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
2 /*
3  *
4  *  (C) 2003 by Argonne National Laboratory.
5  *      See COPYRIGHT in top-level directory.
6  */
7 #include "mpi.h"
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include "mpitest.h"
11 #include <string.h>
12
13 /*
14 static char MTEST_Descrip[] = "Mix synchronization types";
15 */
16
17 void delay( double time );
18 void delay( double time )
19 {
20     double t1;
21     t1 = MPI_Wtime();
22     while (MPI_Wtime() - t1 < time) ;
23 }
24
25 int main( int argc, char *argv[] )
26 {
27     int      errs = 0;
28     int      crank, csize, source, dest, loop;
29     int      *buf0, *buf1, *buf2, *inbuf2, count0, count1, count2, count, i;
30     MPI_Comm comm;
31     MPI_Win  win;
32     int      *winbuf;
33
34     MTest_Init( &argc, &argv );
35
36     comm = MPI_COMM_WORLD;
37
38     count0 = 1000;
39     count1 = 1;
40     count2 = 100;
41
42     count = count0 + count1 + count2 + 2;
43     
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 );
52     }
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;
56
57     /* Allocate the window buffer and create the memory window. */
58     MPI_Alloc_mem( count*sizeof(int), MPI_INFO_NULL, &winbuf );
59     if (!winbuf) {
60         fprintf( stderr, "Unable to allocate %d words\n", count );
61         MPI_Abort( MPI_COMM_WORLD, 0 );
62     }
63     MPI_Win_create( winbuf, count*sizeof(int), sizeof(int), MPI_INFO_NULL, 
64                     comm, &win );
65
66     MPI_Comm_size( comm, &csize );
67     MPI_Comm_rank( comm, &crank );
68     dest   = 0;
69     source = 1;
70
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", 
76                         loop ); 
77         MPI_Barrier( comm );
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, 
83                      win );
84             MPI_Put( buf2, count2, MPI_INT, dest, count0+count1, count2, 
85                      MPI_INT, win );
86             MPI_Win_unlock( dest, win );
87             MTestPrintfMsg( 3, "Released exclusive lock\n" );
88         }
89         else if (crank == dest) {
90             /* Just delay a bit */
91             delay( 0.0001 );
92         }
93
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.  */
98         MPI_Barrier( comm );
99
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, 
105                      win );
106             MPI_Put( buf2, count2, MPI_INT, dest, 1+count0+count1, count2, 
107                      MPI_INT, win );
108         }
109         MPI_Win_fence( 0, win );
110         MTestPrintfMsg( 3, "Finished with fence sync\n" );
111
112         /* Check results */
113         if (crank == dest) {
114             for (i=0; i<count0+count1+count2; i++) {
115                 if (winbuf[1+i] != i) {
116                     errs++;
117                     if (errs < 10) {
118                         fprintf( stderr, "winbuf[%d] = %d, expected %d\n",
119                                  1+i, winbuf[1+i], i ); fflush(stderr);
120                     }
121                 }
122             }
123         }
124         
125         /* End of test loop */
126     }
127
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", 
134                         loop ); 
135         memset( winbuf, 0, count*sizeof(int) );
136         MPI_Barrier( comm );
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, 
140                             MPI_SUM, win );
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, 
144                      MPI_INT, win );
145             MPI_Win_unlock( dest, win );
146         }
147         else if (crank == dest) {
148             /* Just delay a bit */
149             delay( 0.0001 );
150         }
151         /* See above - the fence should not start until the unlock completes */
152         MPI_Barrier( comm );
153         MPI_Win_fence( 0, win );
154         if (crank == source) {
155             MPI_Accumulate( buf0, count0, MPI_INT, dest, 1, count0, MPI_INT, 
156                             MPI_REPLACE, win );
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, 
160                      MPI_INT, win );
161         }
162         MPI_Win_fence( 0, win );
163
164         /* Check results */
165         if (crank == dest) {
166             for (i=0; i<count0+count1+count2; i++) {
167                 if (winbuf[1+i] != i) {
168                     errs++;
169                     if (errs < 10) {
170                         fprintf( stderr, "winbuf[%d] = %d, expected %d\n",
171                                  1+i, winbuf[1+i], i ); fflush(stderr);
172                     }
173                 }
174             }
175         }
176         
177         /* End of test loop */
178     }
179
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", 
186                         loop ); 
187         MPI_Barrier( comm );
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, 
191                             MPI_REPLACE, win );
192             MPI_Put( buf1, count1, MPI_INT, dest, count0, count1, MPI_INT, 
193                      win );
194             MPI_Get( inbuf2, count2, MPI_INT, dest, count0+count1, count2, 
195                      MPI_INT, win );
196             MPI_Win_unlock( dest, win );
197         }
198         else if (crank == dest) {
199             /* Just delay a bit */
200             delay( 0.0001 );
201         }
202         /* See above - the fence should not start until the unlock completes */
203         MPI_Barrier( comm );
204         MPI_Win_fence( 0, win );
205         if (crank == source) {
206             MPI_Accumulate( buf0, count0, MPI_INT, dest, 1, count0, MPI_INT, 
207                             MPI_REPLACE, win );
208             MPI_Put( buf1, count1, MPI_INT, dest, 1+count0, count1, MPI_INT, 
209                      win );
210             MPI_Get( inbuf2, count2, MPI_INT, dest, 1+count0+count1, count2, 
211                      MPI_INT, win );
212         }
213         MPI_Win_fence( 0, win );
214
215         /* Check results */
216         if (crank == dest) {
217             /* Do the put/accumulate parts */
218             for (i=0; i<count0+count1; i++) {
219                 if (winbuf[1+i] != i) {
220                     errs++;
221                     if (errs < 10) {
222                         fprintf( stderr, "winbuf[%d] = %d, expected %d\n",
223                                  1+i, winbuf[1+i], i ); fflush(stderr);
224                     }
225                 }
226             }
227         }
228         
229         /* End of test loop */
230     }
231
232     MTestPrintfMsg( 3, "Freeing the window\n" );
233     MPI_Barrier( comm );
234     MPI_Win_free( &win );
235     MPI_Free_mem( winbuf );
236     free( buf0 );
237     free( buf1 );
238     free( buf2 );
239     free( inbuf2 );
240
241     MTest_Finalize( errs );
242
243     MPI_Finalize();
244     return 0;
245 }