// File: /workspace/github_cpp_makefile_star2_O3/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 0x8c(%rsp), %rax
movl %edi, (%rax)
leaq 0xe8(%rsp), %rbx
movq %rsi, (%rbx)
movq %rax, %rdi
movq %rbx, %rsi
callq 0x2270
callq 0x22d0
movq (%rbx), %rbx
movq 0x10(%rbx), %rdi
callq 0x2240
movsd %xmm0, (%rsp)
movq 0x8(%rbx), %rsi
leaq 0xb0(%rsp), %rdi
leaq 0x128(%rsp), %rdx
callq 0x3236
movq 0x862d(%rip), %rbx      # 0xafd0
movq 0x8(%rbx), %rdi
leaq 0x128(%rsp), %rsi
callq 0x2260
leaq 0x128(%rsp), %rsi
movl (%rsi), %ebp
movq 0x8(%rbx), %rdi
callq 0x2210
cvttsd2si (%rsp), %eax
cltd
idivl 0x128(%rsp)
leal 0x1(%rax), %ebx
movl %ebp, %r15d
subl %edx, %r15d
jge 0x29eb
movl %ebx, %r15d
imull %ebp, %r15d
addl %r15d, %ebx
jmp 0x29fa
imull %ebx, %edx
imull %eax, %r15d
addl %edx, %r15d
addl %r15d, %eax
movl %eax, %ebx
leaq 0xa0(%rsp), %r14
movq %r14, -0x10(%r14)
movq 0xb0(%rsp), %rsi
movq 0xb8(%rsp), %rdx
addq %rsi, %rdx
leaq 0x90(%rsp), %rdi
callq 0x33e4
leaq 0xd0(%rsp), %rdi
leaq 0x90(%rsp), %rsi
movl %r15d, %edx
movl %ebx, %ecx
callq 0x26fe
movq 0x90(%rsp), %rdi
cmpq %r14, %rdi
je 0x2a5d
movq 0xa0(%rsp), %rsi
incq %rsi
callq 0x21e0
xorps %xmm0, %xmm0
movaps %xmm0, 0x30(%rsp)
movq $0x0, 0x40(%rsp)
movq 0x877b(%rip), %rdi      # 0xb1f0
callq 0x4612
movq 0x8777(%rip), %rdi      # 0xb1f8
callq 0x4612
leaq 0x558b(%rip), %rsi      # 0x8018
leaq 0xf0(%rsp), %rdi
movl %ebp, %edx
xorl %eax, %eax
callq 0x2060
leaq 0x18(%rsp), %rax
movq %rax, -0x10(%rax)
leaq 0x556d(%rip), %rsi      # 0x801b
leaq 0x556c(%rip), %rdx      # 0x8021
leaq 0x8(%rsp), %rdi
callq 0x347a
leaq 0x555c(%rip), %rsi      # 0x8022
leaq 0x8(%rsp), %rdi
callq 0x23a0
leaq 0x8(%rsp), %rdi
leaq 0xf0(%rsp), %rsi
callq 0x23a0
leaq 0x57fd(%rip), %rsi      # 0x82e6
leaq 0x8(%rsp), %rdi
callq 0x23a0
leaq 0x128(%rsp), %rdi
callq 0x2320
movq 0x8(%rsp), %rsi
leaq 0x128(%rsp), %rdi
movl $0x10, %edx
callq 0x2050
movq %r15, 0x48(%rsp)
subl %r15d, %ebx
jle 0x2fd3
movl %ebx, %eax
movq %rax, 0x50(%rsp)
xorl %r14d, %r14d
leaq 0x30(%rsp), %r15
leaq 0x128(%rsp), %r13
leaq 0x54e7(%rip), %rbp      # 0x802a
leaq (%r14,%r14,2), %rsi
shlq $0x3, %rsi
addq 0xd0(%rsp), %rsi
movq %r15, %rdi
callq 0x3274
movq 0x868e(%rip), %rbx      # 0xb1f0
leaq 0x70(%rsp), %rdi
movq %r15, %rsi
callq 0x3358
movq %rbx, %rdi
leaq 0x70(%rsp), %rsi
callq 0x41ed
movq 0x70(%rsp), %rdi
testq %rdi, %rdi
je 0x2b96
movq 0x80(%rsp), %rsi
subq %rdi, %rsi
callq 0x21e0
movq 0x865b(%rip), %rbx      # 0xb1f8
leaq 0x58(%rsp), %rdi
movq %r15, %rsi
callq 0x3358
movq %rbx, %rdi
leaq 0x58(%rsp), %rsi
callq 0x41ed
movq 0x58(%rsp), %rdi
testq %rdi, %rdi
je 0x2bce
movq 0x68(%rsp), %rsi
subq %rdi, %rsi
callq 0x21e0
movq 0x861b(%rip), %rdi      # 0xb1f0
callq 0x3dbf
movq 0x8617(%rip), %rdi      # 0xb1f8
callq 0x3dbf
movq 0x8603(%rip), %rdi      # 0xb1f0
cmpl $0x1, 0x58(%rdi)
jne 0x2c23
callq 0x786c
movq 0x85f9(%rip), %rdi      # 0xb1f8
callq 0x786c
movq 0x85e5(%rip), %rdi      # 0xb1f0
callq 0x7480
movq 0x85e1(%rip), %rdi      # 0xb1f8
callq 0x7480
movq 0x85cd(%rip), %rdi      # 0xb1f0
movq 0x85ce(%rip), %rsi      # 0xb1f8
callq 0x25cc
movq %r14, 0x28(%rsp)
movq 0x85b5(%rip), %rax      # 0xb1f0
cmpl $0x0, (%rax)
jle 0x2fbb
movq 0x48(%rsp), %rcx
movq 0x28(%rsp), %rdx
leal (%rcx,%rdx), %ebx
xorl %r14d, %r14d
xorl %r15d, %r15d
cmpl $0x1, 0x58(%rax)
jne 0x2c80
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 0x2c8a
movq 0x128(%rax), %rax
addq %r14, %rax
movsd (%rax), %xmm0
movsd %xmm0, (%rsp)
movq %r13, %rdi
movl %ebx, %esi
callq 0x2330
movq %rax, %r12
movl $0x1, %edx
movq %rax, %rdi
movq %rbp, %rsi
callq 0x2200
movq %r12, %rdi
movl %r15d, %esi
callq 0x2330
movq %rax, %r12
movl $0x1, %edx
movq %rax, %rdi
movq %rbp, %rsi
callq 0x2200
movq 0x851b(%rip), %rax      # 0xb1f0
movq 0x368(%rax), %rax
movsd (%rax,%r14), %xmm0
movq %r12, %rdi
callq 0x22f0
movq %rax, %r12
movl $0x1, %edx
movq %rax, %rdi
movq %rbp, %rsi
callq 0x2200
movq 0x84ec(%rip), %rax      # 0xb1f0
movq 0x288(%rax), %rax
movsd (%rax,%r14), %xmm0
movq %r12, %rdi
callq 0x22f0
movq %rax, %r12
movl $0x1, %edx
movq %rax, %rdi
movq %rbp, %rsi
callq 0x2200
movq 0x84bd(%rip), %rax      # 0xb1f0
movq 0x2c8(%rax), %rax
movsd (%rax,%r14), %xmm0
movq %r12, %rdi
callq 0x22f0
movq %rax, %r12
movl $0x1, %edx
movq %rax, %rdi
movq %rbp, %rsi
callq 0x2200
movq 0x848e(%rip), %rax      # 0xb1f0
movq 0x328(%rax), %rax
movsd (%rax,%r14), %xmm0
movq %r12, %rdi
callq 0x22f0
movq %rax, %r12
movl $0x1, %edx
movq %rax, %rdi
movq %rbp, %rsi
callq 0x2200
movq 0x845f(%rip), %rax      # 0xb1f0
movq 0x390(%rax), %rax
movsd (%rax,%r14), %xmm0
movq %r12, %rdi
callq 0x22f0
movq %rax, %r12
movl $0x1, %edx
movq %rax, %rdi
movq %rbp, %rsi
callq 0x2200
movq 0x8430(%rip), %rax      # 0xb1f0
movq 0x398(%rax), %rax
movsd (%rax,%r14), %xmm0
movq %r12, %rdi
callq 0x22f0
movq %rax, %r12
movl $0x1, %edx
movq %rax, %rdi
movq %rbp, %rsi
callq 0x2200
movq 0x8401(%rip), %rax      # 0xb1f0
movq 0x358(%rax), %rax
movsd (%rax,%r14), %xmm0
movq %r12, %rdi
callq 0x22f0
movq %rax, %r12
movl $0x1, %edx
movq %rax, %rdi
movq %rbp, %rsi
callq 0x2200
movq 0x83d2(%rip), %rax      # 0xb1f0
movq 0x348(%rax), %rax
movsd (%rax,%r14), %xmm0
movq %r12, %rdi
callq 0x22f0
movq %rax, %r12
movl $0x1, %edx
movq %rax, %rdi
movq %rbp, %rsi
callq 0x2200
movq 0x83a3(%rip), %rax      # 0xb1f0
movq 0x308(%rax), %rax
movsd (%rax,%r14), %xmm0
movq %r12, %rdi
callq 0x22f0
movq %rax, %r12
movl $0x1, %edx
movq %rax, %rdi
movq %rbp, %rsi
callq 0x2200
movq 0x8374(%rip), %rax      # 0xb1f0
movq 0x2b0(%rax), %rax
movsd (%rax,%r14), %xmm0
movq %r12, %rdi
callq 0x22f0
movq %rax, %r12
movl $0x1, %edx
movq %rax, %rdi
movq %rbp, %rsi
callq 0x2200
movq %r12, %rdi
movsd (%rsp), %xmm0
callq 0x22f0
movq %rax, %r12
movl $0x1, %edx
movq %rax, %rdi
movq %rbp, %rsi
callq 0x2200
movq 0x8325(%rip), %rax      # 0xb1f0
movq 0x478(%rax), %rax
movsd (%rax,%r14), %xmm0
movq %r12, %rdi
callq 0x22f0
movq %rax, %r12
movl $0x1, %edx
movq %rax, %rdi
movq %rbp, %rsi
callq 0x2200
movq 0x82f6(%rip), %rax      # 0xb1f0
movq 0x470(%rax), %rax
movsd (%rax,%r14), %xmm0
movq %r12, %rdi
callq 0x22f0
movq %rax, %r12
movl $0x1, %edx
movq %rax, %rdi
movq %rbp, %rsi
callq 0x2200
movq 0x82c7(%rip), %rax      # 0xb1f0
movq 0x3c8(%rax), %rax
movsd (%rax,%r14), %xmm0
movq %r12, %rdi
callq 0x22f0
movq %rax, %r12
movl $0x1, %edx
movq %rax, %rdi
movq %rbp, %rsi
callq 0x2200
movq 0x8298(%rip), %rax      # 0xb1f0
movl 0x520(%rax), %esi
movq %r12, %rdi
callq 0x2330
movq %rax, %r12
movl $0x1, %edx
movq %rax, %rdi
movq %rbp, %rsi
callq 0x2200
movq (%r12), %rax
movq -0x18(%rax), %rdi
addq %r12, %rdi
movl $0xa, %esi
callq 0x21b0
movsbl %al, %esi
movq %r12, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2110
incq %r15
movq 0x8245(%rip), %rax      # 0xb1f0
movslq (%rax), %rcx
addq $0x8, %r14
cmpq %rcx, %r15
jl 0x2c57
movq 0x28(%rsp), %r14
incq %r14
cmpq 0x50(%rsp), %r14
leaq 0x30(%rsp), %r15
jne 0x2b43
leaq 0x128(%rsp), %rdi
callq 0x2280
callq 0x2140
movq 0x7fdc(%rip), %rax      # 0xafc8
movq (%rax), %rcx
movq 0x18(%rax), %rax
leaq 0x130(%rsp), %rdi
movq %rcx, -0x8(%rdi)
movq -0x18(%rcx), %rcx
movq %rax, 0x128(%rsp,%rcx)
callq 0x2190
leaq 0x220(%rsp), %rdi
callq 0x2090
movq 0x8(%rsp), %rdi
leaq 0x18(%rsp), %rax
cmpq %rax, %rdi
je 0x3039
movq 0x18(%rsp), %rsi
incq %rsi
callq 0x21e0
movq 0x30(%rsp), %rdi
testq %rdi, %rdi
je 0x3050
movq 0x40(%rsp), %rsi
subq %rdi, %rsi
callq 0x21e0
leaq 0xd0(%rsp), %rdi
callq 0x31e2
leaq 0xc0(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x307e
movq 0xc0(%rsp), %rsi
incq %rsi
callq 0x21e0
xorl %eax, %eax
addq $0x328, %rsp            # imm = 0x328
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x3111
jmp 0x30d7
jmp 0x30cf
movq %rax, %rbx
movq 0x90(%rsp), %rdi
cmpq %r14, %rdi
je 0x318c
movq 0xa0(%rsp), %rsi
incq %rsi
callq 0x21e0
jmp 0x318c
jmp 0x30c5
jmp 0x30c5
movq %rax, %rbx
jmp 0x318c
jmp 0x3111
movq %rax, %rbx
jmp 0x3168
movq %rax, %rbx
jmp 0x314c
movq %rax, %rbx
movq 0x70(%rsp), %rdi
testq %rdi, %rdi
je 0x3114
movq 0x80(%rsp), %rsi
jmp 0x3105
movq %rax, %rbx
movq 0x58(%rsp), %rdi
testq %rdi, %rdi
je 0x3114
movq 0x68(%rsp), %rsi
subq %rdi, %rsi
callq 0x21e0
jmp 0x3114
jmp 0x3111
movq %rax, %rbx
movq 0x7ead(%rip), %rax      # 0xafc8
movq (%rax), %rcx
movq 0x18(%rax), %rax
leaq 0x130(%rsp), %rdi
movq %rcx, -0x8(%rdi)
movq -0x18(%rcx), %rcx
movq %rax, 0x128(%rsp,%rcx)
callq 0x2190
leaq 0x220(%rsp), %rdi
callq 0x2090
leaq 0x18(%rsp), %rax
movq 0x8(%rsp), %rdi
cmpq %rax, %rdi
je 0x3168
movq 0x18(%rsp), %rsi
incq %rsi
callq 0x21e0
movq 0x30(%rsp), %rdi
testq %rdi, %rdi
je 0x317f
movq 0x40(%rsp), %rsi
subq %rdi, %rsi
callq 0x21e0
leaq 0xd0(%rsp), %rdi
callq 0x31e2
leaq 0xc0(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x31ad
movq 0xc0(%rsp), %rsi
incq %rsi
callq 0x21e0
movq %rbx, %rdi
callq 0x2350
nop