// File: /workspace/github_cpp_makefile_star2_O3/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
xorps %xmm0, %xmm0
xorps %xmm1, %xmm1
movhps 0x2d86(%rip), %xmm1     # xmm1 = xmm1[0,1],mem[0,1]
leaq 0xa0(%rsp), %rbx
movups %xmm1, 0x8(%rbx)
movabsq $0x3fefae147ae147ae, %rax # imm = 0x3FEFAE147AE147AE
movq %rax, 0x18(%rbx)
movabsq $0xc800000064, %rax     # imm = 0xC800000064
movq %rax, 0x20(%rbx)
movaps 0x2d9f(%rip), %xmm1     # 0x6070
movups %xmm1, 0x30(%rbx)
movl $0x1, 0x40(%rbx)
movaps 0x2d9d(%rip), %xmm1     # 0x6080
movups %xmm1, 0x48(%rbx)
xorl %r15d, %r15d
movq %r15, 0x70(%rbx)
movq %r15, 0x80(%rbx)
movups %xmm0, 0x58(%rbx)
movl %r15d, 0x68(%rbx)
movq %rbx, %rdi
callq 0x256c
callq 0x2e6c
movsd %xmm0, 0x78(%rbx)
movq 0x5cc2(%rip), %r14      # 0x8fd8
leaq 0x2f26(%rip), %rsi      # 0x6243
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), %r14
leaq 0x128(%rsp), %rdx
movl %r15d, (%rdx)
leaq 0x80(%rsp), %rdi
leaq 0x68(%rsp), %rcx
movq %r14, %rsi
callq 0x40cc
movl 0x30(%rbx), %edx
leaq 0x71fa(%rip), %rdi      # 0xa578
leaq 0x723b(%rip), %rsi      # 0xa5c0
callq 0x22f0
movl 0x28(%rbx), %eax
cmpl $0x2, %eax
je 0x3649
cmpl $0x1, %eax
je 0x34d5
testl %eax, %eax
jne 0x3762
leaq 0x128(%rsp), %rdx
movq $0x0, (%rdx)
leaq 0x68(%rsp), %rdi
leaq 0x30(%rsp), %rcx
movq %r14, %rsi
callq 0x4248
leaq 0x128(%rsp), %rdi
leaq 0x68(%rsp), %rsi
leaq 0x80(%rsp), %rdx
leaq 0xa0(%rsp), %rcx
callq 0x436a
xorps %xmm0, %xmm0
movaps %xmm0, 0x30(%rsp)
xorl %eax, %eax
movq %rax, 0x40(%rsp)
movq %rax, 0x10(%rsp)
cmpl $0x0, 0xd0(%rsp)
je 0x34ab
leaq -0x330(%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 0x440c
movq %rbx, %rdi
movq %r15, %rsi
callq 0x5ae4
cmpq $0x0, 0x50(%rsp)
jne 0x3b26
movq 0x10(%rsp), %rcx
incq %rcx
movq %rcx, 0x10(%rsp)
movslq 0xd0(%rsp), %rax
cmpq %rax, %rcx
jb 0x342f
testl %eax, %eax
je 0x34ab
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 0x348a
leaq 0x30(%rsp), %rdi
callq 0x44b6
movq 0x68(%rsp), %rdi
testq %rdi, %rdi
je 0x38ec
movq 0x78(%rsp), %rsi
subq %rdi, %rsi
callq 0x2200
jmp 0x38ec
movslq 0xa4(%rsp), %rsi
leaq 0x30(%rsp), %rdx
movq $0x0, (%rdx)
leaq 0x128(%rsp), %rdi
leaq 0x10(%rsp), %rcx
callq 0x4248
leaq 0x68(%rsp), %rdi
leaq 0x128(%rsp), %rdx
leaq 0x50(%rsp), %rcx
movq %r14, %rsi
callq 0x44f2
movq 0x128(%rsp), %rdi
testq %rdi, %rdi
je 0x3532
movq 0x138(%rsp), %rsi
subq %rdi, %rsi
callq 0x2200
movslq 0xa0(%rsp), %rsi
leaq 0x30(%rsp), %rdi
leaq 0x128(%rsp), %rdx
callq 0x458a
leaq 0x128(%rsp), %rdi
leaq 0x68(%rsp), %rsi
leaq 0x30(%rsp), %rdx
leaq 0x80(%rsp), %rcx
leaq 0xa0(%rsp), %r8
callq 0x4618
xorps %xmm0, %xmm0
movaps %xmm0, 0x10(%rsp)
xorl %eax, %eax
movq %rax, 0x20(%rsp)
movq %rax, 0x50(%rsp)
cmpl $0x0, 0xd0(%rsp)
je 0x363a
leaq -0x3eb(%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 0x46d4
movq %rbx, %rdi
movq %r15, %rsi
callq 0x5ae4
cmpq $0x0, 0x48(%rsp)
jne 0x3b26
movq 0x50(%rsp), %rcx
incq %rcx
movq %rcx, 0x50(%rsp)
movslq 0xd0(%rsp), %rax
cmpq %rax, %rcx
jb 0x35bb
testl %eax, %eax
je 0x363a
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 0x3619
leaq 0x10(%rsp), %rdi
callq 0x44b6
jmp 0x3742
movslq 0xa4(%rsp), %rsi
leaq 0x30(%rsp), %rdx
movq $0x0, (%rdx)
leaq 0x128(%rsp), %rdi
leaq 0x10(%rsp), %rcx
callq 0x4248
leaq 0x68(%rsp), %rdi
leaq 0x128(%rsp), %rdx
leaq 0x50(%rsp), %rcx
movq %r14, %rsi
callq 0x44f2
movq 0x128(%rsp), %rdi
testq %rdi, %rdi
je 0x36a6
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 0x4248
movslq 0xa0(%rsp), %rsi
leaq 0x128(%rsp), %rdx
movq $0x0, (%rdx)
leaq 0x10(%rsp), %rdi
leaq 0x50(%rsp), %rcx
callq 0x4248
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 0x47d2
leaq 0x128(%rsp), %rdi
callq 0x48aa
movq 0x10(%rsp), %rdi
testq %rdi, %rdi
je 0x3742
movq 0x20(%rsp), %rsi
subq %rdi, %rsi
callq 0x2200
movq 0x30(%rsp), %rdi
testq %rdi, %rdi
je 0x38e2
movq 0x40(%rsp), %rsi
subq %rdi, %rsi
callq 0x2200
jmp 0x38e2
movslq 0xa4(%rsp), %rsi
leaq 0x30(%rsp), %rdx
movq $0x0, (%rdx)
leaq 0x128(%rsp), %rdi
leaq 0x10(%rsp), %rcx
callq 0x4248
leaq 0x68(%rsp), %rdi
leaq 0x128(%rsp), %rdx
leaq 0x50(%rsp), %rcx
movq %r14, %rsi
callq 0x44f2
movq 0x128(%rsp), %rdi
testq %rdi, %rdi
je 0x37bf
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 0x4248
leaq 0x30(%rsp), %rdi
leaq 0x128(%rsp), %rdx
leaq 0x48(%rsp), %rcx
movq %r14, %rsi
callq 0x44f2
movq 0x128(%rsp), %rdi
testq %rdi, %rdi
je 0x3824
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 0x4248
movslq 0xa0(%rsp), %rsi
leaq 0x128(%rsp), %rdx
movq $0x0, (%rdx)
leaq 0x50(%rsp), %rdi
leaq 0x48(%rsp), %rcx
callq 0x4248
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 0x4b9a
leaq 0x128(%rsp), %rdi
callq 0x4c8c
movq 0x50(%rsp), %rdi
testq %rdi, %rdi
je 0x38c1
movq 0x60(%rsp), %rsi
subq %rdi, %rsi
callq 0x2200
movq 0x10(%rsp), %rdi
testq %rdi, %rdi
je 0x38d8
movq 0x20(%rsp), %rsi
subq %rdi, %rsi
callq 0x2200
leaq 0x30(%rsp), %rdi
callq 0x477e
leaq 0x68(%rsp), %rdi
callq 0x477e
cmpl $0x0, 0x108(%rsp)
je 0x39a8
leaq 0x2958(%rip), %rsi      # 0x6259
leaq 0x128(%rsp), %rdi
movl $0x10, %edx
callq 0x2210
cmpl $0x0, 0xa0(%rsp)
jle 0x3963
xorl %r15d, %r15d
leaq 0x128(%rsp), %rbx
leaq 0x2935(%rip), %r14      # 0x6264
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 0x392f
leaq 0x128(%rsp), %rdi
callq 0x2260
movq 0x5659(%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 0x39c5
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 0x3a6f
movq %rax, %rbx
jmp 0x3a86
movq %rax, %rbx
movq 0x128(%rsp), %rdi
testq %rdi, %rdi
je 0x3aea
movq 0x138(%rsp), %rsi
jmp 0x3ae2
jmp 0x3a0c
movq %rax, %rbx
jmp 0x3ad3
jmp 0x3a18
jmp 0x3a18
movq %rax, %rbx
jmp 0x3aea
jmp 0x3a24
jmp 0x3a24
movq %rax, %rbx
movq 0x128(%rsp), %rdi
testq %rdi, %rdi
je 0x3b3b
movq 0x138(%rsp), %rsi
jmp 0x3b1c
movq %rax, %rbx
jmp 0x3b0d
jmp 0x3ab0
jmp 0x3ab0
jmp 0x3ab0
jmp 0x3ab0
movq %rax, %rbx
movq 0x50(%rsp), %rdi
testq %rdi, %rdi
je 0x3a6f
movq 0x60(%rsp), %rsi
subq %rdi, %rsi
callq 0x2200
movq 0x10(%rsp), %rdi
testq %rdi, %rdi
je 0x3a86
movq 0x20(%rsp), %rsi
subq %rdi, %rsi
callq 0x2200
leaq 0x30(%rsp), %rdi
callq 0x477e
jmp 0x3aea
movq %rax, %rbx
movq 0x10(%rsp), %rdi
testq %rdi, %rdi
je 0x3ad3
movq 0x20(%rsp), %rsi
subq %rdi, %rsi
callq 0x2200
jmp 0x3ad3
jmp 0x3b2b
movq %rax, %rbx
jmp 0x3b3b
jmp 0x3ac6
jmp 0x3b00
jmp 0x3ac6
cmpq $0x0, 0x48(%rsp)
jne 0x3b26
movq %rax, %rbx
leaq 0x10(%rsp), %rdi
callq 0x44b6
movq 0x30(%rsp), %rdi
testq %rdi, %rdi
je 0x3aea
movq 0x40(%rsp), %rsi
subq %rdi, %rsi
callq 0x2200
leaq 0x68(%rsp), %rdi
callq 0x477e
jmp 0x3b3b
jmp 0x3b00
cmpq $0x0, 0x50(%rsp)
jne 0x3b26
movq %rax, %rbx
leaq 0x30(%rsp), %rdi
callq 0x44b6
movq 0x68(%rsp), %rdi
testq %rdi, %rdi
je 0x3b3b
movq 0x78(%rsp), %rsi
subq %rdi, %rsi
callq 0x2200
jmp 0x3b3b
callq 0x2040
movq %rax, %rbx
leaq 0x128(%rsp), %rdi
callq 0x2290
movq 0x80(%rsp), %rdi
testq %rdi, %rdi
je 0x3b58
movq 0x90(%rsp), %rsi
subq %rdi, %rsi
callq 0x2200
movq %rbx, %rdi
callq 0x2360