/*
** FIFO Order and Matching Rules, Part 2
** Copyright Rolf Riesen 2008
** 
** 
*/
#include <stdio.h>
#include <mpi.h>



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

int my_rank, nproc;
int tag;
int count;
int dest1, dest2;
int rbuf1, rbuf2;
int sbuf;
MPI_Status status;


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

    if (nproc != 4)   {
        if (my_rank == 0)   {
            printf("Please run this program on 4 nodes\n");
        }
        MPI_Finalize();
        return 0;
    }

    /* Initialize some variables */
    tag= 0;             /* Fixed tag */
    dest1= 0;           /* Send to rank 0 */
    dest2= 1;           /* Send to rank 1 */
    sbuf= my_rank;      /* Initialize send buffer */
    count= 1;           /* Send and receive 1 integer */


    if (my_rank == 0)   {
        /* I am a receiver */
	MPI_Recv(&rbuf1, count, MPI_INT, MPI_ANY_SOURCE, tag,
            MPI_COMM_WORLD, &status);

	MPI_Recv(&rbuf2, count, MPI_INT, MPI_ANY_SOURCE, tag,
            MPI_COMM_WORLD, &status);

        printf("Rank %d: Received the message from rank %d first\n",
            my_rank, rbuf1);
        printf("Rank %d: Received the message from rank %d second\n",
            my_rank, rbuf2);

    } else if (my_rank == 1)   {
        /* I am a receiver */
	MPI_Recv(&rbuf1, count, MPI_INT, MPI_ANY_SOURCE, tag,
            MPI_COMM_WORLD, &status);

	MPI_Recv(&rbuf2, count, MPI_INT, MPI_ANY_SOURCE, tag,
            MPI_COMM_WORLD, &status);

        printf("Rank %d: Received the message from rank %d first\n",
            my_rank, rbuf1);
        printf("Rank %d: Received the message from rank %d second\n",
            my_rank, rbuf2);

    } else if (my_rank == 2)   {
        /* I am a sender */
	MPI_Send(&sbuf, count, MPI_INT, dest1, tag, MPI_COMM_WORLD);
	MPI_Send(&sbuf, count, MPI_INT, dest2, tag, MPI_COMM_WORLD);

    } else if (my_rank == 3)   {
        /* I am a sender */
	MPI_Send(&sbuf, count, MPI_INT, dest1, tag, MPI_COMM_WORLD);
	MPI_Send(&sbuf, count, MPI_INT, dest2, tag, MPI_COMM_WORLD);
    }

    MPI_Finalize();
    return 0;

}  /* end of main() */
