1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
4 * (C) 2015 by Argonne National Laboratory.
5 * See COPYRIGHT in top-level directory.
8 /* This test is going to test the atomicity for "read-modify-write" in GACC
11 /* This test is similiar 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 intergers on the corresponding index
16 * in [0...OP_COUNT-1].
24 #define SHM_BUF_NUM 10000
31 int dest, origin_shm, origin_am;
32 int *orig_buf = NULL, *result_buf = NULL, *target_buf = NULL, *check_buf = NULL;
35 void checkResults(int loop_k, int *errors)
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,
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]) {
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]);
63 MPI_Free_mem(check_buf);
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);
76 MPI_Win_unlock(rank, win);
80 int main(int argc, char *argv[])
83 int errors = 0, all_errors = 0;
85 MPI_Datatype origin_dtp, target_dtp;
87 MPI_Init(&argc, &argv);
89 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
90 MPI_Comm_size(MPI_COMM_WORLD, &size);
92 /* run this test with three processes */
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);
101 /* this works when MPIR_PARAM_CH3_ODD_EVEN_CLIQUES is set */
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;
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);
116 MPI_Win_allocate(sizeof(int) * WIN_BUF_NUM * OP_COUNT, sizeof(int), MPI_INFO_NULL,
117 MPI_COMM_WORLD, &target_buf, &win);
119 for (k = 0; k < LOOP_SIZE; k++) {
121 /* ====== Part 1: test basic datatypes ======== */
125 for (i = 0; i < my_buf_num * OP_COUNT; i++) {
131 MPI_Win_lock(MPI_LOCK_SHARED, rank, 0, win);
132 for (i = 0; i < WIN_BUF_NUM * OP_COUNT; i++) {
135 MPI_Win_unlock(rank, win);
138 MPI_Barrier(MPI_COMM_WORLD);
140 MPI_Win_lock_all(0, win);
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);
149 MPI_Win_unlock_all(win);
151 MPI_Barrier(MPI_COMM_WORLD);
153 checkResults(k, &errors);
155 /* ====== Part 2: test derived datatypes (origin derived, target derived) ======== */
159 for (i = 0; i < my_buf_num * OP_COUNT; i++) {
165 MPI_Win_lock(MPI_LOCK_SHARED, rank, 0, win);
166 for (i = 0; i < WIN_BUF_NUM * OP_COUNT; i++) {
169 MPI_Win_unlock(rank, win);
172 MPI_Barrier(MPI_COMM_WORLD);
174 MPI_Win_lock_all(0, win);
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);
183 MPI_Win_unlock_all(win);
185 MPI_Barrier(MPI_COMM_WORLD);
187 checkResults(k, &errors);
189 /* ====== Part 3: test derived datatypes (origin basic, target derived) ======== */
193 for (i = 0; i < my_buf_num * OP_COUNT; i++) {
199 MPI_Win_lock(MPI_LOCK_SHARED, rank, 0, win);
200 for (i = 0; i < WIN_BUF_NUM * OP_COUNT; i++) {
203 MPI_Win_unlock(rank, win);
206 MPI_Barrier(MPI_COMM_WORLD);
208 MPI_Win_lock_all(0, win);
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);
217 MPI_Win_unlock_all(win);
219 MPI_Barrier(MPI_COMM_WORLD);
221 checkResults(k, &errors);
223 /* ====== Part 4: test derived datatypes (origin derived target basic) ======== */
227 for (i = 0; i < my_buf_num * OP_COUNT; i++) {
233 MPI_Win_lock(MPI_LOCK_SHARED, rank, 0, win);
234 for (i = 0; i < WIN_BUF_NUM * OP_COUNT; i++) {
237 MPI_Win_unlock(rank, win);
240 MPI_Barrier(MPI_COMM_WORLD);
242 MPI_Win_lock_all(0, win);
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);
251 MPI_Win_unlock_all(win);
253 MPI_Barrier(MPI_COMM_WORLD);
255 checkResults(k, &errors);
260 if (rank == origin_am || rank == origin_shm) {
261 MPI_Free_mem(orig_buf);
262 MPI_Free_mem(result_buf);
265 MPI_Type_free(&origin_dtp);
266 MPI_Type_free(&target_dtp);
269 MPI_Reduce(&errors, &all_errors, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD);
271 if (rank == 0 && all_errors == 0)
272 printf(" No Errors\n");