/*
** Show use of MPI_Wait()
** Copyright Rolf Riesen 2008
** 
** 
*/
#include <stdio.h>
#include <stdlib.h>	/* For malloc() */
#include <unistd.h>	/* For sleep() */
#include <string.h>	/* For memset() */
#include <mpi.h>


#define LARGE_MSG_SIZE	(10 * 1024 * 1024)



int
main(int argc, char *argv[])
{

int my_rank, nproc;
int tag;
int count;
int dest;
char *rbuf;
char *sbuf;
double start, end;
MPI_Status status;
MPI_Request request;


    MPI_Init(&argc, &argv);
    MPI_Comm_size(MPI_COMM_WORLD, &nproc);
    MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);


    /* Initialize some variables */
    tag= 0;             /* Fixed tag */
    dest= 1;            /* Send to rank 1 */
    count= LARGE_MSG_SIZE;


    if (my_rank == 0)   {
	sbuf= (char *)malloc(LARGE_MSG_SIZE);
	if (sbuf == NULL)   {
	    fprintf(stderr, "[%3d] Out of memory!\n", my_rank);
	    MPI_Abort(MPI_COMM_WORLD, -1);
	}
	
	memset(sbuf, 1, LARGE_MSG_SIZE);

	MPI_Isend(sbuf, count, MPI_CHAR, dest, tag,
	    MPI_COMM_WORLD, &request);

	start= MPI_Wtime();
	MPI_Wait(&request, MPI_STATUS_IGNORE);
	end= MPI_Wtime();

	printf("Rank %d waited %5.3fs for the send to complete\n",
		my_rank, end - start);

    } else if (my_rank == 1)   {

	sleep(2); /* Pretend to be working */

	rbuf= (char *)malloc(LARGE_MSG_SIZE);
	if (rbuf == NULL)   {
	    fprintf(stderr, "[%3d] Out of memory!\n", my_rank);
	    MPI_Abort(MPI_COMM_WORLD, -1);
	}

	memset(rbuf, 1, LARGE_MSG_SIZE);

	MPI_Recv(rbuf, count, MPI_CHAR, MPI_ANY_SOURCE, tag,
            MPI_COMM_WORLD, &status);

    } else   {
        /* Do nothing */
    }

    MPI_Finalize();
    return 0;

}  /* end of main() */
