#include<stdio.h>
#include "allvars.h"
#include "proto.h"


// Main Code
int main(int argc, char * argv[])
{

	char srank[4];
	double elapsed;

        // DAV: the corresponding KernelLen is calculated within the wstack function. It can be anyway hardcoded for optimization
        dx = 1.0/(double)grid_size_x;
        dw = 1.0/(double)num_w_planes;
        w_supporth = (double)((w_support-1)/2)*dx;
  
        if(argc > 1)
        {
          strcpy(in.paramfile,argv[1]);
        }
        else
        {
          fprintf(stderr, "Parameter file is not given\n");
          exit(1);
        }
 
        clock_gettime(CLOCK_MONOTONIC, &begin0);
   	start0 = clock();

        /* Initializing MPI Environment */

        #ifdef USE_MPI
		MPI_Init(&argc,&argv);
		MPI_Comm_rank(MPI_COMM_WORLD, &rank);
		MPI_Comm_size(MPI_COMM_WORLD, &size);
		if(rank == 0)printf("Running with %d MPI tasks\n",size);
		#ifdef USE_FFTW
			fftw_mpi_init();
  		#endif
	#else
		rank = 0;
		size = 1;
	#endif
	#ifdef ACCOMP
	  if(rank == 0){
  		if (0 == omp_get_num_devices()) {
      			printf("No accelerator found ... exit\n");
      			exit(255);
  		 }
   		printf("Number of available GPUs %d\n", omp_get_num_devices());
   		#ifdef NVIDIA
      			prtAccelInfo();
   		#endif
 	  }  
	#endif

        /* Reading Parameter file */

        read_parameter_file(in.paramfile);

        if ( param.num_threads == 0 )
        {
                fprintf(stderr, "Usage: %s number_of_OMP_Threads \n", param.num_threads);
                exit(1);
        }

      
        for(int ifiles=0; ifiles<param.ndatasets; ifiles++)
        {
              if(rank == 0)
              	printf( "\nDataset %d\n", ifiles);

              /*INIT function */
              init(ifiles);

              /* GRIDDING function */
              gridding();

              /* WRITE_GRIDED_DATA function */
              write_grided_data();

              /* FFTW_DATA function */
              fftw_data();

              /* WRITE_FFTW_DATA function */
              write_fftw_data();
           

              /* WRITE_RESULT function */
              write_result();

              if(rank == 0)
              	 printf("*************************************************************\n"); 

       }
       
       //Close MPI Environment
       
       #ifdef USE_MPI
         MPI_Finalize();
       #endif

}
