// File: /workspace/github_cpp_makefile_star2_O1/uclaopt[P]AsyncQVI/src/test.cc
// Function: main
int main(int argc, char** argv){
	
	/* Step 0: load parameters from makefile.(defined in util.h) */
	Params params;
	parse_input_argv(&params, argc, argv);
	params.time = get_wall_time(); 
	cout<<"iter time reward flag"<<endl;
	
	/* Step 1: choose an algorithm in makefile 
	   -algo 0 is AsyncQVI, 
	         1 is Qlearning,
			 2 is VRVI 
			 3 is VRQVI  */
	
	// policy vector
	std::vector<int> pi(params.len_state, 0.);
	pthread_barrier_init(&barrier, &attr, params.total_num_threads);
	
	 if(params.algo == 0){ // run AsyncQVI
		// state value, V[i] = max_a Q(i,a)
		std::vector<double> V(params.len_state, 0.); 
		
		// QVI object (defined in algo.h)
		QVI obj(&V, &pi, &params);
		
		// launch parallel threads
		std::vector<std::thread> mythreads;
		for (size_t i = 0; i < params.total_num_threads; i++) {
			mythreads.push_back(std::thread(asyncQVI, i, obj, &params));
		} 
		for (size_t i = 0; i < params.total_num_threads; i++) {
			mythreads[i].join();
		}
	}
	
	else if(params.algo == 1){ // run Async Q-learning
		// Q value
		std::vector<std::vector<double>> Q(params.len_state, std::vector<double>(params.len_action, 0.));
		// state value, V[i] = max_a Q(i,a)
		std::vector<double> V(params.len_state);
		
		// Qlearning object (defined in algo.h)
		Qlearning obj(&Q, &V, &pi, &params);
		
		// launch parallel threads
		std::vector<std::thread> mythreads;
		for (size_t i = 0; i < params.total_num_threads; i++) {
			mythreads.push_back(std::thread(asyncQL, i, obj, &params));
		} 
		for (size_t i = 0; i < params.total_num_threads; i++) {
			mythreads[i].join();
		}
	}
	
	else if(params.algo == 2){ // run VRVI: Variance Reduced Value Iteration..., Sidford et al. 2018
		// \tilde{x} in Alg.8 
		std::vector<std::vector<double>> x(params.len_state, std::vector<double>(params.len_action, 0.));
		// v_k in Alg.9
		std::vector<double> v_outer(params.len_state, 0.);
		// v_t in Alg.8
		std::vector<double> v_inner(params.len_state, 0.);
		
		// VRVI object (defined in algo.h)
		VRVI obj(&x, &v_outer, &v_inner, &pi, &params); 
		obj.solve();
	}
	
	else{ // run VRQVI: Near-Optimal Time and Sample Complexities..., Sidford et al. 2018
		// Q, w in Alg.1
		std::vector<std::vector<double>> Q(params.len_state, std::vector<double>(params.len_action, 0.));
		std::vector<std::vector<double>> w(params.len_state, std::vector<double>(params.len_action, 0.));		
		// v^i in Alg.2
		std::vector<double> v_outer(params.len_state, 0.);
		// v^i in Alg.1
		std::vector<double> v_inner(params.len_state, 0.);
		
		// VRQVI object (defined in algo.h)
		VRQVI obj(&Q, &w, &v_outer, &v_inner, &pi, &params); 
		obj.solve();
	}
	
	// Step 2: save results
	if(params.save){
		std::ofstream outFile("policy.txt");
		for (int i = 0; i < params.len_state; i++){
			outFile << pi[i] << "\n";
		}
		outFile.close();
	}
	return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x1638, %rsp           # imm = 0x1638
movq %rsi, %rdx
movl %edi, %esi
xorl %r15d, %r15d
leaq 0xa0(%rsp), %rbx
movq %r15, 0x8(%rbx)
movabsq $0x3fa999999999999a, %rax # imm = 0x3FA999999999999A
movq %rax, 0x10(%rbx)
movabsq $0x3fefae147ae147ae, %rax # imm = 0x3FEFAE147AE147AE
movq %rax, 0x18(%rbx)
movabsq $0xc800000064, %rax     # imm = 0xC800000064
movq %rax, 0x20(%rbx)
movaps 0x2d8b(%rip), %xmm0     # 0x6060
movups %xmm0, 0x30(%rbx)
movl $0x1, 0x40(%rbx)
movabsq $0x3fd3333333333333, %rax # imm = 0x3FD3333333333333
movq %rax, 0x48(%rbx)
movabsq $0x3ff0000000000000, %rax # imm = 0x3FF0000000000000
movq %rax, 0x50(%rbx)
movq %r15, 0x70(%rbx)
movq %r15, 0x80(%rbx)
xorps %xmm0, %xmm0
movups %xmm0, 0x58(%rbx)
movl %r15d, 0x68(%rbx)
movq %rbx, %rdi
callq 0x256c
callq 0x2e6c
movsd %xmm0, 0x78(%rbx)
movq 0x5cad(%rip), %r14      # 0x8fd8
leaq 0x2e91(%rip), %rsi      # 0x61c3
movl $0x15, %edx
movq %r14, %rdi
callq 0x2220
movq (%r14), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x21e0
movsbl %al, %esi
movq %r14, %rdi
callq 0x2030
movq %rax, %rdi
callq 0x2100
movslq (%rbx), %rsi
leaq 0x128(%rsp), %rdx
movl %r15d, (%rdx)
leaq 0x80(%rsp), %rdi
leaq 0x68(%rsp), %rcx
callq 0x40fa
movl 0x30(%rbx), %edx
leaq 0x71e8(%rip), %rdi      # 0xa578
leaq 0x7229(%rip), %rsi      # 0xa5c0
callq 0x22f0
movl 0x28(%rbx), %eax
cmpl $0x2, %eax
je 0x366c
cmpl $0x1, %eax
je 0x34ee
testl %eax, %eax
jne 0x378d
movslq 0xa0(%rsp), %rsi
leaq 0x128(%rsp), %rdx
movq $0x0, (%rdx)
leaq 0x68(%rsp), %rdi
leaq 0x30(%rsp), %rcx
callq 0x4178
leaq 0x128(%rsp), %rdi
leaq 0x68(%rsp), %rsi
leaq 0x80(%rsp), %rdx
leaq 0xa0(%rsp), %rcx
callq 0x41fa
xorps %xmm0, %xmm0
movaps %xmm0, 0x30(%rsp)
xorl %eax, %eax
movq %rax, 0x40(%rsp)
movq %rax, 0x10(%rsp)
cmpl $0x0, 0xd0(%rsp)
je 0x3494
leaq -0x343(%rip), %r14      # 0x30e3
leaq 0x50(%rsp), %r15
leaq 0x10(%rsp), %r12
leaq 0x128(%rsp), %r13
leaq 0x48(%rsp), %rbp
leaq 0x30(%rsp), %rbx
leaq 0xa0(%rsp), %rax
movq %rax, 0x48(%rsp)
movq %r15, %rdi
movq %r14, %rsi
movq %r12, %rdx
movq %r13, %rcx
movq %rbp, %r8
callq 0x429c
movq %rbx, %rdi
movq %r15, %rsi
callq 0x5a12
cmpq $0x0, 0x50(%rsp)
jne 0x3b01
movq 0x10(%rsp), %rax
incq %rax
movq %rax, 0x10(%rsp)
movslq 0xd0(%rsp), %rcx
cmpq %rcx, %rax
jb 0x3442
cmpl $0x0, 0xd0(%rsp)
je 0x34c4
xorl %ebx, %ebx
xorl %r14d, %r14d
movq 0x30(%rsp), %rdi
addq %rbx, %rdi
callq 0x2330
incq %r14
movslq 0xd0(%rsp), %rax
addq $0x8, %rbx
cmpq %rax, %r14
jb 0x34a3
leaq 0x30(%rsp), %rdi
callq 0x4356
movq 0x68(%rsp), %rdi
testq %rdi, %rdi
je 0x391f
movq 0x78(%rsp), %rsi
subq %rdi, %rsi
callq 0x2200
jmp 0x391f
movslq 0xa0(%rsp), %rbx
movslq 0xa4(%rsp), %rsi
leaq 0x30(%rsp), %rdx
movq $0x0, (%rdx)
leaq 0x128(%rsp), %rdi
leaq 0x10(%rsp), %rcx
callq 0x4178
leaq 0x68(%rsp), %rdi
leaq 0x128(%rsp), %rdx
leaq 0x50(%rsp), %rcx
movq %rbx, %rsi
callq 0x4392
movq 0x128(%rsp), %rdi
testq %rdi, %rdi
je 0x3553
movq 0x138(%rsp), %rsi
subq %rdi, %rsi
callq 0x2200
movslq 0xa0(%rsp), %rsi
leaq 0x30(%rsp), %rdi
leaq 0x128(%rsp), %rdx
callq 0x442a
leaq 0x128(%rsp), %rdi
leaq 0x68(%rsp), %rsi
leaq 0x30(%rsp), %rdx
leaq 0x80(%rsp), %rcx
leaq 0xa0(%rsp), %r8
callq 0x44b4
xorps %xmm0, %xmm0
movaps %xmm0, 0x10(%rsp)
xorl %eax, %eax
movq %rax, 0x20(%rsp)
movq %rax, 0x50(%rsp)
cmpl $0x0, 0xd0(%rsp)
je 0x362d
leaq -0x408(%rip), %r14      # 0x31b1
leaq 0x48(%rsp), %r15
leaq 0x50(%rsp), %r12
leaq 0x128(%rsp), %r13
leaq 0x98(%rsp), %rbp
leaq 0x10(%rsp), %rbx
leaq 0xa0(%rsp), %rax
movq %rax, 0x98(%rsp)
movq %r15, %rdi
movq %r14, %rsi
movq %r12, %rdx
movq %r13, %rcx
movq %rbp, %r8
callq 0x4570
movq %rbx, %rdi
movq %r15, %rsi
callq 0x5a12
cmpq $0x0, 0x48(%rsp)
jne 0x3b01
movq 0x50(%rsp), %rax
incq %rax
movq %rax, 0x50(%rsp)
movslq 0xd0(%rsp), %rcx
cmpq %rcx, %rax
jb 0x35d8
cmpl $0x0, 0xd0(%rsp)
je 0x365d
xorl %ebx, %ebx
xorl %r14d, %r14d
movq 0x10(%rsp), %rdi
addq %rbx, %rdi
callq 0x2330
incq %r14
movslq 0xd0(%rsp), %rax
addq $0x8, %rbx
cmpq %rax, %r14
jb 0x363c
leaq 0x10(%rsp), %rdi
callq 0x4356
jmp 0x376d
movslq 0xa0(%rsp), %rbx
movslq 0xa4(%rsp), %rsi
leaq 0x30(%rsp), %rdx
movq $0x0, (%rdx)
leaq 0x128(%rsp), %rdi
leaq 0x10(%rsp), %rcx
callq 0x4178
leaq 0x68(%rsp), %rdi
leaq 0x128(%rsp), %rdx
leaq 0x50(%rsp), %rcx
movq %rbx, %rsi
callq 0x4392
movq 0x128(%rsp), %rdi
testq %rdi, %rdi
je 0x36d1
movq 0x138(%rsp), %rsi
subq %rdi, %rsi
callq 0x2200
movslq 0xa0(%rsp), %rsi
leaq 0x128(%rsp), %rdx
movq $0x0, (%rdx)
leaq 0x30(%rsp), %rdi
leaq 0x10(%rsp), %rcx
callq 0x4178
movslq 0xa0(%rsp), %rsi
leaq 0x128(%rsp), %rdx
movq $0x0, (%rdx)
leaq 0x10(%rsp), %rdi
leaq 0x50(%rsp), %rcx
callq 0x4178
leaq 0x128(%rsp), %rdi
leaq 0x68(%rsp), %rsi
leaq 0x30(%rsp), %rdx
leaq 0x10(%rsp), %rcx
leaq 0x80(%rsp), %r8
leaq 0xa0(%rsp), %r9
callq 0x4678
leaq 0x128(%rsp), %rdi
callq 0x4750
movq 0x10(%rsp), %rdi
testq %rdi, %rdi
je 0x376d
movq 0x20(%rsp), %rsi
subq %rdi, %rsi
callq 0x2200
movq 0x30(%rsp), %rdi
testq %rdi, %rdi
je 0x3915
movq 0x40(%rsp), %rsi
subq %rdi, %rsi
callq 0x2200
jmp 0x3915
movslq 0xa0(%rsp), %r14
movslq 0xa4(%rsp), %rsi
leaq 0x30(%rsp), %rdx
movq $0x0, (%rdx)
leaq 0x128(%rsp), %rdi
leaq 0x10(%rsp), %rcx
callq 0x4178
leaq 0x68(%rsp), %rdi
leaq 0x128(%rsp), %rdx
leaq 0x50(%rsp), %rcx
movq %r14, %rsi
callq 0x4392
movq 0x128(%rsp), %rdi
testq %rdi, %rdi
je 0x37f2
movq 0x138(%rsp), %rsi
subq %rdi, %rsi
callq 0x2200
movslq 0xa0(%rsp), %r14
movslq 0xa4(%rsp), %rsi
leaq 0x10(%rsp), %rdx
movq $0x0, (%rdx)
leaq 0x128(%rsp), %rdi
leaq 0x50(%rsp), %rcx
callq 0x4178
leaq 0x30(%rsp), %rdi
leaq 0x128(%rsp), %rdx
leaq 0x48(%rsp), %rcx
movq %r14, %rsi
callq 0x4392
movq 0x128(%rsp), %rdi
testq %rdi, %rdi
je 0x3857
movq 0x138(%rsp), %rsi
subq %rdi, %rsi
callq 0x2200
movslq 0xa0(%rsp), %rsi
leaq 0x128(%rsp), %rdx
movq $0x0, (%rdx)
leaq 0x10(%rsp), %rdi
leaq 0x50(%rsp), %rcx
callq 0x4178
movslq 0xa0(%rsp), %rsi
leaq 0x128(%rsp), %rdx
movq $0x0, (%rdx)
leaq 0x50(%rsp), %rdi
leaq 0x48(%rsp), %rcx
callq 0x4178
movq %rbx, (%rsp)
leaq 0x128(%rsp), %rdi
leaq 0x68(%rsp), %rsi
leaq 0x30(%rsp), %rdx
leaq 0x10(%rsp), %rcx
leaq 0x50(%rsp), %r8
leaq 0x80(%rsp), %r9
callq 0x4ae0
leaq 0x128(%rsp), %rdi
callq 0x4bd2
movq 0x50(%rsp), %rdi
testq %rdi, %rdi
je 0x38f4
movq 0x60(%rsp), %rsi
subq %rdi, %rsi
callq 0x2200
movq 0x10(%rsp), %rdi
testq %rdi, %rdi
je 0x390b
movq 0x20(%rsp), %rsi
subq %rdi, %rsi
callq 0x2200
leaq 0x30(%rsp), %rdi
callq 0x462a
leaq 0x68(%rsp), %rdi
callq 0x462a
cmpl $0x0, 0x108(%rsp)
je 0x39db
leaq 0x28a5(%rip), %rsi      # 0x61d9
leaq 0x128(%rsp), %rdi
movl $0x10, %edx
callq 0x2210
cmpl $0x0, 0xa0(%rsp)
jle 0x3996
xorl %r15d, %r15d
leaq 0x128(%rsp), %rbx
leaq 0x2882(%rip), %r14      # 0x61e4
movq 0x80(%rsp), %rax
movl (%rax,%r15,4), %esi
movq %rbx, %rdi
callq 0x2340
movl $0x1, %edx
movq %rax, %rdi
movq %r14, %rsi
callq 0x2220
incq %r15
movslq 0xa0(%rsp), %rax
cmpq %rax, %r15
jl 0x3962
leaq 0x128(%rsp), %rdi
callq 0x2260
movq 0x5626(%rip), %rax      # 0x8fd0
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 0x2180
leaq 0x220(%rsp), %rdi
callq 0x2060
movq 0x80(%rsp), %rdi
testq %rdi, %rdi
je 0x39f8
movq 0x90(%rsp), %rsi
subq %rdi, %rsi
callq 0x2200
xorl %eax, %eax
addq $0x1638, %rsp           # imm = 0x1638
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %rbx
jmp 0x3aa2
movq %rax, %rbx
jmp 0x3ab9
movq %rax, %rbx
movq 0x128(%rsp), %rdi
testq %rdi, %rdi
je 0x3b2a
movq 0x138(%rsp), %rsi
jmp 0x3b22
jmp 0x3a3f
movq %rax, %rbx
jmp 0x3b13
jmp 0x3a4b
jmp 0x3a4b
movq %rax, %rbx
jmp 0x3b2a
jmp 0x3a57
jmp 0x3a57
movq %rax, %rbx
movq 0x128(%rsp), %rdi
testq %rdi, %rdi
je 0x3b6c
movq 0x138(%rsp), %rsi
jmp 0x3b52
movq %rax, %rbx
jmp 0x3b43
jmp 0x3ae3
jmp 0x3ae3
jmp 0x3ae3
jmp 0x3ae3
movq %rax, %rbx
movq 0x50(%rsp), %rdi
testq %rdi, %rdi
je 0x3aa2
movq 0x60(%rsp), %rsi
subq %rdi, %rsi
callq 0x2200
movq 0x10(%rsp), %rdi
testq %rdi, %rdi
je 0x3ab9
movq 0x20(%rsp), %rsi
subq %rdi, %rsi
callq 0x2200
leaq 0x30(%rsp), %rdi
callq 0x462a
jmp 0x3b2a
movq %rax, %rbx
movq 0x10(%rsp), %rdi
testq %rdi, %rdi
je 0x3b13
movq 0x20(%rsp), %rsi
subq %rdi, %rsi
callq 0x2200
jmp 0x3b13
jmp 0x3b5c
movq %rax, %rbx
jmp 0x3b6c
jmp 0x3b06
cmpq $0x0, 0x48(%rsp)
jne 0x3b01
jmp 0x3b06
jmp 0x3b36
cmpq $0x0, 0x50(%rsp)
je 0x3b36
callq 0x2040
movq %rax, %rbx
leaq 0x10(%rsp), %rdi
callq 0x4356
movq 0x30(%rsp), %rdi
testq %rdi, %rdi
je 0x3b2a
movq 0x40(%rsp), %rsi
subq %rdi, %rsi
callq 0x2200
leaq 0x68(%rsp), %rdi
callq 0x462a
jmp 0x3b6c
movq %rax, %rbx
leaq 0x30(%rsp), %rdi
callq 0x4356
movq 0x68(%rsp), %rdi
testq %rdi, %rdi
je 0x3b6c
movq 0x78(%rsp), %rsi
subq %rdi, %rsi
callq 0x2200
jmp 0x3b6c
movq %rax, %rbx
leaq 0x128(%rsp), %rdi
callq 0x2290
movq 0x80(%rsp), %rdi
testq %rdi, %rdi
je 0x3b89
movq 0x90(%rsp), %rsi
subq %rdi, %rsi
callq 0x2200
movq %rbx, %rdi
callq 0x2360
nop