/* -----------------------------------------------------------------------
 * Code:   brecv.c
 * Lab:    MPI Point-to-Point Communication
 *         This program demonstrates that replacing a blocking receive
 *         with a non-blocking receive earlier in the program can decrease
 *         the synchronization time on the corresponding send.
 * Usage:  brecv
 *         Run on two nodes
 * Author: Roslyn Leibensperger  Last revised: 2/17/01 JAZ
 * ------------------------------------------------------------------------ */
#include <stdio.h>
#include "mpi.h"
#define TAG 100
void print_time ( double tbegin, double tend );

main( argc, argv ) 
     int argc;
     char **argv;
{
  float *message;    /* message buffer                   */
  int rank,                  /* rank of task in communicator */
      i;
  int mlen;  /* dimmension of the mesage */
  MPI_Status status;         /* status of communication      */
  double tbegin, tend;       /* used to measure elapsed time */
 
  if (argc != 2) {
    printf ( " Usage: blocksends <message_length_in_number_of_floats>\n" );
    return -1;
  }

  /* -------------------------------------------------------------------
   * do initial housekeeping: allocate memory for messages,
   * initialize program with MPI, define message tags 
   * ------------------------------------------------------------------ */

  mlen = atoi (argv[1]); 
  message = (float *)malloc ( mlen * sizeof(float) );   
                  

  MPI_Init( &argc, &argv );
  MPI_Comm_rank( MPI_COMM_WORLD, &rank );
  printf ( " Process %d initialized\n", rank );
  printf ( " Message size = %6d floats\n", mlen );
  printf ( " Total size = %6d bytes\n", (mlen* sizeof(float))  );

  /* -----------------------------------------------------------------
   * task 0 will report the elapsed time for a blocking send
   * ----------------------------------------------------------------- */
  if ( rank == 0 )  {
    for (i=0; i<mlen; i++) message[i] = 100;
    printf ( " Task %d sending message\n", rank );
    tbegin=MPI_Wtime();
    MPI_Send ( message, mlen, MPI_FLOAT, 1, TAG, MPI_COMM_WORLD );
    tend=MPI_Wtime();   
    print_time ( tbegin, tend );
  }

  /* -----------------------------------------------------------------
   * task 1 sleeps for 10 seconds, and then calls a blocking receive.
   * the sleep is intended to simulate time spent in useful computation
   * ----------------------------------------------------------------- */
  else if ( rank == 1)  {
    for (i=0; i<mlen; i++) message[i] = -100;
/*    MPI_Sleep(10); */
    new_sleep(10);
    MPI_Recv ( message, mlen, MPI_FLOAT, 0, TAG, MPI_COMM_WORLD, 
	      &status );
    printf ( " Task %d received message\n", rank );
  }
  MPI_Finalize ();
  return 0;
}

/* -------------------------------------------------------------------
 * calculate elapsed time and print results
 * ------------------------------------------------------------------- */
void print_time ( double tbegin, double tend )
{
  int dt;
  dt = (int)((tend - tbegin)*1000000.0);
  printf ( " Elapsed time for send = %8d uSec\n", dt );
}