/**********************************************************
**MultiplicativeBinomialTree Parallel OptionPriceValuations
**This is the testing function main() component;
**Copyright (c) 2001-2003   Alexandros V. Gerbessiotis
**
**Permission to use, copy, modify, and distribute this 
**software, and to incorporate it, in whole or in part, 
**into other software, is hereby granted without fee, 
**provided that 
**(1) the above copyright notice and  permission notice 
**appear in all copies of the source code, and the 
**above copyright notice appear in clearly visible form 
**on all supporting documentation  and distribution media, 
**and
**(2) any redistribution of the software, in original
**  or modified form, be without fee and subject to
**  these same conditions.
**No guarantee is offered that the code works as
**advertised or is absent of any, even damaging,
**side-effects; use this code on your own personal risk
**/
/* Test Data are available as comment at the end of this file */
#include <stdio.h>
#include <sys/utsname.h>
#include <unistd.h>
#include "bt.h"
#include "aimisc.h"

#define PRINTMAT(X)   bspfold((void (*)(void *,void *,void *)) foldmin,(char *)&t1,(char *)&t3,sizeof(double)); bspfold((void (*)(void *,void *,void *)) foldmax,(char *)&t1,(char *)&t4,sizeof(double)); 

/* MAIN FUNCTION */
int	main(int argc, char *argv[])
{
 int 	n,nprocs,runs,debug,pid;
 double t3,t4,t1;
 char hostname[512];
 double K, S,r,u,d;
 int    T,N,blocksize;
 double rst, rc;

 AIBEGIN(AINPROCS());
 pid = AIPID(); nprocs = AINPROCS();


 /* Show hostnames of processors; */
 gethostname(hostname,sizeof(hostname));
#ifdef SANITY_CHECK
#define SANITY_CHECK
 for(i=0;i<nprocs;i++) {
   if (i==pid) {
      printf("Processor %d of %d [%s]\n",pid,nprocs,hostname);
      fflush(stdout);
   }
 }
#endif
 AIBARRIER();

  /* Command line processing */
 n=8;debug=0;runs=1; 
 if (0 == pid ){
   if (3 != argc){
    printf("Usage: %s blocksize horizon <mdata\n\
            Integer blocksize-1 must divide integer horizon\n\
            mdata is a parameter file\n", 
           argv[0]);
     fflush(stdout);
     AIABORT("exit");
   } 
   else {
    blocksize=atoi(argv[1]);
    scanf("%lf",&K);
    scanf("%d",&T);
    scanf("%lf",&S);
    scanf("%lf",&r);
    scanf("%d",&N);
    scanf("%lf",&u);
    scanf("%lf",&d);
    N= atoi(argv[2]);
   }
 }

   /* Parallel Command line processing */
   AIREGISTER(&K,sizeof(double)); AIINIT();AICOMMIT();
      bspbroad(0,(char *)&K ,(char *)&K ,sizeof(double));
   AISYNC();AIBARRIER(); AIDEREGISTER(&K    );

   AIREGISTER(&T,sizeof(int   )); AIINIT();AICOMMIT();
      bspbroad(0,(char *)&T ,(char *)&T ,sizeof(int));
   AISYNC();AIBARRIER(); AIDEREGISTER(&T    );

   AIREGISTER(&blocksize,sizeof(int   )); AIINIT();AICOMMIT();
      bspbroad(0,(char *)&blocksize ,(char *)&blocksize ,sizeof(int));
   AISYNC();AIBARRIER(); AIDEREGISTER(&blocksize    );

   AIREGISTER(&S,sizeof(double)); AIINIT();AICOMMIT();
      bspbroad(0,(char *)&S ,(char *)&S ,sizeof(double));
   AISYNC();AIBARRIER(); AIDEREGISTER(&S    );

   AIREGISTER(&r,sizeof(double)); AIINIT();AICOMMIT();
      bspbroad(0,(char *)&r ,(char *)&r ,sizeof(double));
   AISYNC();AIBARRIER(); AIDEREGISTER(&r    );

   AIREGISTER(&u,sizeof(double)); AIINIT();AICOMMIT();
      bspbroad(0,(char *)&u ,(char *)&u ,sizeof(double));
   AISYNC();AIBARRIER(); AIDEREGISTER(&u    );

   AIREGISTER(&d,sizeof(double)); AIINIT();AICOMMIT();
      bspbroad(0,(char *)&d ,(char *)&d ,sizeof(double));
   AISYNC();AIBARRIER(); AIDEREGISTER(&d    );

   AIREGISTER(&N        ,sizeof(int   )); AIINIT();AICOMMIT();
      bspbroad(0,(char *)&N         ,(char *)&N         ,sizeof(int));
   AISYNC();AIBARRIER(); AIDEREGISTER(&N            );

   if ((nprocs-1)==pid) {
     fprintf(stdout,"proc=%d ::K=%f T=%d S=%f r=%f N=%d, u=%f d=%f b=%d\n",
     pid,K,T,S,r,N,u,d,blocksize); 
     fflush(stdout);
   }
   AIBARRIER();
   t1=0.0;
   AIBARRIER();
   t3=AITIME();
   bt(K,T,S,r,N,u,d,blocksize,&rst,&rc);
   AIBARRIER();
   t4=AITIME();
   t1 += (t4-t3);
   PRINTMAT(EuroCall);
   if (0 == pid) {
    printf("RunningTime= %8.5f-%8.5f (p=%d,L=%5.1f,g=%5.3f) (%14.9f %10.7f)\n",(t3),(t4),AINPROCS(),AIL(),AIG(),rc,rst);
   }
   AIEND();  
   return(0);
}

/***** Create a file called mdata
 ** 100.0
 ** 1
 ** 100.0
 ** 0.06
 ** 3
 ** 1.01
 ** 0.990099
 * and run bsprun -noload -local -npes 16 executable 32  8192 <mdata
 * or      mpirun                -np   16 executable 32  8192 <mdata
 * If everything works fine you should get
 * one of
 * EuropeanCallOption =    36.719441816  
 * EuropeanPutOption  =    30.895895174  
 * AmericanCallOption =    36.719441816  
 * AmericanPutOption  =    31.658198031  
 * in the output that looks like
 *proc=15 ::K=100.000000 T=1 S=100.000000 r=0.060000 N=8192, u=1.010000 \
 *d=0.990099 b=64
 *RunningTime=  1.12209- 1.12247 (p=16,L=28078.0,g=32.400) \
 *(  31.658198031 100.0000000)
 * Also for N=16384,32768, and 65536 the AmericanPutOption values are
 * 44.21663531, 59.61855590, 76.02769387. Same results should be given
 * by the sequential program moption.c.
 */



