#include "mpi.h"
#include <stdlib.h>
#include <stdio.h>
/* #include "pvm3.h" */
#include "pvmpi.h"

#define MCW MPI_COMM_WORLD 

main (argc,argv)
int argc;
char *argv[];
{

	int rank, size, i;
	char com_name[100];
	MPI_Status status;
	int my_comm_handle;
	MPI_Comm icom_right;
	MPI_Comm icom_left;
	double data;
	int TAG=1;
	int size_left;


	strcpy (com_name, "B");
 	MPI_Init(&argc, &argv); 

	MPI_Comm_size (MCW, &size);
	MPI_Comm_rank (MCW, &rank);
	MPI_Barrier(MCW);


	printf("\nMPI independant information\n");
	printf("\nProg [%s] Size [%d], rank [%d]\n\n", com_name, size, rank);

	i = MPI_Conn_register(com_name, MPI_COMM_WORLD, &my_comm_handle); 
	i = MPI_Conn_intercomm_create (my_comm_handle, "C", &icom_right);
	i = MPI_Conn_intercomm_create (my_comm_handle, "A", &icom_left);

MPI_Barrier (MPI_COMM_WORLD);

	if (i<0) {printf("MPI_Conn failed with code %d\n",i); goto shutdown;}

	i = MPI_Comm_remote_size (icom_left, &size_left);

	/* OK, system is now up so now we can pass messages around */

	if ((!strcmp(com_name,"A"))&&(!rank)) { /* root of ring */
	    data = 3.141592;
	}
	else data = 0.0;

	/* now three possible variations */
	/* the root, only sends */
	/* the middle processes recv and then send */
	/* the end just recvs */

	/* root */
	if ((!strcmp(com_name,"A"))&&(!rank)) { /* root of ring */
	    fprintf(stderr,"First one says data is [%lf]\n", data);
	    if (size==1) /* i.e. only me */
			 /* so pass it to next inter comm */
	      MPI_Send (&data, 1, MPI_DOUBLE, 0, TAG, icom_right);
	    else  /* next in my group */
	      MPI_Send (&data, 1, MPI_DOUBLE, rank+1, TAG, MCW);

		/* get final result from end of ring back to me :) */
	    MPI_Recv (&data, 1, MPI_DOUBLE, size_left-1, TAG, icom_left, &status);

	    fprintf(stderr,"First one says data is now [%lf]\n", data);
	}
	
	else { /* not the root */
	  if (!rank) /* head of my group, so I receive from an intercom */
/* 	    MPI_Recv (&data, 1, MPI_DOUBLE, MPI_ANY_SOURCE, TAG, icom_left, &status); */
	    MPI_Recv (&data, 1, MPI_DOUBLE, size_left-1, TAG, icom_left, &status);
	  else
	    MPI_Recv (&data, 1, MPI_DOUBLE, rank-1, TAG, MCW, &status);

	/* ok, read data */
	/* do calc */
	data *= 2.0;

	/* pass data onto next */
	/* only if not end of the line! */

/* 	if (!strcmp(com_name, "C")&&(rank==(size-1))) { */
/* 		fprintf(stderr,"Last one says data is [%lf]\n", data); */
/* 	} */

/* 	else {  */
	/* not end of the line so pass it on ! */

	    if (rank==(size-1))
              /* so pass it to next inter comm */
              MPI_Send (&data, 1, MPI_DOUBLE, 0, TAG, icom_right);
            else  /* next in my group */
              MPI_Send (&data, 1, MPI_DOUBLE, rank+1, TAG, MCW);
	 
/* 	   }  */
	   /* not end of the line */

	} /* not the root */

		
shutdown:
	/* shut down in a tidy fashion */
	/* 
	MPI_Comm_free (&icom_right);
	MPI_Comm_free (&icom_left); 
	*/
	MPI_Conn_leave ();		/* stop MPI_Conn */
	MPI_Finalize(); 
}
