/* -*- Mode: C; c-basic-offset:4 ; -*- */ /* * * (C) 2012 by Argonne National Laboratory. * See COPYRIGHT in top-level directory. */ #include #include #include #include #include "mpitest.h" #include "squelch.h" #define ITER 100 #define COUNT 5 #if defined (GACC_TYPE_SHORT) # define TYPE_C short # define TYPE_MPI_BASE MPI_SHORT # define TYPE_FMT "%d" #elif defined (GACC_TYPE_LONG) # define TYPE_C long # define TYPE_MPI_BASE MPI_LONG # define TYPE_FMT "%ld" #elif defined (GACC_TYPE_DOUBLE) # define TYPE_C double # define TYPE_MPI_BASE MPI_DOUBLE # define TYPE_FMT "%f" #else # define TYPE_C int # define TYPE_MPI_BASE MPI_INT # define TYPE_FMT "%d" #endif #if defined(GACC_TYPE_DERIVED) # define TYPE_MPI derived_type #else # define TYPE_MPI TYPE_MPI_BASE #endif void reset_bufs(TYPE_C * win_ptr, TYPE_C * res_ptr, TYPE_C * val_ptr, TYPE_C value, MPI_Win win) { int rank, nproc, i; MPI_Barrier(MPI_COMM_WORLD); MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &nproc); MPI_Win_lock(MPI_LOCK_EXCLUSIVE, rank, 0, win); memset(win_ptr, 0, sizeof(TYPE_C) * nproc * COUNT); MPI_Win_unlock(rank, win); memset(res_ptr, -1, sizeof(TYPE_C) * nproc * COUNT); for (i = 0; i < COUNT; i++) val_ptr[i] = value; MPI_Barrier(MPI_COMM_WORLD); } int main(int argc, char **argv) { int i, rank, nproc; int errors = 0, all_errors = 0; TYPE_C *win_ptr, *res_ptr, *val_ptr; MPI_Win win; #if defined (GACC_TYPE_DERIVED) MPI_Datatype derived_type; #endif MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &nproc); win_ptr = malloc(sizeof(TYPE_C) * nproc * COUNT); res_ptr = malloc(sizeof(TYPE_C) * nproc * COUNT); val_ptr = malloc(sizeof(TYPE_C) * COUNT); #if defined (GACC_TYPE_DERIVED) MPI_Type_contiguous(1, TYPE_MPI_BASE, &derived_type); MPI_Type_commit(&derived_type); #endif MPI_Win_create(win_ptr, sizeof(TYPE_C) * nproc * COUNT, sizeof(TYPE_C), MPI_INFO_NULL, MPI_COMM_WORLD, &win); /* Test self communication */ reset_bufs(win_ptr, res_ptr, val_ptr, 1, win); for (i = 0; i < ITER; i++) { MPI_Win_lock(MPI_LOCK_EXCLUSIVE, rank, 0, win); MPI_Get_accumulate(val_ptr, COUNT, TYPE_MPI, res_ptr, COUNT, TYPE_MPI, rank, 0, COUNT, TYPE_MPI, MPI_SUM, win); MPI_Win_unlock(rank, win); } MPI_Win_lock(MPI_LOCK_EXCLUSIVE, rank, 0, win); for (i = 0; i < COUNT; i++) { if (win_ptr[i] != ITER) { SQUELCH(printf("%d->%d -- SELF[%d]: expected " TYPE_FMT ", got " TYPE_FMT "\n", rank, rank, i, (TYPE_C) ITER, win_ptr[i]);); errors++; } } MPI_Win_unlock(rank, win); /* Test neighbor communication */ reset_bufs(win_ptr, res_ptr, val_ptr, 1, win); for (i = 0; i < ITER; i++) { MPI_Win_lock(MPI_LOCK_EXCLUSIVE, (rank + 1) % nproc, 0, win); MPI_Get_accumulate(val_ptr, COUNT, TYPE_MPI, res_ptr, COUNT, TYPE_MPI, (rank + 1) % nproc, 0, COUNT, TYPE_MPI, MPI_SUM, win); MPI_Win_unlock((rank + 1) % nproc, win); } MPI_Barrier(MPI_COMM_WORLD); MPI_Win_lock(MPI_LOCK_EXCLUSIVE, rank, 0, win); for (i = 0; i < COUNT; i++) { if (win_ptr[i] != ITER) { SQUELCH(printf("%d->%d -- NEIGHBOR[%d]: expected " TYPE_FMT ", got " TYPE_FMT "\n", (rank + 1) % nproc, rank, i, (TYPE_C) ITER, win_ptr[i]);); errors++; } } MPI_Win_unlock(rank, win); /* Test contention */ reset_bufs(win_ptr, res_ptr, val_ptr, 1, win); if (rank != 0) { for (i = 0; i < ITER; i++) { MPI_Win_lock(MPI_LOCK_EXCLUSIVE, 0, 0, win); MPI_Get_accumulate(val_ptr, COUNT, TYPE_MPI, res_ptr, COUNT, TYPE_MPI, 0, 0, COUNT, TYPE_MPI, MPI_SUM, win); MPI_Win_unlock(0, win); } } MPI_Barrier(MPI_COMM_WORLD); MPI_Win_lock(MPI_LOCK_EXCLUSIVE, rank, 0, win); if (rank == 0 && nproc > 1) { for (i = 0; i < COUNT; i++) { if (win_ptr[i] != ITER * (nproc - 1)) { SQUELCH(printf("*->%d - CONTENTION[%d]: expected=" TYPE_FMT " val=" TYPE_FMT "\n", rank, i, (TYPE_C) ITER * (nproc - 1), win_ptr[i]);); errors++; } } } MPI_Win_unlock(rank, win); /* Test all-to-all communication (fence) */ reset_bufs(win_ptr, res_ptr, val_ptr, rank, win); for (i = 0; i < ITER; i++) { int j; MPI_Win_fence(MPI_MODE_NOPRECEDE, win); for (j = 0; j < nproc; j++) { MPI_Get_accumulate(val_ptr, COUNT, TYPE_MPI, &res_ptr[j * COUNT], COUNT, TYPE_MPI, j, rank * COUNT, COUNT, TYPE_MPI, MPI_SUM, win); } MPI_Win_fence(MPI_MODE_NOSUCCEED, win); MPI_Barrier(MPI_COMM_WORLD); for (j = 0; j < nproc; j++) { int c; for (c = 0; c < COUNT; c++) { if (res_ptr[j * COUNT + c] != i * rank) { SQUELCH(printf ("%d->%d -- ALL-TO-ALL (FENCE) [%d]: iter %d, expected result " TYPE_FMT ", got " TYPE_FMT "\n", rank, j, c, i, (TYPE_C) i * rank, res_ptr[j * COUNT + c]);); errors++; } } } } MPI_Barrier(MPI_COMM_WORLD); MPI_Win_lock(MPI_LOCK_EXCLUSIVE, rank, 0, win); for (i = 0; i < nproc; i++) { int c; for (c = 0; c < COUNT; c++) { if (win_ptr[i * COUNT + c] != ITER * i) { SQUELCH(printf ("%d->%d -- ALL-TO-ALL (FENCE): expected " TYPE_FMT ", got " TYPE_FMT "\n", i, rank, (TYPE_C) ITER * i, win_ptr[i * COUNT + c]);); errors++; } } } MPI_Win_unlock(rank, win); /* Test all-to-all communication (lock-all) */ reset_bufs(win_ptr, res_ptr, val_ptr, rank, win); for (i = 0; i < ITER; i++) { int j; MPI_Win_lock_all(0, win); for (j = 0; j < nproc; j++) { MPI_Get_accumulate(val_ptr, COUNT, TYPE_MPI, &res_ptr[j * COUNT], COUNT, TYPE_MPI, j, rank * COUNT, COUNT, TYPE_MPI, MPI_SUM, win); } MPI_Win_unlock_all(win); MPI_Barrier(MPI_COMM_WORLD); for (j = 0; j < nproc; j++) { int c; for (c = 0; c < COUNT; c++) { if (res_ptr[j * COUNT + c] != i * rank) { SQUELCH(printf ("%d->%d -- ALL-TO-ALL (LOCK-ALL) [%d]: iter %d, expected result " TYPE_FMT ", got " TYPE_FMT "\n", rank, j, c, i, (TYPE_C) i * rank, res_ptr[j * COUNT + c]);); errors++; } } } } MPI_Barrier(MPI_COMM_WORLD); MPI_Win_lock(MPI_LOCK_EXCLUSIVE, rank, 0, win); for (i = 0; i < nproc; i++) { int c; for (c = 0; c < COUNT; c++) { if (win_ptr[i * COUNT + c] != ITER * i) { SQUELCH(printf ("%d->%d -- ALL-TO-ALL (LOCK-ALL): expected " TYPE_FMT ", got " TYPE_FMT "\n", i, rank, (TYPE_C) ITER * i, win_ptr[i * COUNT + c]);); errors++; } } } MPI_Win_unlock(rank, win); /* Test all-to-all communication (lock-all+flush) */ reset_bufs(win_ptr, res_ptr, val_ptr, rank, win); for (i = 0; i < ITER; i++) { int j; MPI_Win_lock_all(0, win); for (j = 0; j < nproc; j++) { MPI_Get_accumulate(val_ptr, COUNT, TYPE_MPI, &res_ptr[j * COUNT], COUNT, TYPE_MPI, j, rank * COUNT, COUNT, TYPE_MPI, MPI_SUM, win); MPI_Win_flush(j, win); } MPI_Win_unlock_all(win); MPI_Barrier(MPI_COMM_WORLD); for (j = 0; j < nproc; j++) { int c; for (c = 0; c < COUNT; c++) { if (res_ptr[j * COUNT + c] != i * rank) { SQUELCH(printf ("%d->%d -- ALL-TO-ALL (LOCK-ALL+FLUSH) [%d]: iter %d, expected result " TYPE_FMT ", got " TYPE_FMT "\n", rank, j, c, i, (TYPE_C) i * rank, res_ptr[j * COUNT + c]);); errors++; } } } } MPI_Barrier(MPI_COMM_WORLD); MPI_Win_lock(MPI_LOCK_EXCLUSIVE, rank, 0, win); for (i = 0; i < nproc; i++) { int c; for (c = 0; c < COUNT; c++) { if (win_ptr[i * COUNT + c] != ITER * i) { SQUELCH(printf ("%d->%d -- ALL-TO-ALL (LOCK-ALL+FLUSH): expected " TYPE_FMT ", got " TYPE_FMT "\n", i, rank, (TYPE_C) ITER * i, win_ptr[i * COUNT + c]);); errors++; } } } MPI_Win_unlock(rank, win); /* Test NO_OP (neighbor communication) */ reset_bufs(win_ptr, res_ptr, val_ptr, 1, win); MPI_Win_lock(MPI_LOCK_EXCLUSIVE, rank, 0, win); for (i = 0; i < COUNT * nproc; i++) win_ptr[i] = (TYPE_C) rank; MPI_Win_unlock(rank, win); MPI_Barrier(MPI_COMM_WORLD); for (i = 0; i < ITER; i++) { int j, target = (rank + 1) % nproc; /* Test: origin_buf = NULL */ MPI_Win_lock(MPI_LOCK_EXCLUSIVE, target, 0, win); MPI_Get_accumulate(NULL, COUNT, TYPE_MPI, res_ptr, COUNT, TYPE_MPI, target, 0, COUNT, TYPE_MPI, MPI_NO_OP, win); MPI_Win_unlock(target, win); for (j = 0; j < COUNT; j++) { if (res_ptr[j] != (TYPE_C) target) { SQUELCH(printf("%d->%d -- NOP(1)[%d]: expected " TYPE_FMT ", got " TYPE_FMT "\n", target, rank, i, (TYPE_C) target, res_ptr[i]);); errors++; } } /* Test: origin_buf = NULL, origin_count = 0 */ MPI_Win_lock(MPI_LOCK_EXCLUSIVE, target, 0, win); MPI_Get_accumulate(NULL, 0, TYPE_MPI, res_ptr, COUNT, TYPE_MPI, target, 0, COUNT, TYPE_MPI, MPI_NO_OP, win); MPI_Win_unlock(target, win); for (j = 0; j < COUNT; j++) { if (res_ptr[j] != (TYPE_C) target) { SQUELCH(printf("%d->%d -- NOP(2)[%d]: expected " TYPE_FMT ", got " TYPE_FMT "\n", target, rank, i, (TYPE_C) target, res_ptr[i]);); errors++; } } /* Test: origin_buf = NULL, origin_count = 0, origin_dtype = NULL */ MPI_Win_lock(MPI_LOCK_EXCLUSIVE, target, 0, win); MPI_Get_accumulate(NULL, 0, MPI_DATATYPE_NULL, res_ptr, COUNT, TYPE_MPI, target, 0, COUNT, TYPE_MPI, MPI_NO_OP, win); MPI_Win_unlock(target, win); for (j = 0; j < COUNT; j++) { if (res_ptr[j] != (TYPE_C) target) { SQUELCH(printf("%d->%d -- NOP(2)[%d]: expected " TYPE_FMT ", got " TYPE_FMT "\n", target, rank, i, (TYPE_C) target, res_ptr[i]);); errors++; } } } /* Test NO_OP (self communication) */ reset_bufs(win_ptr, res_ptr, val_ptr, 1, win); MPI_Win_lock(MPI_LOCK_EXCLUSIVE, rank, 0, win); for (i = 0; i < COUNT * nproc; i++) win_ptr[i] = (TYPE_C) rank; MPI_Win_unlock(rank, win); MPI_Barrier(MPI_COMM_WORLD); for (i = 0; i < ITER; i++) { int j, target = rank; /* Test: origin_buf = NULL */ MPI_Win_lock(MPI_LOCK_EXCLUSIVE, target, 0, win); MPI_Get_accumulate(NULL, COUNT, TYPE_MPI, res_ptr, COUNT, TYPE_MPI, target, 0, COUNT, TYPE_MPI, MPI_NO_OP, win); MPI_Win_unlock(target, win); for (j = 0; j < COUNT; j++) { if (res_ptr[j] != (TYPE_C) target) { SQUELCH(printf ("%d->%d -- NOP_SELF(1)[%d]: expected " TYPE_FMT ", got " TYPE_FMT "\n", target, rank, i, (TYPE_C) target, res_ptr[i]);); errors++; } } /* Test: origin_buf = NULL, origin_count = 0 */ MPI_Win_lock(MPI_LOCK_EXCLUSIVE, target, 0, win); MPI_Get_accumulate(NULL, 0, TYPE_MPI, res_ptr, COUNT, TYPE_MPI, target, 0, COUNT, TYPE_MPI, MPI_NO_OP, win); MPI_Win_unlock(target, win); for (j = 0; j < COUNT; j++) { if (res_ptr[j] != (TYPE_C) target) { SQUELCH(printf ("%d->%d -- NOP_SELF(2)[%d]: expected " TYPE_FMT ", got " TYPE_FMT "\n", target, rank, i, (TYPE_C) target, res_ptr[i]);); errors++; } } /* Test: origin_buf = NULL, origin_count = 0, origin_dtype = NULL */ MPI_Win_lock(MPI_LOCK_EXCLUSIVE, target, 0, win); MPI_Get_accumulate(NULL, 0, MPI_DATATYPE_NULL, res_ptr, COUNT, TYPE_MPI, target, 0, COUNT, TYPE_MPI, MPI_NO_OP, win); MPI_Win_unlock(target, win); for (j = 0; j < COUNT; j++) { if (res_ptr[j] != (TYPE_C) target) { SQUELCH(printf ("%d->%d -- NOP_SELF(2)[%d]: expected " TYPE_FMT ", got " TYPE_FMT "\n", target, rank, i, (TYPE_C) target, res_ptr[i]);); errors++; } } } MPI_Win_free(&win); MPI_Reduce(&errors, &all_errors, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD); if (rank == 0 && all_errors == 0) printf(" No Errors\n"); #if defined (GACC_TYPE_DERIVED) MPI_Type_free(&derived_type); #endif free(win_ptr); free(res_ptr); free(val_ptr); MPI_Finalize(); return 0; }