1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
3 * (C) 2015 by Argonne National Laboratory.
4 * See COPYRIGHT in top-level directory.
7 /* This test is going to test atomic GET (GACC/FOP+MPI_NO_OP).
9 * There are totally three processes involved in this test. Both
10 * rank 1 and rank 2 issue RMA operations to rank 0. Rank 2 issues
11 * atomic PUT (ACC+MPI_REPLACE), whereas rank 1 issues atomic
12 * GET (GACC/FOP+MPI_NO_OP). The datatype used in the test is
13 * pair-type. The initial value of pair-type data in origin buffer
14 * of atomic PUT is set so that the two basic values equal with
15 * each other. Due to the atomicity of GET, the expected resulting
16 * data should also have equivalent basic values. */
26 typedef struct pair_struct {
31 int main(int argc, char *argv[])
35 int errors = 0, curr_errors = 0;
37 pair_struct_t *tar_buf = NULL;
38 pair_struct_t *orig_buf = NULL;
39 pair_struct_t *result_buf = NULL;
41 /* This test needs to work with 3 processes. */
43 MPI_Init(&argc, &argv);
45 MPI_Comm_size(MPI_COMM_WORLD, &nproc);
46 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
48 MPI_Alloc_mem(sizeof(pair_struct_t) * DATA_SIZE, MPI_INFO_NULL, &orig_buf);
49 MPI_Alloc_mem(sizeof(pair_struct_t) * DATA_SIZE, MPI_INFO_NULL, &result_buf);
51 MPI_Win_allocate(sizeof(pair_struct_t) * DATA_SIZE, sizeof(pair_struct_t),
52 MPI_INFO_NULL, MPI_COMM_WORLD, &tar_buf, &win);
54 for (j = 0; j < LOOP * 6; j++) {
56 MPI_Win_lock(MPI_LOCK_EXCLUSIVE, rank, 0, win);
59 for (i = 0; i < DATA_SIZE; i++) {
62 result_buf[i].a = 0.0;
66 MPI_Win_unlock(rank, win);
68 MPI_Barrier(MPI_COMM_WORLD);
70 MPI_Win_fence(0, win);
74 /* Work with FOP test (Test #1 to Test #2) */
75 for (i = 0; i < OPS_NUM; i++) {
77 int curr_val = j * OPS_NUM + i;
78 orig_buf[0].a = (long double) (curr_val);
79 orig_buf[0].b = curr_val;
81 MPI_Accumulate(orig_buf, 1, MPI_LONG_DOUBLE_INT,
82 0, 0, 1, MPI_LONG_DOUBLE_INT, MPI_REPLACE, win);
86 /* Work with GACC test (Test #3 to Test #6) */
87 for (i = 0; i < OPS_NUM / GACC_SZ; i++) {
89 for (k = 0; k < GACC_SZ; k++) {
90 int curr_val = j * OPS_NUM + i * GACC_SZ + k;
91 orig_buf[k].a = (long double) (curr_val);
92 orig_buf[k].b = curr_val;
95 MPI_Accumulate(orig_buf, GACC_SZ, MPI_LONG_DOUBLE_INT,
96 0, 0, GACC_SZ, MPI_LONG_DOUBLE_INT, MPI_REPLACE, win);
100 else if (rank == 1) {
101 /* equals to an atomic GET */
103 for (i = 0; i < DATA_SIZE; i++) {
104 /* Test #1: FOP + MPI_NO_OP */
105 MPI_Fetch_and_op(orig_buf, &(result_buf[i]), MPI_LONG_DOUBLE_INT,
106 0, 0, MPI_NO_OP, win);
109 else if (j < 2 * LOOP) {
110 for (i = 0; i < DATA_SIZE; i++) {
111 /* Test #2: FOP + MPI_NO_OP + NULL origin buffer address */
112 MPI_Fetch_and_op(NULL, &(result_buf[i]), MPI_LONG_DOUBLE_INT,
113 0, 0, MPI_NO_OP, win);
116 else if (j < 3 * LOOP) {
117 for (i = 0; i < DATA_SIZE / GACC_SZ; i++) {
118 /* Test #3: GACC + MPI_NO_OP */
119 MPI_Get_accumulate(orig_buf, GACC_SZ, MPI_LONG_DOUBLE_INT,
120 &(result_buf[i * GACC_SZ]), GACC_SZ, MPI_LONG_DOUBLE_INT,
121 0, 0, GACC_SZ, MPI_LONG_DOUBLE_INT, MPI_NO_OP, win);
124 else if (j < 4 * LOOP) {
125 for (i = 0; i < DATA_SIZE / GACC_SZ; i++) {
126 /* Test #4: GACC + MPI_NO_OP + NULL origin buffer address */
127 MPI_Get_accumulate(NULL, GACC_SZ, MPI_LONG_DOUBLE_INT,
128 &(result_buf[i * GACC_SZ]), GACC_SZ, MPI_LONG_DOUBLE_INT,
129 0, 0, GACC_SZ, MPI_LONG_DOUBLE_INT, MPI_NO_OP, win);
132 else if (j < 5 * LOOP) {
133 for (i = 0; i < DATA_SIZE / GACC_SZ; i++) {
134 /* Test #5: GACC + MPI_NO_OP + zero origin count */
135 MPI_Get_accumulate(orig_buf, 0, MPI_LONG_DOUBLE_INT,
136 &(result_buf[i * GACC_SZ]), GACC_SZ, MPI_LONG_DOUBLE_INT,
137 0, 0, GACC_SZ, MPI_LONG_DOUBLE_INT, MPI_NO_OP, win);
140 else if (j < 6 * LOOP) {
141 for (i = 0; i < DATA_SIZE / GACC_SZ; i++) {
142 /* Test #5: GACC + MPI_NO_OP + NULL origin datatype */
143 MPI_Get_accumulate(orig_buf, GACC_SZ, MPI_DATATYPE_NULL,
144 &(result_buf[i * GACC_SZ]), GACC_SZ, MPI_LONG_DOUBLE_INT,
145 0, 0, GACC_SZ, MPI_LONG_DOUBLE_INT, MPI_NO_OP, win);
150 MPI_Win_fence(0, win);
154 for (i = 0; i < DATA_SIZE; i++) {
155 if (result_buf[i].a != (long double) (result_buf[i].b)) {
156 if (curr_errors < 10) {
157 printf("LOOP %d: result_buf[%d].a = %Lf, result_buf[%d].b = %d\n",
158 j, i, result_buf[i].a, i, result_buf[i].b);
166 errors += curr_errors;
173 MPI_Free_mem(orig_buf);
174 MPI_Free_mem(result_buf);
178 printf(" No Errors\n");