/* test program to find out how much buffering a system supplies 
   See also mpich/examples/perftest/buflimit.c 
 */

#include "mpi.h"
#include <stdio.h>

int main(argc,argv)
int argc;
char *argv[];
{
    int  myid, numprocs;
    int  namelen;
    char processor_name[MPI_MAX_PROCESSOR_NAME];
    char *buf;
    int  bufsize, other, done, i;
    double t1, t2, tbase;
    MPI_Status status;

    MPI_Init(&argc,&argv);
    MPI_Comm_size(MPI_COMM_WORLD,&numprocs);
    MPI_Comm_rank(MPI_COMM_WORLD,&myid);
    MPI_Get_processor_name(processor_name,&namelen);
    fprintf(stderr,"Process %d on %s\n", myid, processor_name);

    bufsize = 1024;
    other   = (myid + 1) % 2;
    done    = 0;

    while (!done && bufsize < 1024*1024*16) {
	if ((buf = (char *) malloc (bufsize)) == NULL) {
	    fprintf(stderr, "%d could not malloc %d bytes\n", myid, bufsize );
	    MPI_Finalize();
	    exit(-1);
	}
	fprintf(stderr,"%d sending %d to %d\n", myid, bufsize, other );
	if ((myid % 2) == 0) {
	    MPI_Send( MPI_BOTTOM, 0, MPI_INT, other, 1, MPI_COMM_WORLD );
	    MPI_Recv( MPI_BOTTOM, 0, MPI_INT, other, 2, MPI_COMM_WORLD, 
		      &status );
	    /* Compute a time to send when the receive is waiting */
	    t1 = MPI_Wtime();
	    MPI_Send( buf, bufsize, MPI_CHAR, other, 100, MPI_COMM_WORLD );
	    t2 = MPI_Wtime();
	    tbase = t2 - t1;
	    MPI_Recv( MPI_BOTTOM, 0, MPI_INT, other, 2, MPI_COMM_WORLD, 
		      &status );
	    /* Compute a time when the receive is NOT waiting */
	    t1 = MPI_Wtime();
	    MPI_Send( buf, bufsize, MPI_CHAR, other, 100, MPI_COMM_WORLD );
	    t2 = MPI_Wtime();
	    if (t2 - t1 > 1.5 && t2 - t1 > 2.0 * tbase) {
		printf( "MPI_Send blocks with buffers of size %d\n", 
			bufsize );
		done = 1;
	    }
	}
	else {
	    MPI_Recv( MPI_BOTTOM, 0, MPI_INT, other, 1, MPI_COMM_WORLD, 
		      &status );
	    t1 = MPI_Wtime();
	    MPI_Send( MPI_BOTTOM, 0, MPI_INT, other, 2, MPI_COMM_WORLD );
	    MPI_Recv( buf, bufsize, MPI_CHAR, other, 100, MPI_COMM_WORLD, 
		      &status );
	    MPI_Send( MPI_BOTTOM, 0, MPI_INT, other, 2, MPI_COMM_WORLD );
	    while (MPI_Wtime() - t1 < 2.0) ;
	    MPI_Recv( buf, bufsize, MPI_CHAR, other, 100, MPI_COMM_WORLD, 
		      &status );
	}
	fprintf(stderr,"%d received %d fr %d\n", myid, bufsize, other );
	free( buf );
	i = done;
	MPI_Allreduce( &i, &done, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD );
	bufsize *= 2;
    }
    MPI_Finalize();
    return 0;
}

            
