Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Update RMA tests
[simgrid.git] / teshsuite / smpi / mpich3-test / rma / reqops.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 <assert.h>
10 #include "mpitest.h"
11
12 #define ITER 100
13
14 int main(int argc, char *argv[])
15 {
16     int rank, nproc, i;
17     int errors = 0, all_errors = 0;
18     int *buf;
19     MPI_Win window;
20
21     MPI_Init(&argc, &argv);
22     MPI_Comm_rank(MPI_COMM_WORLD, &rank);
23     MPI_Comm_size(MPI_COMM_WORLD, &nproc);
24
25     if (nproc < 2) {
26         if (rank == 0)
27             printf("Error: must be run with two or more processes\n");
28         MPI_Abort(MPI_COMM_WORLD, 1);
29     }
30
31     /** Create using MPI_Win_create() **/
32
33     if (rank == 0) {
34         MPI_Alloc_mem(4 * sizeof(int), MPI_INFO_NULL, &buf);
35         *buf = nproc - 1;
36     }
37     else
38         buf = NULL;
39
40     MPI_Win_create(buf, 4 * sizeof(int) * (rank == 0), sizeof(int),
41                    MPI_INFO_NULL, MPI_COMM_WORLD, &window);
42
43     /* PROC_NULL Communication */
44     {
45         MPI_Request pn_req[4];
46         int val[4], res;
47
48         MPI_Win_lock_all(0, window);
49
50         MPI_Rget_accumulate(&val[0], 1, MPI_INT, &res, 1, MPI_INT, MPI_PROC_NULL, 0, 1, MPI_INT,
51                             MPI_REPLACE, window, &pn_req[0]);
52         MPI_Rget(&val[1], 1, MPI_INT, MPI_PROC_NULL, 1, 1, MPI_INT, window, &pn_req[1]);
53         MPI_Rput(&val[2], 1, MPI_INT, MPI_PROC_NULL, 2, 1, MPI_INT, window, &pn_req[2]);
54         MPI_Raccumulate(&val[3], 1, MPI_INT, MPI_PROC_NULL, 3, 1, MPI_INT, MPI_REPLACE, window,
55                         &pn_req[3]);
56
57         assert(pn_req[0] != MPI_REQUEST_NULL);
58         assert(pn_req[1] != MPI_REQUEST_NULL);
59         assert(pn_req[2] != MPI_REQUEST_NULL);
60         assert(pn_req[3] != MPI_REQUEST_NULL);
61
62         MPI_Win_unlock_all(window);
63
64         MPI_Waitall(4, pn_req, MPI_STATUSES_IGNORE);
65     }
66
67     MPI_Barrier(MPI_COMM_WORLD);
68
69     MPI_Win_lock(MPI_LOCK_SHARED, 0, 0, window);
70
71     /* GET-ACC: Test third-party communication, through rank 0. */
72     for (i = 0; i < ITER; i++) {
73         MPI_Request gacc_req;
74         int val = -1, exp = -1;
75
76         /* Processes form a ring.  Process 0 starts first, then passes a token
77          * to the right.  Each process, in turn, performs third-party
78          * communication via process 0's window. */
79         if (rank > 0) {
80             MPI_Recv(NULL, 0, MPI_BYTE, rank - 1, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
81         }
82
83         MPI_Rget_accumulate(&rank, 1, MPI_INT, &val, 1, MPI_INT, 0, 0, 1, MPI_INT, MPI_REPLACE,
84                             window, &gacc_req);
85         assert(gacc_req != MPI_REQUEST_NULL);
86         MPI_Wait(&gacc_req, MPI_STATUS_IGNORE);
87
88         exp = (rank + nproc - 1) % nproc;
89
90         if (val != exp) {
91             printf("%d - Got %d, expected %d\n", rank, val, exp);
92             errors++;
93         }
94
95         if (rank < nproc - 1) {
96             MPI_Send(NULL, 0, MPI_BYTE, rank + 1, 0, MPI_COMM_WORLD);
97         }
98
99         MPI_Barrier(MPI_COMM_WORLD);
100     }
101
102     MPI_Barrier(MPI_COMM_WORLD);
103
104     if (rank == 0)
105         *buf = nproc - 1;
106     MPI_Win_sync(window);
107
108     /* GET+PUT: Test third-party communication, through rank 0. */
109     for (i = 0; i < ITER; i++) {
110         MPI_Request req;
111         int val = -1, exp = -1;
112
113         /* Processes form a ring.  Process 0 starts first, then passes a token
114          * to the right.  Each process, in turn, performs third-party
115          * communication via process 0's window. */
116         if (rank > 0) {
117             MPI_Recv(NULL, 0, MPI_BYTE, rank - 1, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
118         }
119
120         MPI_Rget(&val, 1, MPI_INT, 0, 0, 1, MPI_INT, window, &req);
121         assert(req != MPI_REQUEST_NULL);
122         MPI_Wait(&req, MPI_STATUS_IGNORE);
123
124         /* Use flush to guarantee remote completion */
125         MPI_Put(&rank, 1, MPI_INT, 0, 0, 1, MPI_INT, window);
126         MPI_Win_flush(0, window);
127
128         exp = (rank + nproc - 1) % nproc;
129
130         if (val != exp) {
131             printf("%d - Got %d, expected %d\n", rank, val, exp);
132             errors++;
133         }
134
135         if (rank < nproc - 1) {
136             MPI_Send(NULL, 0, MPI_BYTE, rank + 1, 0, MPI_COMM_WORLD);
137         }
138
139         MPI_Barrier(MPI_COMM_WORLD);
140     }
141
142     MPI_Barrier(MPI_COMM_WORLD);
143
144     if (rank == 0)
145         *buf = nproc - 1;
146     MPI_Win_sync(window);
147
148     /* GET+ACC: Test third-party communication, through rank 0. */
149     for (i = 0; i < ITER; i++) {
150         MPI_Request req;
151         int val = -1, exp = -1;
152
153         /* Processes form a ring.  Process 0 starts first, then passes a token
154          * to the right.  Each process, in turn, performs third-party
155          * communication via process 0's window. */
156         if (rank > 0) {
157             MPI_Recv(NULL, 0, MPI_BYTE, rank - 1, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
158         }
159
160         MPI_Rget(&val, 1, MPI_INT, 0, 0, 1, MPI_INT, window, &req);
161         assert(req != MPI_REQUEST_NULL);
162         MPI_Wait(&req, MPI_STATUS_IGNORE);
163
164         /* Use flush to guarantee remote completion */
165         MPI_Accumulate(&rank, 1, MPI_INT, 0, 0, 1, MPI_INT, MPI_REPLACE, window);
166         MPI_Win_flush(0, window);
167
168         exp = (rank + nproc - 1) % nproc;
169
170         if (val != exp) {
171             printf("%d - Got %d, expected %d\n", rank, val, exp);
172             errors++;
173         }
174
175         if (rank < nproc - 1) {
176             MPI_Send(NULL, 0, MPI_BYTE, rank + 1, 0, MPI_COMM_WORLD);
177         }
178
179         MPI_Barrier(MPI_COMM_WORLD);
180     }
181     MPI_Win_unlock(0, window);
182
183     MPI_Barrier(MPI_COMM_WORLD);
184
185     /* Wait inside of an epoch */
186     {
187         MPI_Request pn_req[4];
188         int val[4], res;
189         const int target = 0;
190
191         MPI_Win_lock_all(0, window);
192
193         MPI_Rget_accumulate(&val[0], 1, MPI_INT, &res, 1, MPI_INT, target, 0, 1, MPI_INT,
194                             MPI_REPLACE, window, &pn_req[0]);
195         MPI_Rget(&val[1], 1, MPI_INT, target, 1, 1, MPI_INT, window, &pn_req[1]);
196         MPI_Rput(&val[2], 1, MPI_INT, target, 2, 1, MPI_INT, window, &pn_req[2]);
197         MPI_Raccumulate(&val[3], 1, MPI_INT, target, 3, 1, MPI_INT, MPI_REPLACE, window,
198                         &pn_req[3]);
199
200         assert(pn_req[0] != MPI_REQUEST_NULL);
201         assert(pn_req[1] != MPI_REQUEST_NULL);
202         assert(pn_req[2] != MPI_REQUEST_NULL);
203         assert(pn_req[3] != MPI_REQUEST_NULL);
204
205         MPI_Waitall(4, pn_req, MPI_STATUSES_IGNORE);
206
207         MPI_Win_unlock_all(window);
208     }
209
210     MPI_Barrier(MPI_COMM_WORLD);
211
212     /* Wait outside of an epoch */
213     {
214         MPI_Request pn_req[4];
215         int val[4], res;
216         const int target = 0;
217
218         MPI_Win_lock_all(0, window);
219
220         MPI_Rget_accumulate(&val[0], 1, MPI_INT, &res, 1, MPI_INT, target, 0, 1, MPI_INT,
221                             MPI_REPLACE, window, &pn_req[0]);
222         MPI_Rget(&val[1], 1, MPI_INT, target, 1, 1, MPI_INT, window, &pn_req[1]);
223         MPI_Rput(&val[2], 1, MPI_INT, target, 2, 1, MPI_INT, window, &pn_req[2]);
224         MPI_Raccumulate(&val[3], 1, MPI_INT, target, 3, 1, MPI_INT, MPI_REPLACE, window,
225                         &pn_req[3]);
226
227         assert(pn_req[0] != MPI_REQUEST_NULL);
228         assert(pn_req[1] != MPI_REQUEST_NULL);
229         assert(pn_req[2] != MPI_REQUEST_NULL);
230         assert(pn_req[3] != MPI_REQUEST_NULL);
231
232         MPI_Win_unlock_all(window);
233
234         MPI_Waitall(4, pn_req, MPI_STATUSES_IGNORE);
235     }
236
237     /* Wait in a different epoch */
238     {
239         MPI_Request pn_req[4];
240         int val[4], res;
241         const int target = 0;
242
243         MPI_Win_lock_all(0, window);
244
245         MPI_Rget_accumulate(&val[0], 1, MPI_INT, &res, 1, MPI_INT, target, 0, 1, MPI_INT,
246                             MPI_REPLACE, window, &pn_req[0]);
247         MPI_Rget(&val[1], 1, MPI_INT, target, 1, 1, MPI_INT, window, &pn_req[1]);
248         MPI_Rput(&val[2], 1, MPI_INT, target, 2, 1, MPI_INT, window, &pn_req[2]);
249         MPI_Raccumulate(&val[3], 1, MPI_INT, target, 3, 1, MPI_INT, MPI_REPLACE, window,
250                         &pn_req[3]);
251
252         assert(pn_req[0] != MPI_REQUEST_NULL);
253         assert(pn_req[1] != MPI_REQUEST_NULL);
254         assert(pn_req[2] != MPI_REQUEST_NULL);
255         assert(pn_req[3] != MPI_REQUEST_NULL);
256
257         MPI_Win_unlock_all(window);
258
259         MPI_Win_lock_all(0, window);
260         MPI_Waitall(4, pn_req, MPI_STATUSES_IGNORE);
261         MPI_Win_unlock_all(window);
262     }
263
264     /* Wait in a fence epoch */
265     {
266         MPI_Request pn_req[4];
267         int val[4], res;
268         const int target = 0;
269
270         MPI_Win_lock_all(0, window);
271
272         MPI_Rget_accumulate(&val[0], 1, MPI_INT, &res, 1, MPI_INT, target, 0, 1, MPI_INT,
273                             MPI_REPLACE, window, &pn_req[0]);
274         MPI_Rget(&val[1], 1, MPI_INT, target, 1, 1, MPI_INT, window, &pn_req[1]);
275         MPI_Rput(&val[2], 1, MPI_INT, target, 2, 1, MPI_INT, window, &pn_req[2]);
276         MPI_Raccumulate(&val[3], 1, MPI_INT, target, 3, 1, MPI_INT, MPI_REPLACE, window,
277                         &pn_req[3]);
278
279         assert(pn_req[0] != MPI_REQUEST_NULL);
280         assert(pn_req[1] != MPI_REQUEST_NULL);
281         assert(pn_req[2] != MPI_REQUEST_NULL);
282         assert(pn_req[3] != MPI_REQUEST_NULL);
283
284         MPI_Win_unlock_all(window);
285
286         MPI_Win_fence(0, window);
287         MPI_Waitall(4, pn_req, MPI_STATUSES_IGNORE);
288         MPI_Win_fence(0, window);
289     }
290
291     MPI_Win_free(&window);
292     if (buf)
293         MPI_Free_mem(buf);
294
295     MPI_Reduce(&errors, &all_errors, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD);
296
297     if (rank == 0 && all_errors == 0)
298         printf(" No Errors\n");
299
300     MPI_Finalize();
301
302     return 0;
303 }