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 / adlb_mimic1.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
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include "mpi.h"
12 #include "mpitest.h"
13
14 #define NUM_TIMES 500
15 #define MAX_BUF_SIZE (400 * 1024 * 1024) /* 400 MB */
16 #define PUT_SIZE (1024 * 1024) /* 1MB */
17
18 /*
19 static char MTEST_Descrip[] = "ADLB mimic test";
20 */
21
22 /*
23  * ALGORITHM:
24  *    This test uses one server process (S), one target process (T)
25  *    and a bunch of origin processes (O). 'O' PUTs (LOCK/PUT/UNLOCK)
26  *    data to a distinct part of the window, and sends a message to
27  *    'S' once the UNLOCK has completed. The server forwards this
28  *    message to 'T'. 'T' GETS the data from this buffer after it
29  *    receives the message from 'S', to see if it contains the correct
30  *    contents.
31  *
32  *                          -------
33  *                          |  S  |
34  *                          -------
35  *                         ^       \
36  *                step 2  /         \ step 3
37  *                 SEND  /           \ SEND
38  *                      /             v
39  *                  -------  step 1   -------
40  *                  |     | --------> |     |
41  *                  |     |   PUT     |     |
42  *                  |  O  |           |  T  |
43  *                  |     |  step 4   |     |
44  *                  |     | <-------- |     |
45  *                  -------   SEND    -------
46  *
47  */
48
49 int main(int argc, char **argv)
50 {
51     int comm_size, comm_rank, i, by_rank, errs = 0;
52     int rc;
53     char *rma_win_addr, *local_buf;
54     char check;
55     MPI_Win win;
56     MPI_Status status;
57     int max_buf_size = 0, put_size = PUT_SIZE;
58
59     MTest_Init(&argc, &argv);
60     MPI_Comm_size(MPI_COMM_WORLD, &comm_size);
61     MPI_Comm_rank(MPI_COMM_WORLD, &comm_rank);
62
63     if (comm_size <= 2) {
64         fprintf( stderr, "This test requires at least 3 processes\n" );
65         MPI_Abort( MPI_COMM_WORLD, 1 );
66     }
67
68     max_buf_size = comm_size * put_size;
69     if (max_buf_size > MAX_BUF_SIZE) {
70         fprintf( stderr, "Too many processes in COMM_WORLD (max is %d)\n",
71                  MAX_BUF_SIZE / put_size );
72         MPI_Abort( MPI_COMM_WORLD, 1 );
73     }
74
75     /* If alloc mem returns an error (because too much memory is requested */
76     MPI_Errhandler_set( MPI_COMM_WORLD, MPI_ERRORS_RETURN );
77
78     rc = MPI_Alloc_mem(max_buf_size, MPI_INFO_NULL, (void *) &rma_win_addr);
79     if (rc) {
80         MTestPrintErrorMsg( "Unable to MPI_Alloc_mem space (not an error)", rc );
81         MPI_Abort( MPI_COMM_WORLD, 0 );
82     }
83
84     memset(rma_win_addr, 0, max_buf_size);
85     MPI_Win_create((void *) rma_win_addr, max_buf_size, 1, MPI_INFO_NULL, 
86                    MPI_COMM_WORLD, &win);
87
88     /* Note that it is not necessary to use MPI_Alloc_mem for the memory that
89        is not part of the MPI_Win.  */
90     rc = MPI_Alloc_mem(put_size, MPI_INFO_NULL, (void *) &local_buf);
91     if (rc) {
92         MTestPrintErrorMsg( "Unable to MPI_Alloc_mem space (not an error)", rc );
93         MPI_Abort( MPI_COMM_WORLD, 0 );
94     }
95
96     for (i = 0; i < put_size; i++)
97         local_buf[i] = 1;
98
99     MPI_Barrier(MPI_COMM_WORLD);
100
101     if (comm_rank == 0) { /* target */
102         for (i = 0; i < (NUM_TIMES * (comm_size - 2)); i++) {
103             /* Wait for a message from the server to notify me that
104              * someone put some data in my window */
105             MPI_Recv(&by_rank, 1, MPI_INT, 1, 0, MPI_COMM_WORLD, &status);
106
107             /* Got a message from the server that 'by_rank' put some
108              * data in my local window. Check the last byte to make
109              * sure we got it correctly. */
110             MPI_Win_lock(MPI_LOCK_SHARED, 0, 0, win);
111             MPI_Get((void *) &check, 1, MPI_CHAR, 0, 
112                     ((by_rank + 1) * put_size) - 1, 1,
113                     MPI_CHAR, win);
114             MPI_Win_unlock(0, win);
115
116             /* If this is not the value I expect, count it as an error */
117             if (check != 1)
118                 errs++;
119
120             /* Reset the buffer to zero for the next round */
121             memset((void *) (rma_win_addr + (by_rank * put_size)), 0, put_size);
122
123             /* Tell the origin that I am ready for the next round */
124             MPI_Send(NULL, 0, MPI_INT, by_rank, 0, MPI_COMM_WORLD);
125         }
126     }
127
128     else if (comm_rank == 1) { /* server */
129         for (i = 0; i < (NUM_TIMES * (comm_size - 2)); i++) {
130             /* Wait for a message from any of the origin processes
131              * informing me that it has put data to the target
132              * process */
133             MPI_Recv(NULL, 0, MPI_INT, MPI_ANY_SOURCE, 0, MPI_COMM_WORLD, 
134                      &status);
135             by_rank = status.MPI_SOURCE;
136
137             /* Tell the target process that it should be seeing some
138              * data in its local buffer */
139             MPI_Send(&by_rank, 1, MPI_INT, 0, 0, MPI_COMM_WORLD);
140         }
141     }
142
143     else { /* origin */
144         for (i = 0; i < NUM_TIMES; i++) {
145             /* Put some data in the target window */
146             MPI_Win_lock(MPI_LOCK_SHARED, 0, 0, win);
147             MPI_Put(local_buf, put_size, MPI_CHAR, 0, comm_rank * put_size, 
148                     put_size, MPI_CHAR, win);
149             MPI_Win_unlock(0, win);
150
151             /* Tell the server that the put has completed */
152             MPI_Send(NULL, 0, MPI_INT, 1, 0, MPI_COMM_WORLD);
153
154             /* Wait for a message from the target that it is ready for
155              * the next round */
156             MPI_Recv(NULL, 0, MPI_INT, 0, 0, MPI_COMM_WORLD, &status);
157         }
158     }
159
160     MPI_Win_free(&win);
161
162     MPI_Free_mem(rma_win_addr);
163     MPI_Free_mem(local_buf);
164
165     MTest_Finalize(errs);
166     MPI_Finalize();
167
168     return 0;
169 }