|
Packit |
0848f5 |
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
|
|
Packit |
0848f5 |
/*
|
|
Packit |
0848f5 |
*
|
|
Packit |
0848f5 |
* (C) 2003 by Argonne National Laboratory.
|
|
Packit |
0848f5 |
* See COPYRIGHT in top-level directory.
|
|
Packit |
0848f5 |
*/
|
|
Packit |
0848f5 |
#include "mpi.h"
|
|
Packit |
0848f5 |
#include <stdio.h>
|
|
Packit |
0848f5 |
#include <stdlib.h>
|
|
Packit |
0848f5 |
#include "mpitest.h"
|
|
Packit |
0848f5 |
#include <string.h>
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/*
|
|
Packit |
0848f5 |
static char MTEST_Descrip[] = "Mix synchronization types";
|
|
Packit |
0848f5 |
*/
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
void delay(double time);
|
|
Packit |
0848f5 |
void delay(double time)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
double t1;
|
|
Packit |
0848f5 |
t1 = MPI_Wtime();
|
|
Packit |
0848f5 |
while (MPI_Wtime() - t1 < time);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
int main(int argc, char *argv[])
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
int errs = 0;
|
|
Packit |
0848f5 |
int crank, csize, source, dest, loop;
|
|
Packit |
0848f5 |
int *buf0, *buf1, *buf2, *inbuf2, count0, count1, count2, count, i;
|
|
Packit |
0848f5 |
MPI_Comm comm;
|
|
Packit |
0848f5 |
MPI_Win win;
|
|
Packit |
0848f5 |
int *winbuf;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
MTest_Init(&argc, &argv);
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
comm = MPI_COMM_WORLD;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
count0 = 1000;
|
|
Packit |
0848f5 |
count1 = 1;
|
|
Packit |
0848f5 |
count2 = 100;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
count = count0 + count1 + count2 + 2;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* Allocate and initialize the local buffers */
|
|
Packit |
0848f5 |
buf0 = (int *) malloc(count0 * sizeof(int));
|
|
Packit |
0848f5 |
buf1 = (int *) malloc(count1 * sizeof(int));
|
|
Packit |
0848f5 |
buf2 = (int *) malloc(count2 * sizeof(int));
|
|
Packit |
0848f5 |
inbuf2 = (int *) malloc(count2 * sizeof(int));
|
|
Packit |
0848f5 |
if (!buf0 || !buf1 || !buf2 || !inbuf2) {
|
|
Packit |
0848f5 |
fprintf(stderr, "Unable to allocated buf0-2\n");
|
|
Packit |
0848f5 |
MPI_Abort(MPI_COMM_WORLD, 1);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
for (i = 0; i < count0; i++)
|
|
Packit |
0848f5 |
buf0[i] = i;
|
|
Packit |
0848f5 |
for (i = 0; i < count1; i++)
|
|
Packit |
0848f5 |
buf1[i] = i + count0;
|
|
Packit |
0848f5 |
for (i = 0; i < count2; i++)
|
|
Packit |
0848f5 |
buf2[i] = i + count0 + count1;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* Allocate the window buffer and create the memory window. */
|
|
Packit |
0848f5 |
MPI_Alloc_mem(count * sizeof(int), MPI_INFO_NULL, &winbuf);
|
|
Packit |
0848f5 |
if (!winbuf) {
|
|
Packit |
0848f5 |
fprintf(stderr, "Unable to allocate %d words\n", count);
|
|
Packit |
0848f5 |
MPI_Abort(MPI_COMM_WORLD, 0);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
MPI_Win_create(winbuf, count * sizeof(int), sizeof(int), MPI_INFO_NULL, comm, &win);
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
MPI_Comm_size(comm, &csize);
|
|
Packit |
0848f5 |
MPI_Comm_rank(comm, &crank);
|
|
Packit |
0848f5 |
dest = 0;
|
|
Packit |
0848f5 |
source = 1;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
for (loop = 0; loop < 2; loop++) {
|
|
Packit |
0848f5 |
/* Perform several communication operations, mixing synchronization
|
|
Packit |
0848f5 |
* types. Use multiple communication to avoid the single-operation
|
|
Packit |
0848f5 |
* optimization that may be present. */
|
|
Packit |
0848f5 |
MTestPrintfMsg(3, "Beginning loop %d of mixed sync put operations\n", loop);
|
|
Packit |
0848f5 |
MPI_Barrier(comm);
|
|
Packit |
0848f5 |
if (crank == source) {
|
|
Packit |
0848f5 |
MTestPrintfMsg(3, "About to perform exclusive lock\n");
|
|
Packit |
0848f5 |
MPI_Win_lock(MPI_LOCK_EXCLUSIVE, dest, 0, win);
|
|
Packit |
0848f5 |
MPI_Put(buf0, count0, MPI_INT, dest, 0, count0, MPI_INT, win);
|
|
Packit |
0848f5 |
MPI_Put(buf1, count1, MPI_INT, dest, count0, count1, MPI_INT, win);
|
|
Packit |
0848f5 |
MPI_Put(buf2, count2, MPI_INT, dest, count0 + count1, count2, MPI_INT, win);
|
|
Packit |
0848f5 |
MPI_Win_unlock(dest, win);
|
|
Packit |
0848f5 |
MTestPrintfMsg(3, "Released exclusive lock\n");
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
else if (crank == dest) {
|
|
Packit |
0848f5 |
/* Just delay a bit */
|
|
Packit |
0848f5 |
delay(0.0001);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* The synchronization mode can only be changed when the process
|
|
Packit |
0848f5 |
* memory and public copy are guaranteed to have the same values
|
|
Packit |
0848f5 |
* (See 11.7, Semantics and Correctness). This barrier ensures that
|
|
Packit |
0848f5 |
* the lock/unlock completes before the fence call. */
|
|
Packit |
0848f5 |
MPI_Barrier(comm);
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
MTestPrintfMsg(3, "About to start fence\n");
|
|
Packit |
0848f5 |
MPI_Win_fence(0, win);
|
|
Packit |
0848f5 |
if (crank == source) {
|
|
Packit |
0848f5 |
MPI_Put(buf0, count0, MPI_INT, dest, 1, count0, MPI_INT, win);
|
|
Packit |
0848f5 |
MPI_Put(buf1, count1, MPI_INT, dest, 1 + count0, count1, MPI_INT, win);
|
|
Packit |
0848f5 |
MPI_Put(buf2, count2, MPI_INT, dest, 1 + count0 + count1, count2, MPI_INT, win);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
MPI_Win_fence(0, win);
|
|
Packit |
0848f5 |
MTestPrintfMsg(3, "Finished with fence sync\n");
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* Check results */
|
|
Packit |
0848f5 |
if (crank == dest) {
|
|
Packit |
0848f5 |
for (i = 0; i < count0 + count1 + count2; i++) {
|
|
Packit |
0848f5 |
if (winbuf[1 + i] != i) {
|
|
Packit |
0848f5 |
errs++;
|
|
Packit |
0848f5 |
if (errs < 10) {
|
|
Packit |
0848f5 |
fprintf(stderr, "winbuf[%d] = %d, expected %d\n", 1 + i, winbuf[1 + i], i);
|
|
Packit |
0848f5 |
fflush(stderr);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* End of test loop */
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* Use mixed put and accumulate */
|
|
Packit |
0848f5 |
for (loop = 0; loop < 2; loop++) {
|
|
Packit |
0848f5 |
/* Perform several communication operations, mixing synchronization
|
|
Packit |
0848f5 |
* types. Use multiple communication to avoid the single-operation
|
|
Packit |
0848f5 |
* optimization that may be present. */
|
|
Packit |
0848f5 |
MTestPrintfMsg(3, "Begining loop %d of mixed sync put/acc operations\n", loop);
|
|
Packit |
0848f5 |
memset(winbuf, 0, count * sizeof(int));
|
|
Packit |
0848f5 |
MPI_Barrier(comm);
|
|
Packit |
0848f5 |
if (crank == source) {
|
|
Packit |
0848f5 |
MPI_Win_lock(MPI_LOCK_EXCLUSIVE, dest, 0, win);
|
|
Packit |
0848f5 |
MPI_Accumulate(buf0, count0, MPI_INT, dest, 0, count0, MPI_INT, MPI_SUM, win);
|
|
Packit |
0848f5 |
MPI_Accumulate(buf1, count1, MPI_INT, dest, count0, count1, MPI_INT, MPI_SUM, win);
|
|
Packit |
0848f5 |
MPI_Put(buf2, count2, MPI_INT, dest, count0 + count1, count2, MPI_INT, win);
|
|
Packit |
0848f5 |
MPI_Win_unlock(dest, win);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
else if (crank == dest) {
|
|
Packit |
0848f5 |
/* Just delay a bit */
|
|
Packit |
0848f5 |
delay(0.0001);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
/* See above - the fence should not start until the unlock completes */
|
|
Packit |
0848f5 |
MPI_Barrier(comm);
|
|
Packit |
0848f5 |
MPI_Win_fence(0, win);
|
|
Packit |
0848f5 |
if (crank == source) {
|
|
Packit |
0848f5 |
MPI_Accumulate(buf0, count0, MPI_INT, dest, 1, count0, MPI_INT, MPI_REPLACE, win);
|
|
Packit |
0848f5 |
MPI_Accumulate(buf1, count1, MPI_INT, dest, 1 + count0, count1,
|
|
Packit |
0848f5 |
MPI_INT, MPI_REPLACE, win);
|
|
Packit |
0848f5 |
MPI_Put(buf2, count2, MPI_INT, dest, 1 + count0 + count1, count2, MPI_INT, win);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
MPI_Win_fence(0, win);
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* Check results */
|
|
Packit |
0848f5 |
if (crank == dest) {
|
|
Packit |
0848f5 |
for (i = 0; i < count0 + count1 + count2; i++) {
|
|
Packit |
0848f5 |
if (winbuf[1 + i] != i) {
|
|
Packit |
0848f5 |
errs++;
|
|
Packit |
0848f5 |
if (errs < 10) {
|
|
Packit |
0848f5 |
fprintf(stderr, "winbuf[%d] = %d, expected %d\n", 1 + i, winbuf[1 + i], i);
|
|
Packit |
0848f5 |
fflush(stderr);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* End of test loop */
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* Use mixed accumulate and get */
|
|
Packit |
0848f5 |
for (loop = 0; loop < 2; loop++) {
|
|
Packit |
0848f5 |
/* Perform several communication operations, mixing synchronization
|
|
Packit |
0848f5 |
* types. Use multiple communication to avoid the single-operation
|
|
Packit |
0848f5 |
* optimization that may be present. */
|
|
Packit |
0848f5 |
MTestPrintfMsg(3, "Begining loop %d of mixed sync put/get/acc operations\n", loop);
|
|
Packit |
0848f5 |
MPI_Barrier(comm);
|
|
Packit |
0848f5 |
if (crank == source) {
|
|
Packit |
0848f5 |
MPI_Win_lock(MPI_LOCK_EXCLUSIVE, dest, 0, win);
|
|
Packit |
0848f5 |
MPI_Accumulate(buf0, count0, MPI_INT, dest, 0, count0, MPI_INT, MPI_REPLACE, win);
|
|
Packit |
0848f5 |
MPI_Put(buf1, count1, MPI_INT, dest, count0, count1, MPI_INT, win);
|
|
Packit |
0848f5 |
MPI_Get(inbuf2, count2, MPI_INT, dest, count0 + count1, count2, MPI_INT, win);
|
|
Packit |
0848f5 |
MPI_Win_unlock(dest, win);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
else if (crank == dest) {
|
|
Packit |
0848f5 |
/* Just delay a bit */
|
|
Packit |
0848f5 |
delay(0.0001);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
/* See above - the fence should not start until the unlock completes */
|
|
Packit |
0848f5 |
MPI_Barrier(comm);
|
|
Packit |
0848f5 |
MPI_Win_fence(0, win);
|
|
Packit |
0848f5 |
if (crank == source) {
|
|
Packit |
0848f5 |
MPI_Accumulate(buf0, count0, MPI_INT, dest, 1, count0, MPI_INT, MPI_REPLACE, win);
|
|
Packit |
0848f5 |
MPI_Put(buf1, count1, MPI_INT, dest, 1 + count0, count1, MPI_INT, win);
|
|
Packit |
0848f5 |
MPI_Get(inbuf2, count2, MPI_INT, dest, 1 + count0 + count1, count2, MPI_INT, win);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
MPI_Win_fence(0, win);
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* Check results */
|
|
Packit |
0848f5 |
if (crank == dest) {
|
|
Packit |
0848f5 |
/* Do the put/accumulate parts */
|
|
Packit |
0848f5 |
for (i = 0; i < count0 + count1; i++) {
|
|
Packit |
0848f5 |
if (winbuf[1 + i] != i) {
|
|
Packit |
0848f5 |
errs++;
|
|
Packit |
0848f5 |
if (errs < 10) {
|
|
Packit |
0848f5 |
fprintf(stderr, "winbuf[%d] = %d, expected %d\n", 1 + i, winbuf[1 + i], i);
|
|
Packit |
0848f5 |
fflush(stderr);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* End of test loop */
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
MTestPrintfMsg(3, "Freeing the window\n");
|
|
Packit |
0848f5 |
MPI_Barrier(comm);
|
|
Packit |
0848f5 |
MPI_Win_free(&win);
|
|
Packit |
0848f5 |
MPI_Free_mem(winbuf);
|
|
Packit |
0848f5 |
free(buf0);
|
|
Packit |
0848f5 |
free(buf1);
|
|
Packit |
0848f5 |
free(buf2);
|
|
Packit |
0848f5 |
free(inbuf2);
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
MTest_Finalize(errs);
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
MPI_Finalize();
|
|
Packit |
0848f5 |
return 0;
|
|
Packit |
0848f5 |
}
|