/*============================================================================

 Function      main

 Description   Solves a standard stochastic ramsey model via value function
               iteration on a CPU and/or GPU. The flags 'gpusolve' and
	       'cpusolve' allow the user to solve the the problem on only the
	       CPU, the GPU or both. The maximization step at each  iteration
	       of the algorithm is carried out by a grid or binary search
	       method. The variable 'max' specifies the type of maximation
	       method to use, and is defined in 'globalvars.cpp'. Economic
	       variables and grid sizes are also defined in 'globalvars.cpp'.

 Dependencies  Global variables: nk, nz (globalvars.h).

               Functions:        clock() (ctime.h);
	                         cblas_daxpy, cblas_idamax (cblas.h);
				 vfiCPU, vfiGPU (auxfuncs.h).

 Return value  Returns 0 upon successful completion, 1 otherwise.

 =============================================================================

 Author:       Eric M. Aldrich

 Contact:      ealdrich@gmail.com

 Date:         20 April 2010

 ============================================================================*/

#include "globalvars.h"
#include "auxfuncs.h"
#include <iostream>
#include <ctime>
extern "C" {
  #include "cblas.h"
}

using namespace std;

int main()
{

  // admin
  int i,j;
  clock_t start;
  const bool gpusolve = true;
  const bool cpusolve = true;

  // declare value (V) and policy (G) function matrices
  double* Vgpu = new double[nk*nz];
  double* Ggpu = new double[nk*nz];
  double* Vcpu = new double[nk*nz];
  double* Gcpu = new double[nk*nz];

  // vfi on gpu
  if(gpusolve){
    start = clock();
    vfiGPU(Vgpu, Ggpu);
    cout << "GPU Total Time: " << (clock() - start)/(double)CLOCKS_PER_SEC << endl;
  }

  // vfi on cpu
  if(cpusolve){
    start = clock();
    vfiCPU(Vcpu, Gcpu);
    cout << "CPU Solve Time: " << (clock() - start)/(double)CLOCKS_PER_SEC << endl;
  }

  // report max abs diff between GPU and CPU value functions and policy functions
  if(gpusolve & cpusolve){
    int maxVdiff, maxGdiff;
    cblas_daxpy(nk*nz, -1.0, Vcpu, 1, Vgpu, 1);
    cblas_daxpy(nk*nz, -1.0, Gcpu, 1, Ggpu, 1);
    maxVdiff = cblas_idamax(nk*nz, Vgpu, 1);
    maxGdiff = cblas_idamax(nk*nz, Ggpu, 1);
    cout << "Max Absolute Difference for CPU and GPU Value Functions : " << Vgpu[maxVdiff] << endl;
    cout << "Max Absolute Difference for CPU and GPU Policy Functions : " << Ggpu[maxGdiff] << endl;
  }  

  return 0;
}
