/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
/*
*
* (C) 2010 by Argonne National Laboratory.
* See COPYRIGHT in top-level directory.
*/
#include "mpi.h"
#include <stdio.h>
#include <stdlib.h>
#include "mpitest.h"
/* Test the given operation within a Fence epoch */
#define TEST_FENCE_OP(op_name_, fcn_call_) \
do { \
err = fcn_call_ \
if (err) { \
errs++; \
if (errs < 10) { \
MTestPrintErrorMsg("PROC_NULL to " op_name_, err); \
} \
} \
err = MPI_Win_fence(0, win); \
if (err) { \
errs++; \
if (errs < 10) { \
MTestPrintErrorMsg("Fence after " op_name_, err); \
} \
} \
} while (0)
/* Test the given operation within a passive target epoch */
#define TEST_PT_OP(op_name_, fcn_call_) \
do { \
err = MPI_Win_lock(MPI_LOCK_EXCLUSIVE, MPI_PROC_NULL, 0, win); \
if (err) { \
errs++; \
if (errs < 10) { \
MTestPrintErrorMsg("Lock before" op_name_, err); \
} \
} \
err = fcn_call_ \
if (err) { \
errs++; \
if (errs < 10) { \
MTestPrintErrorMsg("PROC_NULL to " op_name_, err); \
} \
} \
err = MPI_Win_unlock(MPI_PROC_NULL, win); \
if (err) { \
errs++; \
if (errs < 10) { \
MTestPrintErrorMsg("Unlock after " op_name_, err); \
} \
} \
} while (0)
/* Test the given request-based operation within a passive target epoch */
#define TEST_REQ_OP(op_name_, req_, fcn_call_) \
do { \
err = MPI_Win_lock(MPI_LOCK_EXCLUSIVE, MPI_PROC_NULL, 0, win); \
if (err) { \
errs++; \
if (errs < 10) { \
MTestPrintErrorMsg("Lock before" op_name_, err); \
} \
} \
err = fcn_call_ \
if (err) { \
errs++; \
if (errs < 10) { \
MTestPrintErrorMsg("PROC_NULL to " op_name_, err); \
} \
} \
err = MPI_Win_unlock(MPI_PROC_NULL, win); \
if (err) { \
errs++; \
if (errs < 10) { \
MTestPrintErrorMsg("Unlock after " op_name_, err); \
} \
} \
err = MPI_Wait(&req_, MPI_STATUS_IGNORE); \
if (err) { \
errs++; \
if (errs < 10) { \
MTestPrintErrorMsg("Wait after " op_name_, err); \
} \
} \
} while (0)
/*
static char MTEST_Descrip[] = "Test the MPI_PROC_NULL is a valid target";
*/
int main(int argc, char *argv[])
{
int errs = 0, err;
int rank, size;
int *buf, bufsize;
int *result;
int *rmabuf, rsize, rcount;
MPI_Comm comm;
MPI_Win win;
MPI_Request req;
MTest_Init(&argc, &argv);
bufsize = 256 * sizeof(int);
buf = (int *) malloc(bufsize);
if (!buf) {
fprintf(stderr, "Unable to allocated %d bytes\n", bufsize);
MPI_Abort(MPI_COMM_WORLD, 1);
}
result = (int *) malloc(bufsize);
if (!result) {
fprintf(stderr, "Unable to allocated %d bytes\n", bufsize);
MPI_Abort(MPI_COMM_WORLD, 1);
}
rcount = 16;
rsize = rcount * sizeof(int);
rmabuf = (int *) malloc(rsize);
if (!rmabuf) {
fprintf(stderr, "Unable to allocated %d bytes\n", rsize);
MPI_Abort(MPI_COMM_WORLD, 1);
}
/* The following illustrates the use of the routines to
* run through a selection of communicators and datatypes.
* Use subsets of these for tests that do not involve combinations
* of communicators, datatypes, and counts of datatypes */
while (MTestGetIntracommGeneral(&comm, 1, 1)) {
if (comm == MPI_COMM_NULL)
continue;
/* Determine the sender and receiver */
MPI_Comm_rank(comm, &rank);
MPI_Comm_size(comm, &size);
MPI_Win_create(buf, bufsize, sizeof(int), MPI_INFO_NULL, comm, &win);
/* To improve reporting of problems about operations, we
* change the error handler to errors return */
MPI_Win_set_errhandler(win, MPI_ERRORS_RETURN);
/** TEST OPERATIONS USING ACTIVE TARGET (FENCE) SYNCHRONIZATION **/
MPI_Win_fence(0, win);
TEST_FENCE_OP("Put",
MPI_Put(rmabuf, rcount, MPI_INT, MPI_PROC_NULL, 0, rcount, MPI_INT, win);
);
TEST_FENCE_OP("Get",
MPI_Get(rmabuf, rcount, MPI_INT, MPI_PROC_NULL, 0, rcount, MPI_INT, win);
);
TEST_FENCE_OP("Accumulate",
MPI_Accumulate(rmabuf, rcount, MPI_INT, MPI_PROC_NULL,
0, rcount, MPI_INT, MPI_SUM, win);
);
TEST_FENCE_OP("Get accumulate",
MPI_Get_accumulate(rmabuf, rcount, MPI_INT, result,
rcount, MPI_INT, MPI_PROC_NULL, 0,
rcount, MPI_INT, MPI_SUM, win);
);
TEST_FENCE_OP("Fetch and op",
MPI_Fetch_and_op(rmabuf, result, MPI_INT, MPI_PROC_NULL, 0, MPI_SUM, win);
);
TEST_FENCE_OP("Compare and swap",
MPI_Compare_and_swap(rmabuf, &rank, result, MPI_INT, MPI_PROC_NULL, 0, win);
);
/** TEST OPERATIONS USING PASSIVE TARGET SYNCHRONIZATION **/
TEST_PT_OP("Put", MPI_Put(rmabuf, rcount, MPI_INT, MPI_PROC_NULL, 0, rcount, MPI_INT, win);
);
TEST_PT_OP("Get", MPI_Get(rmabuf, rcount, MPI_INT, MPI_PROC_NULL, 0, rcount, MPI_INT, win);
);
TEST_PT_OP("Accumulate",
MPI_Accumulate(rmabuf, rcount, MPI_INT, MPI_PROC_NULL, 0,
rcount, MPI_INT, MPI_SUM, win);
);
TEST_PT_OP("Get accumulate",
MPI_Get_accumulate(rmabuf, rcount, MPI_INT, result, rcount,
MPI_INT, MPI_PROC_NULL, 0, rcount, MPI_INT, MPI_SUM, win);
);
TEST_PT_OP("Fetch and op",
MPI_Fetch_and_op(rmabuf, result, MPI_INT, MPI_PROC_NULL, 0, MPI_SUM, win);
);
TEST_PT_OP("Compare and swap",
MPI_Compare_and_swap(rmabuf, &rank, result, MPI_INT, MPI_PROC_NULL, 0, win);
);
/** TEST REQUEST-BASED OPERATIONS (PASSIVE TARGET ONLY) **/
TEST_REQ_OP("Rput", req,
MPI_Rput(rmabuf, rcount, MPI_INT, MPI_PROC_NULL, 0, rcount, MPI_INT, win, &req);
);
TEST_REQ_OP("Rget", req,
MPI_Rget(rmabuf, rcount, MPI_INT, MPI_PROC_NULL, 0, rcount, MPI_INT, win, &req);
);
TEST_REQ_OP("Raccumulate", req,
MPI_Raccumulate(rmabuf, rcount, MPI_INT, MPI_PROC_NULL, 0,
rcount, MPI_INT, MPI_SUM, win, &req);
);
TEST_REQ_OP("Rget_accumulate", req,
MPI_Rget_accumulate(rmabuf, rcount, MPI_INT, result,
rcount, MPI_INT, MPI_PROC_NULL, 0,
rcount, MPI_INT, MPI_SUM, win, &req);
);
MPI_Win_free(&win);
MTestFreeComm(&comm);
}
free(result);
free(buf);
free(rmabuf);
MTest_Finalize(errs);
MPI_Finalize();
return 0;
}