Blame test/mpi/rma/wrma_flush_get.c

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
#include <stdio.h>
Packit Service c5cf8c
#include <stdlib.h>
Packit Service c5cf8c
#include <mpi.h>
Packit Service c5cf8c
#include "mpitest.h"
Packit Service c5cf8c
Packit Service c5cf8c
#define ITER 10000
Packit Service c5cf8c
#define BUF_CNT 1
Packit Service c5cf8c
int local_buf[BUF_CNT], result_addr[BUF_CNT], check_addr[BUF_CNT];
Packit Service c5cf8c
#ifdef TEST_CAS
Packit Service c5cf8c
int compare_buf[BUF_CNT];
Packit Service c5cf8c
#endif
Packit Service c5cf8c
Packit Service c5cf8c
const int verbose = 0;
Packit Service c5cf8c
Packit Service c5cf8c
/* This test checks the remote completion of flush with RMA write-like operations
Packit Service c5cf8c
 * (PUT, ACC, GET_ACC, FOP, CAS), and confirms result by GET issued from another
Packit Service c5cf8c
 * process.
Packit Service c5cf8c
 * 1. Three processes create window by Win_allocate.
Packit Service c5cf8c
 * 2. P(origin) issues RMA operations and flush to P(target), then call
Packit Service c5cf8c
 *    send-recv to synchronize with P(checker).
Packit Service c5cf8c
 * 3. P(checker) then issues get to P(target) to check the results.
Packit Service c5cf8c
 */
Packit Service c5cf8c
Packit Service c5cf8c
int rank = -1, nproc = 0;
Packit Service c5cf8c
int origin = -1, target = -1, checker = -1;
Packit Service c5cf8c
MPI_Win win = MPI_WIN_NULL;
Packit Service c5cf8c
int *my_base = NULL;
Packit Service c5cf8c
Packit Service c5cf8c
/* Define operation name for error message */
Packit Service c5cf8c
#ifdef TEST_PUT
Packit Service c5cf8c
const char *rma_name = "Put";
Packit Service c5cf8c
#elif defined(TEST_ACC)
Packit Service c5cf8c
const char *rma_name = "Accumulate";
Packit Service c5cf8c
#elif defined(TEST_GACC)
Packit Service c5cf8c
const char *rma_name = "Get_accumulate";
Packit Service c5cf8c
#elif defined(TEST_FOP)
Packit Service c5cf8c
const char *rma_name = "Fetch_and_op";
Packit Service c5cf8c
#elif defined(TEST_CAS)
Packit Service c5cf8c
const char *rma_name = "Compare_and_swap";
Packit Service c5cf8c
#else
Packit Service c5cf8c
const char *rma_name = "None";
Packit Service c5cf8c
#endif
Packit Service c5cf8c
Packit Service c5cf8c
/* Issue functions for different RMA operations */
Packit Service c5cf8c
#ifdef TEST_PUT
Packit Service c5cf8c
static inline void issue_rma_op(int i)
Packit Service c5cf8c
{
Packit Service c5cf8c
    MPI_Put(&local_buf[i], 1, MPI_INT, target, i, 1, MPI_INT, win);
Packit Service c5cf8c
}
Packit Service c5cf8c
#elif defined(TEST_ACC)
Packit Service c5cf8c
static inline void issue_rma_op(int i)
Packit Service c5cf8c
{
Packit Service c5cf8c
    MPI_Accumulate(&local_buf[i], 1, MPI_INT, target, i, 1, MPI_INT, MPI_REPLACE, win);
Packit Service c5cf8c
}
Packit Service c5cf8c
#elif defined(TEST_GACC)
Packit Service c5cf8c
static inline void issue_rma_op(int i)
Packit Service c5cf8c
{
Packit Service c5cf8c
    MPI_Get_accumulate(&local_buf[i], 1, MPI_INT, &result_addr[i], 1, MPI_INT, target, i,
Packit Service c5cf8c
                       1, MPI_INT, MPI_REPLACE, win);
Packit Service c5cf8c
}
Packit Service c5cf8c
#elif defined(TEST_FOP)
Packit Service c5cf8c
static inline void issue_rma_op(int i)
Packit Service c5cf8c
{
Packit Service c5cf8c
    MPI_Fetch_and_op(&local_buf[i], &result_addr[i], MPI_INT, target, i, MPI_REPLACE, win);
Packit Service c5cf8c
}
Packit Service c5cf8c
#elif defined(TEST_CAS)
Packit Service c5cf8c
static inline void issue_rma_op(int i)
Packit Service c5cf8c
{
Packit Service c5cf8c
    compare_buf[i] = i; /* always equal to window value, thus swap happens */
Packit Service c5cf8c
    MPI_Compare_and_swap(&local_buf[i], &compare_buf[i], &result_addr[i], MPI_INT, target, i, win);
Packit Service c5cf8c
}
Packit Service c5cf8c
#endif
Packit Service c5cf8c
Packit Service c5cf8c
Packit Service c5cf8c
/* Local check function for GET-like operations */
Packit Service c5cf8c
#if defined(TEST_GACC) || defined(TEST_FOP) || defined(TEST_CAS)
Packit Service c5cf8c
Packit Service c5cf8c
/* Check local result buffer for GET-like operations */
Packit Service c5cf8c
static int check_local_result(int iter)
Packit Service c5cf8c
{
Packit Service c5cf8c
    int i = 0;
Packit Service c5cf8c
    int errors = 0;
Packit Service c5cf8c
Packit Service c5cf8c
    for (i = 0; i < BUF_CNT; i++) {
Packit Service c5cf8c
        if (result_addr[i] != i) {
Packit Service c5cf8c
            printf("rank %d (iter %d) - check %s, got result_addr[%d] = %d, expected %d\n",
Packit Service c5cf8c
                   rank, iter, rma_name, i, result_addr[i], i);
Packit Service c5cf8c
            errors++;
Packit Service c5cf8c
        }
Packit Service c5cf8c
    }
Packit Service c5cf8c
    return errors;
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
#else
Packit Service c5cf8c
#define check_local_result(iter) (0)
Packit Service c5cf8c
#endif
Packit Service c5cf8c
Packit Service c5cf8c
static int run_test()
Packit Service c5cf8c
{
Packit Service c5cf8c
    int i = 0, x = 0;
Packit Service c5cf8c
    int errors = 0;
Packit Service c5cf8c
    int sbuf = 0, rbuf = 0;
Packit Service c5cf8c
    MPI_Status stat;
Packit Service c5cf8c
Packit Service c5cf8c
    for (x = 0; x < ITER; x++) {
Packit Service c5cf8c
        /* 1. Target resets window data */
Packit Service c5cf8c
        if (rank == target) {
Packit Service c5cf8c
            for (i = 0; i < BUF_CNT; i++)
Packit Service c5cf8c
                my_base[i] = i;
Packit Service c5cf8c
            MPI_Win_sync(win);  /* write is done on window */
Packit Service c5cf8c
        }
Packit Service c5cf8c
Packit Service c5cf8c
        MPI_Barrier(MPI_COMM_WORLD);
Packit Service c5cf8c
Packit Service c5cf8c
        /* 2. Every one resets local data */
Packit Service c5cf8c
        for (i = 0; i < BUF_CNT; i++) {
Packit Service c5cf8c
            local_buf[i] = BUF_CNT + x * BUF_CNT + i;
Packit Service c5cf8c
            result_addr[i] = 0;
Packit Service c5cf8c
        }
Packit Service c5cf8c
Packit Service c5cf8c
        /* 3. Origin issues RMA operation to target */
Packit Service c5cf8c
        if (rank == origin) {
Packit Service c5cf8c
            /* 3-1. Issue RMA. */
Packit Service c5cf8c
            for (i = 0; i < BUF_CNT; i++) {
Packit Service c5cf8c
                issue_rma_op(i);
Packit Service c5cf8c
            }
Packit Service c5cf8c
            MPI_Win_flush(target, win);
Packit Service c5cf8c
Packit Service c5cf8c
            /* 3-2. Sync with checker */
Packit Service c5cf8c
            MPI_Send(&sbuf, 1, MPI_INT, checker, 999, MPI_COMM_WORLD);
Packit Service c5cf8c
Packit Service c5cf8c
            /* 3-3. Check local result buffer */
Packit Service c5cf8c
            errors += check_local_result(x);
Packit Service c5cf8c
        }
Packit Service c5cf8c
Packit Service c5cf8c
        /* 4. Checker issues GET to target and checks result */
Packit Service c5cf8c
        if (rank == checker) {
Packit Service c5cf8c
            /* 4-1. Sync with origin */
Packit Service c5cf8c
            MPI_Recv(&rbuf, 1, MPI_INT, origin, 999, MPI_COMM_WORLD, &stat;;
Packit Service c5cf8c
Packit Service c5cf8c
            /* 4-2. Get result and check */
Packit Service c5cf8c
            MPI_Get(check_addr, BUF_CNT, MPI_INT, target, 0, BUF_CNT, MPI_INT, win);
Packit Service c5cf8c
            MPI_Win_flush(target, win);
Packit Service c5cf8c
Packit Service c5cf8c
            for (i = 0; i < BUF_CNT; i++) {
Packit Service c5cf8c
                if (check_addr[i] != local_buf[i]) {
Packit Service c5cf8c
                    printf("rank %d (iter %d) - check %s, got check_addr[%d] = %d, expected %d\n",
Packit Service c5cf8c
                           rank, x, rma_name, i, check_addr[i], local_buf[i]);
Packit Service c5cf8c
                    errors++;
Packit Service c5cf8c
                }
Packit Service c5cf8c
            }
Packit Service c5cf8c
        }
Packit Service c5cf8c
Packit Service c5cf8c
        MPI_Barrier(MPI_COMM_WORLD);
Packit Service c5cf8c
    }
Packit Service c5cf8c
Packit Service c5cf8c
    return errors;
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
int main(int argc, char *argv[])
Packit Service c5cf8c
{
Packit Service c5cf8c
    int errors = 0;
Packit Service c5cf8c
    int win_size = sizeof(int) * BUF_CNT;
Packit Service c5cf8c
    int win_unit = sizeof(int);
Packit Service c5cf8c
Packit Service c5cf8c
    MTest_Init(&argc, &argv);
Packit Service c5cf8c
    MPI_Comm_rank(MPI_COMM_WORLD, &rank;;
Packit Service c5cf8c
    MPI_Comm_size(MPI_COMM_WORLD, &nproc);
Packit Service c5cf8c
Packit Service c5cf8c
    if (nproc != 3) {
Packit Service c5cf8c
        if (rank == 0)
Packit Service c5cf8c
            printf("Error: must be run with three processes\n");
Packit Service c5cf8c
        MPI_Barrier(MPI_COMM_WORLD);
Packit Service c5cf8c
        MPI_Abort(MPI_COMM_WORLD, 1);
Packit Service c5cf8c
    }
Packit Service c5cf8c
#if !defined(TEST_PUT) && !defined(TEST_ACC) && !defined(TEST_GACC) && !defined(TEST_FOP) && !defined(TEST_CAS)
Packit Service c5cf8c
    if (rank == 0)
Packit Service c5cf8c
        printf("Error: must specify operation type at compile time\n");
Packit Service c5cf8c
    MPI_Barrier(MPI_COMM_WORLD);
Packit Service c5cf8c
    MPI_Abort(MPI_COMM_WORLD, 1);
Packit Service c5cf8c
#endif
Packit Service c5cf8c
Packit Service c5cf8c
    /* Identify origin, target and checker ranks. */
Packit Service c5cf8c
    target = 0;
Packit Service c5cf8c
    checker = 2;
Packit Service c5cf8c
    origin = 1;
Packit Service c5cf8c
Packit Service c5cf8c
    MPI_Win_allocate(win_size, win_unit, MPI_INFO_NULL, MPI_COMM_WORLD, &my_base, &win);
Packit Service c5cf8c
Packit Service c5cf8c
    /* Start checking. */
Packit Service c5cf8c
    MPI_Win_lock_all(0, win);
Packit Service c5cf8c
Packit Service c5cf8c
    errors = run_test();
Packit Service c5cf8c
Packit Service c5cf8c
    MPI_Win_unlock_all(win);
Packit Service c5cf8c
Packit Service c5cf8c
    if (win != MPI_WIN_NULL)
Packit Service c5cf8c
        MPI_Win_free(&win);
Packit Service c5cf8c
Packit Service c5cf8c
    MTest_Finalize(errors);
Packit Service c5cf8c
Packit Service c5cf8c
    return MTestReturnValue(errors);
Packit Service c5cf8c
}