/***********************************************************
** Parallel Option Price valuations with the explicit finite
** difference method. 
**This is the testing function main() component
*Copyright (c) 2002-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    N, Nj, blocksize;
 int T;
 double result,sigma,dx,dividend;
 double rst, rc;


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

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

  /* Command line processing */
 n=8;debug=0;runs=1; 
 if (0 == pid ){
   if (3 != argc){
     printf("Usage: %s blocksize horizon <edata\n\
            Integer blocksize-1 must divide integer horizon\n\
            edata 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);
    scanf("%lf",&dx);
    scanf("%lf",&dividend);
    N= atoi(argv[2]);
    Nj=N;
   }
 }
   dx= sigma*sqrt(3.0*T/N);

   /* 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(&dx   ,sizeof(double)); AIINIT();AICOMMIT();
      bspbroad(0,(char *)&dx    ,(char *)&dx    ,sizeof(double));
   AISYNC();AIBARRIER(); AIDEREGISTER(&dx       );

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

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

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

#ifdef SANITY_CHECK
   if ((nprocs-1)==pid) {
     fprintf(stdout, "proc=%d ::K=%f T=%d S=%f r=%f N=%d Nj=%d, sigma=%f b=%d dx=%f dividend=%f\n", pid,K,T,S,r,N,Nj,sigma,blocksize,dx,dividend); 
     fflush(stdout);
   }
#endif

   AIBARRIER();
   t1=0.0;
   AIBARRIER();
   t3=AITIME();
   efd(K,T,S,r,N,sigma,dx,dividend,blocksize,&rst,&rc,Nj);
   AIBARRIER();
   t4=AITIME();
   t1 += (t4-t3);
   PRINTMAT(AmerPut );
   if (0 == pid) {
    printf("RunningTime= %8.5f-%8.5f (p=%3d,L=%5.1f,g=%5.2f,b=%4d)(%14.9f %10.7f)\n",(t3),(t4),AINPROCS(),AIL(),AIG(),blocksize,rc,rst);
   }

   AIEND();
   return(0);
}
/*** If edata is
 *100.0
 *1    <<<<<< Note: this is an integer
 *100.0
 *0.06
 *6 ***This is not actually used. The command line value supersedes it
 *0.2
 *0.2
 *0.03
 *6 *** This is not actually needed nore read. The command line value supersedes it.
 * 
 *Option prices for EXECUTABLE 8192 <edata
 * are as follows
 * EuropeanCallOption=    9.135002979 (S=  100.000000000)
 * EuropeanPutOption=    6.266882881 (S=  100.000000000)
 * 
 */
