/**********************************************************************
 *                 III TTTTTTT U     U                                *
 *                  I     T    U     U                                *
 *                  I     T    U     U                                *
 *                  I     T    U     U                                *
 *                 III    T    UUUUUUU                                *
 *                                                                    *
 *  ITU Informatics Institute                                         *
 *  Computational Science & Engineering Dept.                         *
 *  Istanbul / TURKIYE                                                *
 *                                                                    *
 *  By: Ozden AKINCI                                                  *
 *  E-mail: akinci@be.itu.edu.tr                                      *
 *  Date: 13.10.2005                                                  *
 *                                                                    *
 *  Program:                                                          *
 *  The master node with 0 rank sends a random number to next node.   *
 *  The next node sends the newvalue which is summation of previous   *
 *  received value and its rank number to the next node. It continuous*
 *  until the last node. The last node sends its newvalue to the      *
 *  master node which is ranked with 0.                               *
 *                                                                    *
 **********************************************************************/

#include<stdio.h>
#include "mpi.h"
#define TAG 1000
int main (int argc, char **argv)
{
	char nodename[BUFSIZ];
	int myrank, size,length,nextnode,prevnode;
	int m,n,i,number,value,newvalue;
	MPI_Status status;
	MPI_Init(&argc,&argv); /* initialisation of MPI */
	MPI_Get_processor_name(nodename,&length);
	MPI_Comm_rank(MPI_COMM_WORLD, &myrank);
	MPI_Comm_size(MPI_COMM_WORLD, &size);
	printf("Nodename=%s\tRank=%d\tSize=%d\n",nodename,myrank,size);
	
	if (myrank==size-1) /* the last node */
	{
		nextnode=0;
	}
	else /* other nodes */
	{
		nextnode=myrank+1;
	}
	
	if (myrank==0)	/* master node */
	{
		prevnode=size-1;
	}
	else /* other nodes */
	{
		prevnode=myrank-1;
	}
	
	if (myrank==0) /* master node */
	{
		srand(time(NULL));
		number=(int)(rand()%100);
		MPI_Send(&number,1,MPI_INT,nextnode,TAG,MPI_COMM_WORLD); /* sends the number to the nextnode */
		printf("INFO: %s (%d of %d) sent %d value to %d of %d\n",nodename,myrank,size,number,nextnode,size);
		MPI_Recv(&value,1,MPI_INT,prevnode,TAG,MPI_COMM_WORLD,&status);	/* reveices the value from the prevnode */
		printf("INFO: %s (%d of %d) received %d value from %d of %d\n",nodename,myrank,size,value,prevnode,size);
			
	}
	else /* other nodes */
	{
		MPI_Recv(&value,1,MPI_INT,prevnode,TAG,MPI_COMM_WORLD,&status);	/* receives the value from prevnode */
		printf("INFO: %s (%d of %d) received %d value from %d of %d\n",nodename,myrank,size,value,prevnode,size);
		newvalue=value+myrank;
		MPI_Send(&newvalue,1,MPI_INT,nextnode,TAG,MPI_COMM_WORLD); /* sends the newvalue to the nextnode */
		printf("INFO: %s (%d of %d) sent %d+%d=%d value to %d of %d\n",nodename,myrank,size,value,myrank,newvalue,nextnode,size);
	}
	MPI_Finalize(); /* finalization of mpi */
	return 0;

} /* main */
