/* -*- 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 #include #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; }