Blame test/mpi/rma/atomic_rmw_fop.c

Packit 0848f5
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
Packit 0848f5
/*
Packit 0848f5
 *
Packit 0848f5
 *  (C) 2015 by Argonne National Laboratory.
Packit 0848f5
 *      See COPYRIGHT in top-level directory.
Packit 0848f5
 */
Packit 0848f5
Packit 0848f5
/* This test is going to test the atomicity for "read-modify-write" in FOP
Packit 0848f5
 * operations */
Packit 0848f5
Packit 0848f5
/* There are three processes involved in this test: P0 (origin_shm), P1 (origin_am),
Packit 0848f5
 * and P2 (dest). P0 and P1 issues multiple FOP with MPI_SUM and integer (value 1)
Packit 0848f5
 * to P2 via SHM and AM respectively. The correct results should be that the
Packit 0848f5
 * results on P0 and P1 never be the same. */
Packit 0848f5
Packit 0848f5
#include "mpi.h"
Packit 0848f5
#include <stdio.h>
Packit 0848f5
Packit 0848f5
#define AM_BUF_SIZE  10
Packit 0848f5
#define SHM_BUF_SIZE 1000
Packit 0848f5
#define WIN_BUF_SIZE 1
Packit 0848f5
Packit 0848f5
#define LOOP_SIZE 15
Packit 0848f5
#define CHECK_TAG 123
Packit 0848f5
Packit 0848f5
int main(int argc, char *argv[])
Packit 0848f5
{
Packit 0848f5
    int rank, size, i, j, k;
Packit 0848f5
    int errors = 0, all_errors = 0;
Packit 0848f5
    int origin_shm, origin_am, dest;
Packit 0848f5
    int my_buf_size;
Packit 0848f5
    int *orig_buf = NULL, *result_buf = NULL, *target_buf = NULL, *check_buf = NULL;
Packit 0848f5
    MPI_Win win;
Packit 0848f5
    MPI_Status status;
Packit 0848f5
Packit 0848f5
    MPI_Init(&argc, &argv);
Packit 0848f5
Packit 0848f5
    MPI_Comm_rank(MPI_COMM_WORLD, &rank;;
Packit 0848f5
    MPI_Comm_size(MPI_COMM_WORLD, &size);
Packit 0848f5
    if (size != 3) {
Packit 0848f5
        /* run this test with three processes */
Packit 0848f5
        goto exit_test;
Packit 0848f5
    }
Packit 0848f5
Packit 0848f5
    /* this works when MPIR_PARAM_CH3_ODD_EVEN_CLIQUES is set */
Packit 0848f5
    dest = 2;
Packit 0848f5
    origin_shm = 0;
Packit 0848f5
    origin_am = 1;
Packit 0848f5
Packit 0848f5
    if (rank == origin_am)
Packit 0848f5
        my_buf_size = AM_BUF_SIZE;
Packit 0848f5
    else if (rank == origin_shm)
Packit 0848f5
        my_buf_size = SHM_BUF_SIZE;
Packit 0848f5
Packit 0848f5
    if (rank != dest) {
Packit 0848f5
        MPI_Alloc_mem(sizeof(int) * my_buf_size, MPI_INFO_NULL, &orig_buf);
Packit 0848f5
        MPI_Alloc_mem(sizeof(int) * my_buf_size, MPI_INFO_NULL, &result_buf);
Packit 0848f5
    }
Packit 0848f5
Packit 0848f5
    MPI_Win_allocate(sizeof(int) * WIN_BUF_SIZE, sizeof(int), MPI_INFO_NULL,
Packit 0848f5
                     MPI_COMM_WORLD, &target_buf, &win);
Packit 0848f5
Packit 0848f5
    for (k = 0; k < LOOP_SIZE; k++) {
Packit 0848f5
Packit 0848f5
        /* init buffers */
Packit 0848f5
        if (rank != dest) {
Packit 0848f5
            for (i = 0; i < my_buf_size; i++) {
Packit 0848f5
                orig_buf[i] = 1;
Packit 0848f5
                result_buf[i] = 0;
Packit 0848f5
            }
Packit 0848f5
        }
Packit 0848f5
        else {
Packit 0848f5
            MPI_Win_lock(MPI_LOCK_SHARED, rank, 0, win);
Packit 0848f5
            for (i = 0; i < WIN_BUF_SIZE; i++) {
Packit 0848f5
                target_buf[i] = 0;
Packit 0848f5
            }
Packit 0848f5
            MPI_Win_unlock(rank, win);
Packit 0848f5
        }
Packit 0848f5
Packit 0848f5
        MPI_Barrier(MPI_COMM_WORLD);
Packit 0848f5
Packit 0848f5
        /* perform FOP */
Packit 0848f5
        MPI_Win_lock_all(0, win);
Packit 0848f5
        if (rank != dest) {
Packit 0848f5
            for (i = 0; i < my_buf_size; i++) {
Packit 0848f5
                MPI_Fetch_and_op(&(orig_buf[i]), &(result_buf[i]), MPI_INT, dest, 0, MPI_SUM, win);
Packit 0848f5
                MPI_Win_flush(dest, win);
Packit 0848f5
            }
Packit 0848f5
        }
Packit 0848f5
        MPI_Win_unlock_all(win);
Packit 0848f5
Packit 0848f5
        MPI_Barrier(MPI_COMM_WORLD);
Packit 0848f5
Packit 0848f5
        if (rank != dest) {
Packit 0848f5
            /* check results on P0 and P2 (origin) */
Packit 0848f5
            if (rank == origin_am) {
Packit 0848f5
                MPI_Send(result_buf, AM_BUF_SIZE, MPI_INT, origin_shm, CHECK_TAG, MPI_COMM_WORLD);
Packit 0848f5
            }
Packit 0848f5
            else if (rank == origin_shm) {
Packit 0848f5
                MPI_Alloc_mem(sizeof(int) * AM_BUF_SIZE, MPI_INFO_NULL, &check_buf);
Packit 0848f5
                MPI_Recv(check_buf, AM_BUF_SIZE, MPI_INT, origin_am, CHECK_TAG, MPI_COMM_WORLD,
Packit 0848f5
                         &status);
Packit 0848f5
                for (i = 0; i < AM_BUF_SIZE; i++) {
Packit 0848f5
                    for (j = 0; j < SHM_BUF_SIZE; j++) {
Packit 0848f5
                        if (check_buf[i] == result_buf[j]) {
Packit 0848f5
                            printf
Packit 0848f5
                                ("LOOP=%d, rank=%d, FOP, both check_buf[%d] and result_buf[%d] equal to %d, expected to be different. \n",
Packit 0848f5
                                 k, rank, i, j, check_buf[i]);
Packit 0848f5
                            errors++;
Packit 0848f5
                        }
Packit 0848f5
                    }
Packit 0848f5
                }
Packit 0848f5
                MPI_Free_mem(check_buf);
Packit 0848f5
            }
Packit 0848f5
        }
Packit 0848f5
        else {
Packit 0848f5
            MPI_Win_lock(MPI_LOCK_SHARED, rank, 0, win);
Packit 0848f5
            /* check results on P1 */
Packit 0848f5
            if (target_buf[0] != AM_BUF_SIZE + SHM_BUF_SIZE) {
Packit 0848f5
                printf("LOOP=%d, rank=%d, FOP, target_buf[0] = %d, expected %d. \n",
Packit 0848f5
                       k, rank, target_buf[0], AM_BUF_SIZE + SHM_BUF_SIZE);
Packit 0848f5
                errors++;
Packit 0848f5
            }
Packit 0848f5
            MPI_Win_unlock(rank, win);
Packit 0848f5
        }
Packit 0848f5
    }
Packit 0848f5
Packit 0848f5
    MPI_Win_free(&win);
Packit 0848f5
Packit 0848f5
    if (rank == origin_am || rank == origin_shm) {
Packit 0848f5
        MPI_Free_mem(orig_buf);
Packit 0848f5
        MPI_Free_mem(result_buf);
Packit 0848f5
    }
Packit 0848f5
Packit 0848f5
  exit_test:
Packit 0848f5
    MPI_Reduce(&errors, &all_errors, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD);
Packit 0848f5
Packit 0848f5
    if (rank == 0 && all_errors == 0)
Packit 0848f5
        printf(" No Errors\n");
Packit 0848f5
Packit 0848f5
    MPI_Finalize();
Packit 0848f5
    return 0;
Packit 0848f5
}