|
Packit Service |
c5cf8c |
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
|
|
Packit Service |
c5cf8c |
/*
|
|
Packit Service |
c5cf8c |
*
|
|
Packit Service |
c5cf8c |
* (C) 2015 by Argonne National Laboratory.
|
|
Packit Service |
c5cf8c |
* See COPYRIGHT in top-level directory.
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* This test is going to test the atomicity for "read-modify-write" in GACC
|
|
Packit Service |
c5cf8c |
* operations */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* This test is similiar with atomic_rmw_fop.c.
|
|
Packit Service |
c5cf8c |
* There are three processes involved in this test: P0 (origin_shm), P1 (origin_am),
|
|
Packit Service |
c5cf8c |
* and P2 (dest). P0 and P1 issues multiple GACC with MPI_SUM and OP_COUNT integers
|
|
Packit Service |
c5cf8c |
* (value 1) to P2 via SHM and AM respectively. The correct results should be that the
|
|
Packit Service |
c5cf8c |
* results on P0 and P1 never be the same for intergers on the corresponding index
|
|
Packit Service |
c5cf8c |
* in [0...OP_COUNT-1].
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#include "mpi.h"
|
|
Packit Service |
c5cf8c |
#include <stdio.h>
|
|
Packit Service |
c5cf8c |
#include "mpitest.h"
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#define OP_COUNT 10
|
|
Packit Service |
c5cf8c |
#define AM_BUF_NUM 10
|
|
Packit Service |
c5cf8c |
#define SHM_BUF_NUM 10000
|
|
Packit Service |
c5cf8c |
#define WIN_BUF_NUM 1
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#define LOOP_SIZE 15
|
|
Packit Service |
c5cf8c |
#define CHECK_TAG 123
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
int rank, size;
|
|
Packit Service |
c5cf8c |
int dest, origin_shm, origin_am;
|
|
Packit Service |
c5cf8c |
int *orig_buf = NULL, *result_buf = NULL, *target_buf = NULL, *check_buf = NULL;
|
|
Packit Service |
c5cf8c |
MPI_Win win;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
void checkResults(int loop_k, int *errors)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
int i, j, m;
|
|
Packit Service |
c5cf8c |
MPI_Status status;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (rank != dest) {
|
|
Packit Service |
c5cf8c |
/* check results on P0 and P2 (origin) */
|
|
Packit Service |
c5cf8c |
if (rank == origin_am) {
|
|
Packit Service |
c5cf8c |
MPI_Send(result_buf, AM_BUF_NUM * OP_COUNT, MPI_INT, origin_shm, CHECK_TAG,
|
|
Packit Service |
c5cf8c |
MPI_COMM_WORLD);
|
|
Packit Service |
c5cf8c |
} else if (rank == origin_shm) {
|
|
Packit Service |
c5cf8c |
MPI_Alloc_mem(sizeof(int) * AM_BUF_NUM * OP_COUNT, MPI_INFO_NULL, &check_buf);
|
|
Packit Service |
c5cf8c |
MPI_Recv(check_buf, AM_BUF_NUM * OP_COUNT, MPI_INT, origin_am, CHECK_TAG,
|
|
Packit Service |
c5cf8c |
MPI_COMM_WORLD, &status);
|
|
Packit Service |
c5cf8c |
for (i = 0; i < AM_BUF_NUM; i++) {
|
|
Packit Service |
c5cf8c |
for (j = 0; j < SHM_BUF_NUM; j++) {
|
|
Packit Service |
c5cf8c |
for (m = 0; m < OP_COUNT; m++) {
|
|
Packit Service |
c5cf8c |
if (check_buf[i * OP_COUNT + m] == result_buf[j * OP_COUNT + m]) {
|
|
Packit Service |
c5cf8c |
printf
|
|
Packit Service |
c5cf8c |
("LOOP=%d, rank=%d, FOP, both check_buf[%d] and result_buf[%d] equal to %d, expected to be different. \n",
|
|
Packit Service |
c5cf8c |
loop_k, rank, i * OP_COUNT + m, j * OP_COUNT + m,
|
|
Packit Service |
c5cf8c |
check_buf[i * OP_COUNT + m]);
|
|
Packit Service |
c5cf8c |
(*errors)++;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
MPI_Free_mem(check_buf);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
} else {
|
|
Packit Service |
c5cf8c |
MPI_Win_lock(MPI_LOCK_SHARED, rank, 0, win);
|
|
Packit Service |
c5cf8c |
/* check results on P1 */
|
|
Packit Service |
c5cf8c |
for (i = 0; i < OP_COUNT; i++) {
|
|
Packit Service |
c5cf8c |
if (target_buf[i] != AM_BUF_NUM + SHM_BUF_NUM) {
|
|
Packit Service |
c5cf8c |
printf("LOOP=%d, rank=%d, FOP, target_buf[%d] = %d, expected %d. \n",
|
|
Packit Service |
c5cf8c |
loop_k, rank, i, target_buf[i], AM_BUF_NUM + SHM_BUF_NUM);
|
|
Packit Service |
c5cf8c |
(*errors)++;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
MPI_Win_unlock(rank, win);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
int main(int argc, char *argv[])
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
int i, k;
|
|
Packit Service |
c5cf8c |
int errors = 0;
|
|
Packit Service |
c5cf8c |
int my_buf_num;
|
|
Packit Service |
c5cf8c |
MPI_Datatype origin_dtp, target_dtp;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
MTest_Init(&argc, &argv);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
MPI_Comm_rank(MPI_COMM_WORLD, &rank;;
|
|
Packit Service |
c5cf8c |
MPI_Comm_size(MPI_COMM_WORLD, &size);
|
|
Packit Service |
c5cf8c |
if (size != 3) {
|
|
Packit Service |
c5cf8c |
/* run this test with three processes */
|
|
Packit Service |
c5cf8c |
goto exit_test;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
MPI_Type_contiguous(OP_COUNT, MPI_INT, &origin_dtp);
|
|
Packit Service |
c5cf8c |
MPI_Type_commit(&origin_dtp);
|
|
Packit Service |
c5cf8c |
MPI_Type_contiguous(OP_COUNT, MPI_INT, &target_dtp);
|
|
Packit Service |
c5cf8c |
MPI_Type_commit(&target_dtp);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* this works when MPIR_PARAM_CH3_ODD_EVEN_CLIQUES is set */
|
|
Packit Service |
c5cf8c |
dest = 2;
|
|
Packit Service |
c5cf8c |
origin_shm = 0;
|
|
Packit Service |
c5cf8c |
origin_am = 1;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (rank == origin_am)
|
|
Packit Service |
c5cf8c |
my_buf_num = AM_BUF_NUM;
|
|
Packit Service |
c5cf8c |
else if (rank == origin_shm)
|
|
Packit Service |
c5cf8c |
my_buf_num = SHM_BUF_NUM;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (rank != dest) {
|
|
Packit Service |
c5cf8c |
MPI_Alloc_mem(sizeof(int) * my_buf_num * OP_COUNT, MPI_INFO_NULL, &orig_buf);
|
|
Packit Service |
c5cf8c |
MPI_Alloc_mem(sizeof(int) * my_buf_num * OP_COUNT, MPI_INFO_NULL, &result_buf);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
MPI_Win_allocate(sizeof(int) * WIN_BUF_NUM * OP_COUNT, sizeof(int), MPI_INFO_NULL,
|
|
Packit Service |
c5cf8c |
MPI_COMM_WORLD, &target_buf, &win);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
for (k = 0; k < LOOP_SIZE; k++) {
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* ====== Part 1: test basic datatypes ======== */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* init buffers */
|
|
Packit Service |
c5cf8c |
if (rank != dest) {
|
|
Packit Service |
c5cf8c |
for (i = 0; i < my_buf_num * OP_COUNT; i++) {
|
|
Packit Service |
c5cf8c |
orig_buf[i] = 1;
|
|
Packit Service |
c5cf8c |
result_buf[i] = 0;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
} else {
|
|
Packit Service |
c5cf8c |
MPI_Win_lock(MPI_LOCK_SHARED, rank, 0, win);
|
|
Packit Service |
c5cf8c |
for (i = 0; i < WIN_BUF_NUM * OP_COUNT; i++) {
|
|
Packit Service |
c5cf8c |
target_buf[i] = 0;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
MPI_Win_unlock(rank, win);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
MPI_Barrier(MPI_COMM_WORLD);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
MPI_Win_lock_all(0, win);
|
|
Packit Service |
c5cf8c |
if (rank != dest) {
|
|
Packit Service |
c5cf8c |
for (i = 0; i < my_buf_num; i++) {
|
|
Packit Service |
c5cf8c |
MPI_Get_accumulate(&(orig_buf[i * OP_COUNT]), OP_COUNT, MPI_INT,
|
|
Packit Service |
c5cf8c |
&(result_buf[i * OP_COUNT]), OP_COUNT, MPI_INT,
|
|
Packit Service |
c5cf8c |
dest, 0, OP_COUNT, MPI_INT, MPI_SUM, win);
|
|
Packit Service |
c5cf8c |
MPI_Win_flush(dest, win);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
MPI_Win_unlock_all(win);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
MPI_Barrier(MPI_COMM_WORLD);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
checkResults(k, &errors);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* ====== Part 2: test derived datatypes (origin derived, target derived) ======== */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* init buffers */
|
|
Packit Service |
c5cf8c |
if (rank != dest) {
|
|
Packit Service |
c5cf8c |
for (i = 0; i < my_buf_num * OP_COUNT; i++) {
|
|
Packit Service |
c5cf8c |
orig_buf[i] = 1;
|
|
Packit Service |
c5cf8c |
result_buf[i] = 0;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
} else {
|
|
Packit Service |
c5cf8c |
MPI_Win_lock(MPI_LOCK_SHARED, rank, 0, win);
|
|
Packit Service |
c5cf8c |
for (i = 0; i < WIN_BUF_NUM * OP_COUNT; i++) {
|
|
Packit Service |
c5cf8c |
target_buf[i] = 0;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
MPI_Win_unlock(rank, win);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
MPI_Barrier(MPI_COMM_WORLD);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
MPI_Win_lock_all(0, win);
|
|
Packit Service |
c5cf8c |
if (rank != dest) {
|
|
Packit Service |
c5cf8c |
for (i = 0; i < my_buf_num; i++) {
|
|
Packit Service |
c5cf8c |
MPI_Get_accumulate(&(orig_buf[i * OP_COUNT]), 1, origin_dtp,
|
|
Packit Service |
c5cf8c |
&(result_buf[i * OP_COUNT]), 1, origin_dtp,
|
|
Packit Service |
c5cf8c |
dest, 0, 1, target_dtp, MPI_SUM, win);
|
|
Packit Service |
c5cf8c |
MPI_Win_flush(dest, win);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
MPI_Win_unlock_all(win);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
MPI_Barrier(MPI_COMM_WORLD);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
checkResults(k, &errors);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* ====== Part 3: test derived datatypes (origin basic, target derived) ======== */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* init buffers */
|
|
Packit Service |
c5cf8c |
if (rank != dest) {
|
|
Packit Service |
c5cf8c |
for (i = 0; i < my_buf_num * OP_COUNT; i++) {
|
|
Packit Service |
c5cf8c |
orig_buf[i] = 1;
|
|
Packit Service |
c5cf8c |
result_buf[i] = 0;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
} else {
|
|
Packit Service |
c5cf8c |
MPI_Win_lock(MPI_LOCK_SHARED, rank, 0, win);
|
|
Packit Service |
c5cf8c |
for (i = 0; i < WIN_BUF_NUM * OP_COUNT; i++) {
|
|
Packit Service |
c5cf8c |
target_buf[i] = 0;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
MPI_Win_unlock(rank, win);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
MPI_Barrier(MPI_COMM_WORLD);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
MPI_Win_lock_all(0, win);
|
|
Packit Service |
c5cf8c |
if (rank != dest) {
|
|
Packit Service |
c5cf8c |
for (i = 0; i < my_buf_num; i++) {
|
|
Packit Service |
c5cf8c |
MPI_Get_accumulate(&(orig_buf[i * OP_COUNT]), OP_COUNT, MPI_INT,
|
|
Packit Service |
c5cf8c |
&(result_buf[i * OP_COUNT]), OP_COUNT, MPI_INT,
|
|
Packit Service |
c5cf8c |
dest, 0, 1, target_dtp, MPI_SUM, win);
|
|
Packit Service |
c5cf8c |
MPI_Win_flush(dest, win);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
MPI_Win_unlock_all(win);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
MPI_Barrier(MPI_COMM_WORLD);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
checkResults(k, &errors);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* ====== Part 4: test derived datatypes (origin derived target basic) ======== */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* init buffers */
|
|
Packit Service |
c5cf8c |
if (rank != dest) {
|
|
Packit Service |
c5cf8c |
for (i = 0; i < my_buf_num * OP_COUNT; i++) {
|
|
Packit Service |
c5cf8c |
orig_buf[i] = 1;
|
|
Packit Service |
c5cf8c |
result_buf[i] = 0;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
} else {
|
|
Packit Service |
c5cf8c |
MPI_Win_lock(MPI_LOCK_SHARED, rank, 0, win);
|
|
Packit Service |
c5cf8c |
for (i = 0; i < WIN_BUF_NUM * OP_COUNT; i++) {
|
|
Packit Service |
c5cf8c |
target_buf[i] = 0;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
MPI_Win_unlock(rank, win);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
MPI_Barrier(MPI_COMM_WORLD);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
MPI_Win_lock_all(0, win);
|
|
Packit Service |
c5cf8c |
if (rank != dest) {
|
|
Packit Service |
c5cf8c |
for (i = 0; i < my_buf_num; i++) {
|
|
Packit Service |
c5cf8c |
MPI_Get_accumulate(&(orig_buf[i * OP_COUNT]), 1, origin_dtp,
|
|
Packit Service |
c5cf8c |
&(result_buf[i * OP_COUNT]), 1, origin_dtp,
|
|
Packit Service |
c5cf8c |
dest, 0, OP_COUNT, MPI_INT, MPI_SUM, win);
|
|
Packit Service |
c5cf8c |
MPI_Win_flush(dest, win);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
MPI_Win_unlock_all(win);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
MPI_Barrier(MPI_COMM_WORLD);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
checkResults(k, &errors);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
MPI_Win_free(&win);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (rank == origin_am || rank == origin_shm) {
|
|
Packit Service |
c5cf8c |
MPI_Free_mem(orig_buf);
|
|
Packit Service |
c5cf8c |
MPI_Free_mem(result_buf);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
MPI_Type_free(&origin_dtp);
|
|
Packit Service |
c5cf8c |
MPI_Type_free(&target_dtp);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
exit_test:
|
|
Packit Service |
c5cf8c |
MTest_Finalize(errors);
|
|
Packit Service |
c5cf8c |
return MTestReturnValue(errors);
|
|
Packit Service |
c5cf8c |
}
|