1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
4 * (C) 2003 by Argonne National Laboratory.
5 * See COPYRIGHT in top-level directory.
14 static char MTEST_Descrip[] = "Mix synchronization types";
17 void delay(double time);
18 void delay(double time)
22 while (MPI_Wtime() - t1 < time);
25 int main(int argc, char *argv[])
28 int crank, csize, source, dest, loop;
29 int *buf0, *buf1, *buf2, *inbuf2, count0, count1, count2, count, i;
34 MTest_Init(&argc, &argv);
36 comm = MPI_COMM_WORLD;
42 count = count0 + count1 + count2 + 2;
44 /* Allocate and initialize the local buffers */
45 buf0 = (int *) malloc(count0 * sizeof(int));
46 buf1 = (int *) malloc(count1 * sizeof(int));
47 buf2 = (int *) malloc(count2 * sizeof(int));
48 inbuf2 = (int *) malloc(count2 * sizeof(int));
49 if (!buf0 || !buf1 || !buf2 || !inbuf2) {
50 fprintf(stderr, "Unable to allocated buf0-2\n");
51 MPI_Abort(MPI_COMM_WORLD, 1);
53 for (i = 0; i < count0; i++)
55 for (i = 0; i < count1; i++)
57 for (i = 0; i < count2; i++)
58 buf2[i] = i + count0 + count1;
60 /* Allocate the window buffer and create the memory window. */
61 MPI_Alloc_mem(count * sizeof(int), MPI_INFO_NULL, &winbuf);
63 fprintf(stderr, "Unable to allocate %d words\n", count);
64 MPI_Abort(MPI_COMM_WORLD, 0);
66 MPI_Win_create(winbuf, count * sizeof(int), sizeof(int), MPI_INFO_NULL, comm, &win);
68 MPI_Comm_size(comm, &csize);
69 MPI_Comm_rank(comm, &crank);
73 for (loop = 0; loop < 2; loop++) {
74 /* Perform several communication operations, mixing synchronization
75 * types. Use multiple communication to avoid the single-operation
76 * optimization that may be present. */
77 MTestPrintfMsg(3, "Beginning loop %d of mixed sync put operations\n", loop);
79 if (crank == source) {
80 MTestPrintfMsg(3, "About to perform exclusive lock\n");
81 MPI_Win_lock(MPI_LOCK_EXCLUSIVE, dest, 0, win);
82 MPI_Put(buf0, count0, MPI_INT, dest, 0, count0, MPI_INT, win);
83 MPI_Put(buf1, count1, MPI_INT, dest, count0, count1, MPI_INT, win);
84 MPI_Put(buf2, count2, MPI_INT, dest, count0 + count1, count2, MPI_INT, win);
85 MPI_Win_unlock(dest, win);
86 MTestPrintfMsg(3, "Released exclusive lock\n");
88 else if (crank == dest) {
89 /* Just delay a bit */
93 /* The synchronization mode can only be changed when the process
94 * memory and public copy are guaranteed to have the same values
95 * (See 11.7, Semantics and Correctness). This barrier ensures that
96 * the lock/unlock completes before the fence call. */
99 MTestPrintfMsg(3, "About to start fence\n");
100 MPI_Win_fence(0, win);
101 if (crank == source) {
102 MPI_Put(buf0, count0, MPI_INT, dest, 1, count0, MPI_INT, win);
103 MPI_Put(buf1, count1, MPI_INT, dest, 1 + count0, count1, MPI_INT, win);
104 MPI_Put(buf2, count2, MPI_INT, dest, 1 + count0 + count1, count2, MPI_INT, win);
106 MPI_Win_fence(0, win);
107 MTestPrintfMsg(3, "Finished with fence sync\n");
111 for (i = 0; i < count0 + count1 + count2; i++) {
112 if (winbuf[1 + i] != i) {
115 fprintf(stderr, "winbuf[%d] = %d, expected %d\n", 1 + i, winbuf[1 + i], i);
122 /* End of test loop */
125 /* Use mixed put and accumulate */
126 for (loop = 0; loop < 2; loop++) {
127 /* Perform several communication operations, mixing synchronization
128 * types. Use multiple communication to avoid the single-operation
129 * optimization that may be present. */
130 MTestPrintfMsg(3, "Beginning loop %d of mixed sync put/acc operations\n", loop);
131 memset(winbuf, 0, count * sizeof(int));
133 if (crank == source) {
134 MPI_Win_lock(MPI_LOCK_EXCLUSIVE, dest, 0, win);
135 MPI_Accumulate(buf0, count0, MPI_INT, dest, 0, count0, MPI_INT, MPI_SUM, win);
136 MPI_Accumulate(buf1, count1, MPI_INT, dest, count0, count1, MPI_INT, MPI_SUM, win);
137 MPI_Put(buf2, count2, MPI_INT, dest, count0 + count1, count2, MPI_INT, win);
138 MPI_Win_unlock(dest, win);
140 else if (crank == dest) {
141 /* Just delay a bit */
144 /* See above - the fence should not start until the unlock completes */
146 MPI_Win_fence(0, win);
147 if (crank == source) {
148 MPI_Accumulate(buf0, count0, MPI_INT, dest, 1, count0, MPI_INT, MPI_REPLACE, win);
149 MPI_Accumulate(buf1, count1, MPI_INT, dest, 1 + count0, count1,
150 MPI_INT, MPI_REPLACE, win);
151 MPI_Put(buf2, count2, MPI_INT, dest, 1 + count0 + count1, count2, MPI_INT, win);
153 MPI_Win_fence(0, win);
157 for (i = 0; i < count0 + count1 + count2; i++) {
158 if (winbuf[1 + i] != i) {
161 fprintf(stderr, "winbuf[%d] = %d, expected %d\n", 1 + i, winbuf[1 + i], i);
168 /* End of test loop */
171 /* Use mixed accumulate and get */
172 for (loop = 0; loop < 2; loop++) {
173 /* Perform several communication operations, mixing synchronization
174 * types. Use multiple communication to avoid the single-operation
175 * optimization that may be present. */
176 MTestPrintfMsg(3, "Beginning loop %d of mixed sync put/get/acc operations\n", loop);
178 if (crank == source) {
179 MPI_Win_lock(MPI_LOCK_EXCLUSIVE, dest, 0, win);
180 MPI_Accumulate(buf0, count0, MPI_INT, dest, 0, count0, MPI_INT, MPI_REPLACE, win);
181 MPI_Put(buf1, count1, MPI_INT, dest, count0, count1, MPI_INT, win);
182 MPI_Get(inbuf2, count2, MPI_INT, dest, count0 + count1, count2, MPI_INT, win);
183 MPI_Win_unlock(dest, win);
185 else if (crank == dest) {
186 /* Just delay a bit */
189 /* See above - the fence should not start until the unlock completes */
191 MPI_Win_fence(0, win);
192 if (crank == source) {
193 MPI_Accumulate(buf0, count0, MPI_INT, dest, 1, count0, MPI_INT, MPI_REPLACE, win);
194 MPI_Put(buf1, count1, MPI_INT, dest, 1 + count0, count1, MPI_INT, win);
195 MPI_Get(inbuf2, count2, MPI_INT, dest, 1 + count0 + count1, count2, MPI_INT, win);
197 MPI_Win_fence(0, win);
201 /* Do the put/accumulate parts */
202 for (i = 0; i < count0 + count1; i++) {
203 if (winbuf[1 + i] != i) {
206 fprintf(stderr, "winbuf[%d] = %d, expected %d\n", 1 + i, winbuf[1 + i], i);
213 /* End of test loop */
216 MTestPrintfMsg(3, "Freeing the window\n");
219 MPI_Free_mem(winbuf);
225 MTest_Finalize(errs);