1 /*
2  * Copyright (C) by Argonne National Laboratory
3  *     See COPYRIGHT in top-level directory
4  */
5 
6 #include <mpi.h>
7 #include <stdio.h>
8 #include "mpitest.h"
9 
10 #define ITER 100
11 
main(int argc,char * argv[])12 int main(int argc, char *argv[])
13 {
14     int rank, nproc, i;
15     int errors = 0, all_errors = 0;
16     int *buf;
17     MPI_Win window;
18 
19     MTest_Init(&argc, &argv);
20     MPI_Comm_rank(MPI_COMM_WORLD, &rank);
21     MPI_Comm_size(MPI_COMM_WORLD, &nproc);
22 
23     if (nproc < 2) {
24         if (rank == 0)
25             printf("Error: must be run with two or more processes\n");
26         MPI_Abort(MPI_COMM_WORLD, 1);
27     }
28 
29     /** Create using MPI_Win_create() **/
30 
31     if (rank == 0) {
32         MPI_Alloc_mem(sizeof(int), MPI_INFO_NULL, &buf);
33         *buf = nproc - 1;
34     } else
35         buf = NULL;
36 
37     MPI_Win_create(buf, sizeof(int) * (rank == 0), 1, MPI_INFO_NULL, MPI_COMM_WORLD, &window);
38 
39     /* Test flush of an empty epoch */
40     MPI_Win_lock(MPI_LOCK_SHARED, 0, 0, window);
41     MPI_Win_flush_all(window);
42     MPI_Win_unlock(0, window);
43 
44     MPI_Barrier(MPI_COMM_WORLD);
45 
46     /* Test third-party communication, through rank 0. */
47     MPI_Win_lock(MPI_LOCK_SHARED, 0, 0, window);
48 
49     for (i = 0; i < ITER; i++) {
50         int val = -1, exp = -1;
51 
52         /* Processes form a ring.  Process 0 starts first, then passes a token
53          * to the right.  Each process, in turn, performs third-party
54          * communication via process 0's window. */
55         if (rank > 0) {
56             MPI_Recv(NULL, 0, MPI_BYTE, rank - 1, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
57         }
58 
59         MPI_Get_accumulate(&rank, 1, MPI_INT, &val, 1, MPI_INT, 0, 0, 1, MPI_INT, MPI_REPLACE,
60                            window);
61         MPI_Win_flush(0, window);
62 
63         exp = (rank + nproc - 1) % nproc;
64 
65         if (val != exp) {
66             printf("%d - Got %d, expected %d\n", rank, val, exp);
67             errors++;
68         }
69 
70         if (rank < nproc - 1) {
71             MPI_Send(NULL, 0, MPI_BYTE, rank + 1, 0, MPI_COMM_WORLD);
72         }
73 
74         MPI_Barrier(MPI_COMM_WORLD);
75     }
76 
77     MPI_Win_unlock(0, window);
78 
79     MPI_Win_free(&window);
80     if (buf)
81         MPI_Free_mem(buf);
82 
83     MTest_Finalize(errors);
84 
85     return MTestReturnValue(all_errors);
86 }
87