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