/**********************************************************
**GeneralizedBinomialTree 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 	i,j,k,n,nprocs,runs,debug,pid,option;
 double t3,t4,t1,a,b,c;
 char hostname[512];
 double K, S,r,u,d;
 int    T,N,blocksize;
 double result,sigma;
 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 <gdata\n\
            Integer blocksize-1 must divide integer horizon\n\
            gdata 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",&sigma);
    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(&sigma,sizeof(double)); AIINIT();AICOMMIT();
      bspbroad(0,(char *)&sigma ,(char *)&sigma ,sizeof(double));
   AISYNC();AIBARRIER(); AIDEREGISTER(&sigma    );

   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, sigma=%f b=%d\n",
     pid,K,T,S,r,N,sigma,blocksize); 
     fflush(stdout);
   }
   AIBARRIER();
   t1=0.0;
   AIBARRIER();
   t3=AITIME();
   gbt(K,T,S,r,N,sigma,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 gdata
 ** 100.0
 ** 1
 ** 100.0
 ** 0.06
 ** 3
 ** 0.2
 * and run bsprun -noload -local -npes 16 executable 32  8192 <gdata
 * or      mpirun                -np   16 executable 32  8192 <gdata
 * If everything works fine you should get
 * one of
 *K=100.0 T=1 S=100.0 r=0.06 N=8192,sigma=0.20 dt=0.000122 v=0.0400 
 *dxu=0.002210 dxd=-0.002210 pu=0.501105 pd=0.498895 discount=0.999993 
 *barrier=8192.000000
 *EuropeanCallOption =    10.989316051 (S= 100.000000) (Time=3.250000)
 *EuropeanPutOption  =     5.165777547 (S= 100.000000) (Time=1.630000)
 *AmericanCallOption =    10.989316051 (S= 100.000000) (Time=3.990000)
 *AmericanPutOption  =     5.798868043 (S= 100.000000) (Time=1.880000)
 *
 *barrier=16384.000000
 *EuropeanCallOption =    10.989432601 (S= 100.000000) (Time=18.580000)
 *EuropeanPutOption  =     5.165890028 (S= 100.000000) (Time=7.710000)
 *AmericanCallOption =    10.989432601 (S= 100.000000) (Time=26.200000)
 *AmericanPutOption  =     5.798902014 (S= 100.000000) (Time=11.730000)
 *
 *barrier=32768.000000
 *EuropeanCallOption =    10.989490877 (S= 100.000000) (Time=102.790000)
 *EuropeanPutOption  =     5.165946269 (S= 100.000000) (Time=37.750000)
 *AmericanCallOption =    10.989490877 (S= 100.000000) (Time=139.910000)
 *AmericanPutOption  =     5.798918955 (S= 100.000000) (Time=55.100000)
 *
 */



