Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Add new entry in Release_Notes.
[simgrid.git] / teshsuite / smpi / mpich3-test / rma / atomic_rmw_gacc.c
1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
2 /*
3  *
4  *  (C) 2015 by Argonne National Laboratory.
5  *      See COPYRIGHT in top-level directory.
6  */
7
8 /* This test is going to test the atomicity for "read-modify-write" in GACC
9  * operations */
10
11 /* This test is similar with atomic_rmw_fop.c.
12  * There are three processes involved in this test: P0 (origin_shm), P1 (origin_am),
13  * and P2 (dest). P0 and P1 issues multiple GACC with MPI_SUM and OP_COUNT integers
14  * (value 1) to P2 via SHM and AM respectively. The correct results should be that the
15  * results on P0 and P1 never be the same for integers on the corresponding index
16  * in [0...OP_COUNT-1].
17  */
18
19 #include "mpi.h"
20 #include <stdio.h>
21
22 #define OP_COUNT 10
23 #define AM_BUF_NUM  10
24 #define SHM_BUF_NUM 10000
25 #define WIN_BUF_NUM 1
26
27 #define LOOP_SIZE 15
28 #define CHECK_TAG 123
29
30 int rank, size;
31 int dest, origin_shm, origin_am;
32 int *orig_buf = NULL, *result_buf = NULL, *target_buf = NULL, *check_buf = NULL;
33 MPI_Win win;
34
35 void checkResults(int loop_k, int *errors)
36 {
37     int i, j, m;
38     MPI_Status status;
39
40     if (rank != dest) {
41         /* check results on P0 and P2 (origin) */
42         if (rank == origin_am) {
43             MPI_Send(result_buf, AM_BUF_NUM * OP_COUNT, MPI_INT, origin_shm, CHECK_TAG,
44                      MPI_COMM_WORLD);
45         }
46         else if (rank == origin_shm) {
47             MPI_Alloc_mem(sizeof(int) * AM_BUF_NUM * OP_COUNT, MPI_INFO_NULL, &check_buf);
48             MPI_Recv(check_buf, AM_BUF_NUM * OP_COUNT, MPI_INT, origin_am, CHECK_TAG,
49                      MPI_COMM_WORLD, &status);
50             for (i = 0; i < AM_BUF_NUM; i++) {
51                 for (j = 0; j < SHM_BUF_NUM; j++) {
52                     for (m = 0; m < OP_COUNT; m++) {
53                         if (check_buf[i * OP_COUNT + m] == result_buf[j * OP_COUNT + m]) {
54                             printf
55                                 ("LOOP=%d, rank=%d, FOP, both check_buf[%d] and result_buf[%d] equal to %d, expected to be different. \n",
56                                  loop_k, rank, i * OP_COUNT + m, j * OP_COUNT + m,
57                                  check_buf[i * OP_COUNT + m]);
58                             (*errors)++;
59                         }
60                     }
61                 }
62             }
63             MPI_Free_mem(check_buf);
64         }
65     }
66     else {
67         MPI_Win_lock(MPI_LOCK_SHARED, rank, 0, win);
68         /* check results on P1 */
69         for (i = 0; i < OP_COUNT; i++) {
70             if (target_buf[i] != AM_BUF_NUM + SHM_BUF_NUM) {
71                 printf("LOOP=%d, rank=%d, FOP, target_buf[%d] = %d, expected %d. \n",
72                        loop_k, rank, i, target_buf[i], AM_BUF_NUM + SHM_BUF_NUM);
73                 (*errors)++;
74             }
75         }
76         MPI_Win_unlock(rank, win);
77     }
78 }
79
80 int main(int argc, char *argv[])
81 {
82     int i, k;
83     int errors = 0, all_errors = 0;
84     int my_buf_num;
85     MPI_Datatype origin_dtp, target_dtp;
86
87     MPI_Init(&argc, &argv);
88
89     MPI_Comm_rank(MPI_COMM_WORLD, &rank);
90     MPI_Comm_size(MPI_COMM_WORLD, &size);
91     if (size != 3) {
92         /* run this test with three processes */
93         goto exit_test;
94     }
95
96     MPI_Type_contiguous(OP_COUNT, MPI_INT, &origin_dtp);
97     MPI_Type_commit(&origin_dtp);
98     MPI_Type_contiguous(OP_COUNT, MPI_INT, &target_dtp);
99     MPI_Type_commit(&target_dtp);
100
101     /* this works when MPIR_PARAM_CH3_ODD_EVEN_CLIQUES is set */
102     dest = 2;
103     origin_shm = 0;
104     origin_am = 1;
105
106     if (rank == origin_am)
107         my_buf_num = AM_BUF_NUM;
108     else if (rank == origin_shm)
109         my_buf_num = SHM_BUF_NUM;
110
111     if (rank != dest) {
112         MPI_Alloc_mem(sizeof(int) * my_buf_num * OP_COUNT, MPI_INFO_NULL, &orig_buf);
113         MPI_Alloc_mem(sizeof(int) * my_buf_num * OP_COUNT, MPI_INFO_NULL, &result_buf);
114     }
115
116     MPI_Win_allocate(sizeof(int) * WIN_BUF_NUM * OP_COUNT, sizeof(int), MPI_INFO_NULL,
117                      MPI_COMM_WORLD, &target_buf, &win);
118
119     for (k = 0; k < LOOP_SIZE; k++) {
120
121         /* ====== Part 1: test basic datatypes ======== */
122
123         /* init buffers */
124         if (rank != dest) {
125             for (i = 0; i < my_buf_num * OP_COUNT; i++) {
126                 orig_buf[i] = 1;
127                 result_buf[i] = 0;
128             }
129         }
130         else {
131             MPI_Win_lock(MPI_LOCK_SHARED, rank, 0, win);
132             for (i = 0; i < WIN_BUF_NUM * OP_COUNT; i++) {
133                 target_buf[i] = 0;
134             }
135             MPI_Win_unlock(rank, win);
136         }
137
138         MPI_Barrier(MPI_COMM_WORLD);
139
140         MPI_Win_lock_all(0, win);
141         if (rank != dest) {
142             for (i = 0; i < my_buf_num; i++) {
143                 MPI_Get_accumulate(&(orig_buf[i * OP_COUNT]), OP_COUNT, MPI_INT,
144                                    &(result_buf[i * OP_COUNT]), OP_COUNT, MPI_INT,
145                                    dest, 0, OP_COUNT, MPI_INT, MPI_SUM, win);
146                 MPI_Win_flush(dest, win);
147             }
148         }
149         MPI_Win_unlock_all(win);
150
151         MPI_Barrier(MPI_COMM_WORLD);
152
153         checkResults(k, &errors);
154
155         /* ====== Part 2: test derived datatypes (origin derived, target derived) ======== */
156
157         /* init buffers */
158         if (rank != dest) {
159             for (i = 0; i < my_buf_num * OP_COUNT; i++) {
160                 orig_buf[i] = 1;
161                 result_buf[i] = 0;
162             }
163         }
164         else {
165             MPI_Win_lock(MPI_LOCK_SHARED, rank, 0, win);
166             for (i = 0; i < WIN_BUF_NUM * OP_COUNT; i++) {
167                 target_buf[i] = 0;
168             }
169             MPI_Win_unlock(rank, win);
170         }
171
172         MPI_Barrier(MPI_COMM_WORLD);
173
174         MPI_Win_lock_all(0, win);
175         if (rank != dest) {
176             for (i = 0; i < my_buf_num; i++) {
177                 MPI_Get_accumulate(&(orig_buf[i * OP_COUNT]), 1, origin_dtp,
178                                    &(result_buf[i * OP_COUNT]), 1, origin_dtp,
179                                    dest, 0, 1, target_dtp, MPI_SUM, win);
180                 MPI_Win_flush(dest, win);
181             }
182         }
183         MPI_Win_unlock_all(win);
184
185         MPI_Barrier(MPI_COMM_WORLD);
186
187         checkResults(k, &errors);
188
189         /* ====== Part 3: test derived datatypes (origin basic, target derived) ======== */
190
191         /* init buffers */
192         if (rank != dest) {
193             for (i = 0; i < my_buf_num * OP_COUNT; i++) {
194                 orig_buf[i] = 1;
195                 result_buf[i] = 0;
196             }
197         }
198         else {
199             MPI_Win_lock(MPI_LOCK_SHARED, rank, 0, win);
200             for (i = 0; i < WIN_BUF_NUM * OP_COUNT; i++) {
201                 target_buf[i] = 0;
202             }
203             MPI_Win_unlock(rank, win);
204         }
205
206         MPI_Barrier(MPI_COMM_WORLD);
207
208         MPI_Win_lock_all(0, win);
209         if (rank != dest) {
210             for (i = 0; i < my_buf_num; i++) {
211                 MPI_Get_accumulate(&(orig_buf[i * OP_COUNT]), OP_COUNT, MPI_INT,
212                                    &(result_buf[i * OP_COUNT]), OP_COUNT, MPI_INT,
213                                    dest, 0, 1, target_dtp, MPI_SUM, win);
214                 MPI_Win_flush(dest, win);
215             }
216         }
217         MPI_Win_unlock_all(win);
218
219         MPI_Barrier(MPI_COMM_WORLD);
220
221         checkResults(k, &errors);
222
223         /* ====== Part 4: test derived datatypes (origin derived target basic) ======== */
224
225         /* init buffers */
226         if (rank != dest) {
227             for (i = 0; i < my_buf_num * OP_COUNT; i++) {
228                 orig_buf[i] = 1;
229                 result_buf[i] = 0;
230             }
231         }
232         else {
233             MPI_Win_lock(MPI_LOCK_SHARED, rank, 0, win);
234             for (i = 0; i < WIN_BUF_NUM * OP_COUNT; i++) {
235                 target_buf[i] = 0;
236             }
237             MPI_Win_unlock(rank, win);
238         }
239
240         MPI_Barrier(MPI_COMM_WORLD);
241
242         MPI_Win_lock_all(0, win);
243         if (rank != dest) {
244             for (i = 0; i < my_buf_num; i++) {
245                 MPI_Get_accumulate(&(orig_buf[i * OP_COUNT]), 1, origin_dtp,
246                                    &(result_buf[i * OP_COUNT]), 1, origin_dtp,
247                                    dest, 0, OP_COUNT, MPI_INT, MPI_SUM, win);
248                 MPI_Win_flush(dest, win);
249             }
250         }
251         MPI_Win_unlock_all(win);
252
253         MPI_Barrier(MPI_COMM_WORLD);
254
255         checkResults(k, &errors);
256     }
257
258     MPI_Win_free(&win);
259
260     if (rank == origin_am || rank == origin_shm) {
261         MPI_Free_mem(orig_buf);
262         MPI_Free_mem(result_buf);
263     }
264
265     MPI_Type_free(&origin_dtp);
266     MPI_Type_free(&target_dtp);
267
268   exit_test:
269     MPI_Reduce(&errors, &all_errors, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD);
270
271     if (rank == 0 && all_errors == 0)
272         printf(" No Errors\n");
273
274     MPI_Finalize();
275     return 0;
276 }