// File: /workspace/github_cpp_makefile_star2_O2/JRLamontagne[P]cdice_sa/CDICEMain.cpp
// Function: main
int main(int argc, char* argv[])
{
	// Initialize MPI
	MPI::Init(argc,argv);
	
  // Obtain the number of iterations, from the input	
  int N = atof(argv[2]);
  
  // Obtain the CDICE input file name, from the input
  string filename = argv[1];
  
  // Get the number of processes, and the id of this process
  int rank = MPI::COMM_WORLD.Get_rank();
  int nprocs = MPI::COMM_WORLD.Get_size();

  // Determine the chunk which each processor will need to do.
  int count = N/nprocs;
  
  // We use the rank of this processor to determine which chunk of iterations it
  // will perform
  int start;
  int stop;
  int rem = N%nprocs;
  
  if(rank<rem) {
		start = rank*(count+1);
		stop = start+count+1;
  }
  else {
		start = rem*(count+1)+(rank-rem)*count;
		stop = start+count;
  }


/*	// DEBUG -----------------------------------------------------------------------------
	string filename = argv[1];
	string name = "./output/CDICE_DOECLIM_output.txt";
	int stop = 1;
	int start = 0;
	// -----------------------------------------------------------------------------------
*/	
	
  // Load-in the data
  vector< vector <double> > params = readFile(filename, start, stop);
  vector<double> params_hold;
  
  // Initialize the DICE structures
  // Note: Allocating here allows us to test for
  // DOECLIM.  We can then adjust the output filename
  // accordingly.
  allocateDICE(dicePtr);
  allocateDICE(dice2Ptr);
  
  //This code generates the file name based on processor rank
  char rnk [50];
  int l = sprintf(rnk,"%d",rank);
  string name = "CDICE_";
  name += "output_";
  name += rnk;
  name +=".txt";

	
  // This code opens the output file.
  ofstream myfile;
  myfile.open(name.c_str());
  
  // Loop over params
  int param_len = stop - start;
  for(int j=0; j<param_len; j++) {
	  params_hold = params[j];
	  
	  // Populate the parameter values with this current parameter sample
	  populateDICE(dicePtr, params_hold);
	  populateDICE(dice2Ptr, params_hold);
	  
	  // Initialize DICE for this set of parameters (if needed)
	  initTS(dicePtr);
	  initTS(dice2Ptr);
	  if(dicePtr->ctrl.use_doeclim == 1){
	  	doeclim_load_hind_forc(dicePtr);
	  	doeclim_load_hind_forc(dice2Ptr);
		  doeclim_DICE_init(dicePtr);
		  doeclim_DICE_init(dice2Ptr);	  
		}

	  // Run the model
	  calc_CDICE(dicePtr, dice2Ptr);
	  
	  //myfile <<-99<< " " <<start+j<< endl;
	  // Print the index of the factor set
	  
	  // PRINT OUT MODEL VARIABLES-------------------------------------------
	  // These time-series variables will be printed out to stdout forming
	  // space-delimited columns.  The output can be considered a matrix of
	  // size (dicePtr->config.nPeriods x N) where N is the number of
	  // variables being output.  Time increases with each row, so row 1 would
	  // be the initial time-step and row dicePtr->config.nPeriods would be
	  // the last.
  
	  // Here's currently what is being output
	  // Column: Variable
	  // 1			Utility of per-capita consumption for a given period
	  // 2			Population
	  // 3			Discount Factor
	  // 4			NPV Damages
	  // 5			NPV Abatement
	  // 6			Social cost of carbon
	  // 7			Gross Atmospheric temperature
	  // 8			Gross GWP
	  // 9			Cumulative Carbon
  
	  // Time series variables
	  for(int i=0; i<dicePtr->config.nPeriods; i++) {
	  	
	  	// Figure out which temperature variable to use
	  	double this_temp = 0.0;
	  	if(dicePtr->ctrl.use_doeclim == 1){
	  		this_temp = dicePtr->clim.temp[(dicePtr->config.hind_ns -1) + (i * (int)dicePtr->config.tstep)];
	  	}
	  	else {
	  		this_temp = dicePtr->clim.tatm[i];
	  	}
	
			// Print each time step's econ parameters to file
		  myfile << start+j << " "
		  << i << " "
		  << dicePtr->econ.periodu[i] << " "
		  << dicePtr->econ.l[i] << " "
		  << dicePtr->econ.rr[i] << " "
		  << dicePtr->econ.ri[i] << " "
		  << dicePtr->econ.pv_damages[i] << " "
		  << dicePtr->econ.pv_abatecost[i] << " "
		  << dicePtr->econ.abatecost[i] << " "
		  << dicePtr->econ.damages[i] << " "
		  << dicePtr->econ.c[i] << " "
		  << dicePtr->econ.scc[i] << " "
		  << this_temp << " "
		  << dicePtr->carb.mat[i] << " "
		  << dicePtr->carb.forc[i] << " "
		  << dicePtr->econ.cca[i] << " "
		  << dicePtr->lims.cca_up_step << " " << endl;
	  }	
  }

  myfile.close();
  MPI::Finalize();

  return 0;

}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x328, %rsp            # imm = 0x328
leaq 0x3c(%rsp), %rax
movl %edi, (%rax)
leaq 0xd0(%rsp), %rbx
movq %rsi, (%rbx)
movq %rax, %rdi
movq %rbx, %rsi
callq 0x2edf
movq (%rbx), %rbx
movq 0x10(%rbx), %rdi
callq 0x2210
movsd %xmm0, (%rsp)
movq 0x8(%rbx), %rsi
leaq 0xb0(%rsp), %rdi
leaq 0x128(%rsp), %rdx
callq 0x2eec
movq 0x8768(%rip), %rdi      # 0xafd0
callq 0x2f28
movl %eax, %ebx
movq 0x875a(%rip), %rdi      # 0xafd0
callq 0x2f46
movl %eax, %ecx
cvttsd2si (%rsp), %eax
cltd
idivl %ecx
leal 0x1(%rax), %r13d
movl %ebx, %r15d
subl %edx, %r15d
jge 0x289d
movl %r13d, %r15d
imull %ebx, %r15d
addl %r15d, %r13d
jmp 0x28ae
imull %r13d, %edx
imull %eax, %r15d
addl %edx, %r15d
addl %r15d, %eax
movl %eax, %r13d
leaq 0x90(%rsp), %rdi
leaq 0xb0(%rsp), %rsi
callq 0x2230
leaq 0x60(%rsp), %rdi
leaq 0x90(%rsp), %rsi
movl %r15d, %edx
movl %r13d, %ecx
callq 0x267e
leaq 0x90(%rsp), %rdi
callq 0x20c0
xorps %xmm0, %xmm0
movaps %xmm0, 0x10(%rsp)
andq $0x0, 0x20(%rsp)
movq 0x88e3(%rip), %rdi      # 0xb1e0
callq 0x4225
movq 0x88df(%rip), %rdi      # 0xb1e8
callq 0x4225
leaq 0x5703(%rip), %rsi      # 0x8018
leaq 0xf0(%rsp), %rdi
movl %ebx, %edx
xorl %eax, %eax
callq 0x2050
leaq 0x56ee(%rip), %rsi      # 0x801b
leaq 0x40(%rsp), %rdi
leaq 0x128(%rsp), %rdx
callq 0x2eec
leaq 0x56dc(%rip), %rsi      # 0x8022
leaq 0x40(%rsp), %rdi
callq 0x2380
leaq 0x40(%rsp), %rdi
leaq 0xf0(%rsp), %rsi
callq 0x2380
leaq 0x597d(%rip), %rsi      # 0x82e6
leaq 0x40(%rsp), %rdi
callq 0x2380
leaq 0x128(%rsp), %rdi
callq 0x2310
movq 0x40(%rsp), %rsi
leaq 0x128(%rsp), %rdi
pushq $0x10
popq %rdx
callq 0x2040
subl %r15d, %r13d
xorl %eax, %eax
testl %r13d, %r13d
cmovlel %eax, %r13d
leaq 0xd8(%rsp), %r12
leaq 0x128(%rsp), %rbp
leaq 0x5672(%rip), %rbx      # 0x802a
movq %r15, 0x30(%rsp)
movq %r13, 0x28(%rsp)
cmpq %r13, %rax
je 0x2d84
movq %rax, 0x8(%rsp)
imulq $0x18, %rax, %rsi
addq 0x60(%rsp), %rsi
leaq 0x10(%rsp), %rdi
callq 0x2f64
movq 0x87f6(%rip), %r14      # 0xb1e0
movq %r12, %rdi
leaq 0x10(%rsp), %rsi
callq 0x302e
movq %r14, %rdi
movq %r12, %r14
movq %r12, %rsi
callq 0x3e06
movq %r14, %rdi
callq 0x30e8
movq 0x87d4(%rip), %r14      # 0xb1e8
leaq 0x78(%rsp), %rdi
leaq 0x10(%rsp), %rsi
callq 0x302e
movq %r14, %rdi
leaq 0x78(%rsp), %r14
movq %r14, %rsi
callq 0x3e06
movq %r14, %rdi
callq 0x30e8
movq 0x879e(%rip), %rdi      # 0xb1e0
callq 0x3acd
movq 0x879a(%rip), %rdi      # 0xb1e8
callq 0x3acd
movq 0x8786(%rip), %rdi      # 0xb1e0
cmpl $0x1, 0x58(%rdi)
jne 0x2a90
callq 0x729d
movq 0x877c(%rip), %rdi      # 0xb1e8
callq 0x729d
movq 0x8768(%rip), %rdi      # 0xb1e0
callq 0x6f08
movq 0x8764(%rip), %rdi      # 0xb1e8
callq 0x6f08
movq 0x8750(%rip), %rdi      # 0xb1e0
movq 0x8751(%rip), %rsi      # 0xb1e8
callq 0x253c
movq 0x8(%rsp), %rax
leal (%r15,%rax), %r14d
xorl %r13d, %r13d
xorl %r15d, %r15d
movq 0x872e(%rip), %rax      # 0xb1e0
movslq (%rax), %rcx
cmpq %rcx, %r15
jge 0x2d6d
cmpl $0x1, 0x58(%rax)
jne 0x2ae7
movq 0x140(%rax), %rcx
movslq 0x20(%rax), %rdx
cvttsd2si 0x8(%rax), %eax
imull %r15d, %eax
cltq
addq %rdx, %rax
leaq (%rcx,%rax,8), %rax
addq $-0x8, %rax
jmp 0x2af1
movq 0x128(%rax), %rax
addq %r13, %rax
movsd (%rax), %xmm0
movsd %xmm0, (%rsp)
movq %rbp, %rdi
movl %r14d, %esi
callq 0x2320
movq %rax, %rdi
movq %rbx, %rsi
callq 0x2190
movq %rax, %rdi
movl %r15d, %esi
callq 0x2320
movq %rax, %rdi
movq %rbx, %rsi
callq 0x2190
movq 0x86b3(%rip), %rcx      # 0xb1e0
movq 0x368(%rcx), %rcx
movsd (%rcx,%r13), %xmm0
movq %rax, %rdi
callq 0x22e0
movq %rax, %rdi
movq %rbx, %rsi
callq 0x2190
movq 0x868c(%rip), %rcx      # 0xb1e0
movq 0x288(%rcx), %rcx
movsd (%rcx,%r13), %xmm0
movq %rax, %rdi
callq 0x22e0
movq %rax, %rdi
movq %rbx, %rsi
callq 0x2190
movq 0x8665(%rip), %rcx      # 0xb1e0
movq 0x2c8(%rcx), %rcx
movsd (%rcx,%r13), %xmm0
movq %rax, %rdi
callq 0x22e0
movq %rax, %rdi
movq %rbx, %rsi
callq 0x2190
movq 0x863e(%rip), %rcx      # 0xb1e0
movq 0x328(%rcx), %rcx
movsd (%rcx,%r13), %xmm0
movq %rax, %rdi
callq 0x22e0
movq %rax, %rdi
movq %rbx, %rsi
callq 0x2190
movq 0x8617(%rip), %rcx      # 0xb1e0
movq 0x390(%rcx), %rcx
movsd (%rcx,%r13), %xmm0
movq %rax, %rdi
callq 0x22e0
movq %rax, %rdi
movq %rbx, %rsi
callq 0x2190
movq 0x85f0(%rip), %rcx      # 0xb1e0
movq 0x398(%rcx), %rcx
movsd (%rcx,%r13), %xmm0
movq %rax, %rdi
callq 0x22e0
movq %rax, %rdi
movq %rbx, %rsi
callq 0x2190
movq 0x85c9(%rip), %rcx      # 0xb1e0
movq 0x358(%rcx), %rcx
movsd (%rcx,%r13), %xmm0
movq %rax, %rdi
callq 0x22e0
movq %rax, %rdi
movq %rbx, %rsi
callq 0x2190
movq 0x85a2(%rip), %rcx      # 0xb1e0
movq 0x348(%rcx), %rcx
movsd (%rcx,%r13), %xmm0
movq %rax, %rdi
callq 0x22e0
movq %rax, %rdi
movq %rbx, %rsi
callq 0x2190
movq 0x857b(%rip), %rcx      # 0xb1e0
movq 0x308(%rcx), %rcx
movsd (%rcx,%r13), %xmm0
movq %rax, %rdi
callq 0x22e0
movq %rax, %rdi
movq %rbx, %rsi
callq 0x2190
movq 0x8554(%rip), %rcx      # 0xb1e0
movq 0x2b0(%rcx), %rcx
movsd (%rcx,%r13), %xmm0
movq %rax, %rdi
callq 0x22e0
movq %rax, %rdi
movq %rbx, %rsi
callq 0x2190
movq %rax, %rdi
movsd (%rsp), %xmm0
callq 0x22e0
movq %rax, %rdi
movq %rbx, %rsi
callq 0x2190
movq 0x8515(%rip), %rcx      # 0xb1e0
movq 0x478(%rcx), %rcx
movsd (%rcx,%r13), %xmm0
movq %rax, %rdi
callq 0x22e0
movq %rax, %rdi
movq %rbx, %rsi
callq 0x2190
movq 0x84ee(%rip), %rcx      # 0xb1e0
movq 0x470(%rcx), %rcx
movsd (%rcx,%r13), %xmm0
movq %rax, %rdi
callq 0x22e0
movq %rax, %rdi
movq %rbx, %rsi
callq 0x2190
movq 0x84c7(%rip), %rcx      # 0xb1e0
movq 0x3c8(%rcx), %rcx
movsd (%rcx,%r13), %xmm0
movq %rax, %rdi
callq 0x22e0
movq %rax, %rdi
movq %rbx, %rsi
callq 0x2190
movq 0x84a0(%rip), %rcx      # 0xb1e0
movl 0x520(%rcx), %esi
movq %rax, %rdi
callq 0x2320
movq %rax, %rdi
movq %rbx, %rsi
callq 0x2190
movq %rax, %rdi
callq 0x20d0
incq %r15
addq $0x8, %r13
jmp 0x2aab
movq 0x8(%rsp), %rax
incq %rax
movq 0x30(%rsp), %r15
movq 0x28(%rsp), %r13
jmp 0x29c2
leaq 0x128(%rsp), %rdi
callq 0x2260
callq 0x2130
leaq 0x128(%rsp), %rdi
callq 0x2280
leaq 0x40(%rsp), %rdi
callq 0x20c0
leaq 0x10(%rsp), %rdi
callq 0x30e8
leaq 0x60(%rsp), %rdi
callq 0x2ebe
leaq 0xb0(%rsp), %rdi
callq 0x20c0
xorl %eax, %eax
addq $0x328, %rsp            # imm = 0x328
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x2e2d
jmp 0x2e0a
jmp 0x2e05
movq %rax, %rbx
leaq 0x90(%rsp), %rdi
callq 0x20c0
jmp 0x2e5b
jmp 0x2dfe
jmp 0x2dfe
movq %rax, %rbx
jmp 0x2e5b
jmp 0x2e2d
movq %rax, %rbx
jmp 0x2e47
movq %rax, %rbx
jmp 0x2e3d
movq %rax, %rbx
leaq 0xd8(%rsp), %rdi
jmp 0x2e24
movq %rax, %rbx
leaq 0x78(%rsp), %rdi
callq 0x30e8
jmp 0x2e30
jmp 0x2e2d
movq %rax, %rbx
leaq 0x128(%rsp), %rdi
callq 0x2280
leaq 0x40(%rsp), %rdi
callq 0x20c0
leaq 0x10(%rsp), %rdi
callq 0x30e8
leaq 0x60(%rsp), %rdi
callq 0x2ebe
leaq 0xb0(%rsp), %rdi
callq 0x20c0
movq %rbx, %rdi
callq 0x2340