// File: flastest[P]HeterogeneousParallelDijkstra/parallel_workloads.cc
// Function: get_min_graph_time_for_given_amount_of_threads(bool, int, int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>)
time_type get_min_graph_time_for_given_amount_of_threads(bool TEST_DEBUG, int num_threads, int num_tests, std::string graph_name)
{
	time_type min_time = 2147483647;

	if (TEST_DEBUG) 
	{
		std::cout<<"loading graph from a graph"<<std::endl;
		std::cout << "num threads: " << num_threads<< " num tests: "<<num_tests<<std::endl; 
	}
	graph_t g = cit_graph_from_file(graph_name,true);
	
	//number of nodes in g
	int num_nodes = num_vertices(g);

	//get a source node...
	vertex_descriptor s = vertex(1, g);

	predecessor_map_t pred;


	//get the results from the BGL to compare against
	std::vector<vertex_descriptor> p_BGL(num_nodes);

	std::vector<int> BGL_results = testBGL ( g,  s, p_BGL);
		
	distance_map_t parallel_results;


	for (int i = 0 ; i < num_tests; i++)
	{
		if(TEST_DEBUG) std::cout << "test " << i << " of "<< num_tests << std::endl;
		auto startTime = chrono::high_resolution_clock::now();
		parallel_results = parallel_dijkstra(g, s, pred, num_threads);
		auto endTime = chrono::high_resolution_clock::now();

		float t = chrono::duration_cast<std::chrono::microseconds>( endTime - startTime ).count();

		for (int i = 0 ; i < num_nodes; i++)
		{
			// if(TEST_DEBUG)
			// {	
			// 	std::cout<<"test number "<<i<<std::endl;
			// 	std::cout<<"comparing " <<parallel_results[i] <<" and "<<BGL_results[i]<<std::endl;
			// }
			if(parallel_results[i] != BGL_results[i])
			{
				//std::cout<<"testing parallel_results: " << parallel_results[i] <<" and " <<"BGL_results: " <<BGL_results[i]<<std::endl;
				if(parallel_results[i] != INFINITY && (BGL_results[i] !=  2147483647 || BGL_results[i] !=  -2147483647))
				{	
					std::cout<<"ERROR: parallel dijkstra produced different result than BGL"<<std::endl;
					return -1;
				}
			}
			
			//not sure if I need to check predecessors because they might be different even with functioning code
		}

		min_time = t < min_time ? t : min_time; 
	}
	//if (TEST_DEBUG)std::cout<< "results are:"<<std::endl << print_dijkstra_results(g, parallel_results) <<std::endl;
	return min_time;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x280, %rsp            # imm = 0x280
movq %rcx, -0x1e8(%rbp)
movb %dil, %al
andb $0x1, %al
movb %al, -0x5(%rbp)
movl %esi, -0xc(%rbp)
movl %edx, -0x10(%rbp)
movq %rcx, -0x18(%rbp)
movl $0x7fffffff, -0x1c(%rbp) # imm = 0x7FFFFFFF
testb $0x1, -0x5(%rbp)
je 0xb80a
movq 0x2f820(%rip), %rdi     # 0x3afc8
leaq 0x1ba3b(%rip), %rsi     # 0x271ea
callq 0x4320
movq %rax, %rdi
movq 0x2f7e2(%rip), %rsi     # 0x3afa0
callq 0x4380
movq 0x2f7fe(%rip), %rdi     # 0x3afc8
leaq 0x1ba5f(%rip), %rsi     # 0x27230
callq 0x4320
movq %rax, %rdi
movl -0xc(%rbp), %esi
callq 0x4570
movq %rax, %rdi
leaq 0x1ba53(%rip), %rsi     # 0x2723e
callq 0x4320
movq %rax, %rdi
movl -0x10(%rbp), %esi
callq 0x4570
movq %rax, %rdi
movq 0x2f79b(%rip), %rsi     # 0x3afa0
callq 0x4380
movq -0x1e8(%rbp), %rsi
leaq -0x78(%rbp), %rdi
movq %rdi, -0x1f0(%rbp)
callq 0x4140
movq -0x1f0(%rbp), %rsi
leaq -0x58(%rbp), %rdi
movl $0x1, %edx
callq 0x24550
jmp 0xb838
leaq -0x78(%rbp), %rdi
callq 0x41d0
leaq -0x58(%rbp), %rdi
callq 0xc720
movq %rax, -0x1f8(%rbp)
jmp 0xb853
movq -0x1f8(%rbp), %rax
movl %eax, -0x88(%rbp)
movl $0x1, %edi
leaq -0x58(%rbp), %rsi
callq 0xcb40
movq %rax, -0x200(%rbp)
jmp 0xb877
movq -0x200(%rbp), %rax
movq %rax, -0x90(%rbp)
leaq -0xc0(%rbp), %rdi
callq 0xcb20
movslq -0x88(%rbp), %rax
movq %rax, -0x210(%rbp)
leaq -0xd9(%rbp), %rdi
movq %rdi, -0x208(%rbp)
callq 0xcb60
movq -0x210(%rbp), %rsi
movq -0x208(%rbp), %rdx
leaq -0xd8(%rbp), %rdi
callq 0xcb80
jmp 0xb8ce
leaq -0xd9(%rbp), %rdi
callq 0xcbf0
leaq -0x130(%rbp), %rdi
leaq -0x58(%rbp), %rsi
callq 0xcc10
jmp 0xb8ec
movq -0x90(%rbp), %rdx
leaq -0xf8(%rbp), %rdi
leaq -0x130(%rbp), %rsi
leaq -0xd8(%rbp), %rcx
callq 0x4fa0
jmp 0xb90f
leaq -0x130(%rbp), %rdi
callq 0xcc90
leaq -0x160(%rbp), %rdi
callq 0xd190
movl $0x0, -0x164(%rbp)
movl -0x164(%rbp), %eax
cmpl -0x10(%rbp), %eax
jge 0xbd3a
testb $0x1, -0x5(%rbp)
je 0xba80
movq 0x2f677(%rip), %rdi     # 0x3afc8
leaq 0x1b8f3(%rip), %rsi     # 0x2724b
callq 0x4320
movq %rax, -0x218(%rbp)
jmp 0xb966
movq -0x218(%rbp), %rdi
movl -0x164(%rbp), %esi
callq 0x4570
movq %rax, -0x220(%rbp)
jmp 0xb981
movq -0x220(%rbp), %rdi
leaq 0x1b8c2(%rip), %rsi     # 0x27251
callq 0x4320
movq %rax, -0x228(%rbp)
jmp 0xb99d
movq -0x228(%rbp), %rdi
movl -0x10(%rbp), %esi
callq 0x4570
movq %rax, -0x230(%rbp)
jmp 0xb9b5
movq -0x230(%rbp), %rdi
movq 0x2f5dd(%rip), %rsi     # 0x3afa0
callq 0x4380
jmp 0xb9ca
jmp 0xba80
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
leaq -0x78(%rbp), %rdi
callq 0x41d0
jmp 0xbdb0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
jmp 0xbda7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
leaq -0xd9(%rbp), %rdi
callq 0xcbf0
jmp 0xbd9b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
jmp 0xbd8f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
leaq -0x130(%rbp), %rdi
callq 0xcc90
jmp 0xbd8f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
leaq -0x160(%rbp), %rdi
callq 0xcd10
leaq -0xf8(%rbp), %rdi
callq 0xca30
jmp 0xbd8f
callq 0x4060
movq %rax, -0x170(%rbp)
movl -0xc(%rbp), %r8d
leaq -0x1a0(%rbp), %rdi
leaq -0x58(%rbp), %rsi
leaq -0x90(%rbp), %rdx
leaq -0xc0(%rbp), %rcx
callq 0x1cbe0
jmp 0xbab0
leaq -0x160(%rbp), %rdi
leaq -0x1a0(%rbp), %rsi
movq %rsi, -0x240(%rbp)
callq 0xcd30
movq -0x240(%rbp), %rdi
callq 0xcd10
callq 0x4060
movq %rax, -0x1a8(%rbp)
leaq -0x1a8(%rbp), %rdi
leaq -0x170(%rbp), %rsi
callq 0xd120
movq %rax, -0x238(%rbp)
jmp 0xbafe
movq -0x238(%rbp), %rax
movq %rax, -0x1c0(%rbp)
leaq -0x1c0(%rbp), %rdi
callq 0xd0f0
movq %rax, -0x248(%rbp)
jmp 0xbb21
movq -0x248(%rbp), %rax
movq %rax, -0x1b8(%rbp)
leaq -0x1b8(%rbp), %rdi
callq 0xd170
movq %rax, -0x250(%rbp)
jmp 0xbb44
movq -0x250(%rbp), %rax
cvtsi2ss %rax, %xmm0
movss %xmm0, -0x1ac(%rbp)
movl $0x0, -0x1c4(%rbp)
movl -0x1c4(%rbp), %eax
cmpl -0x88(%rbp), %eax
jge 0xbce6
movslq -0x1c4(%rbp), %rax
movq %rax, -0x1d0(%rbp)
leaq -0x160(%rbp), %rdi
leaq -0x1d0(%rbp), %rsi
callq 0xc610
movq %rax, -0x258(%rbp)
jmp 0xbb9e
movq -0x258(%rbp), %rax
movss (%rax), %xmm0
movss %xmm0, -0x25c(%rbp)
movslq -0x1c4(%rbp), %rsi
leaq -0xf8(%rbp), %rdi
callq 0xccc0
movss -0x25c(%rbp), %xmm0
cvtsi2ssl (%rax), %xmm1
ucomiss %xmm1, %xmm0
jne 0xbbdc
jp 0xbbdc
jmp 0xbcd0
movslq -0x1c4(%rbp), %rax
movq %rax, -0x1d8(%rbp)
leaq -0x160(%rbp), %rdi
leaq -0x1d8(%rbp), %rsi
callq 0xc610
movq %rax, -0x268(%rbp)
jmp 0xbc06
movq -0x268(%rbp), %rax
movss (%rax), %xmm0
xorl %eax, %eax
movss 0x1b3e9(%rip), %xmm1    # 0x27004
ucomiss %xmm1, %xmm0
movb %al, -0x269(%rbp)
jne 0xbc2a
jp 0xbc2a
jmp 0xbc7e
movslq -0x1c4(%rbp), %rsi
leaq -0xf8(%rbp), %rdi
callq 0xccc0
movq %rax, %rcx
movb $0x1, %al
cmpl $0x7fffffff, (%rcx)     # imm = 0x7FFFFFFF
movb %al, -0x26a(%rbp)
jne 0xbc72
movslq -0x1c4(%rbp), %rsi
leaq -0xf8(%rbp), %rdi
callq 0xccc0
cmpl $0x80000001, (%rax)     # imm = 0x80000001
setne %al
movb %al, -0x26a(%rbp)
movb -0x26a(%rbp), %al
movb %al, -0x269(%rbp)
movb -0x269(%rbp), %al
testb $0x1, %al
jne 0xbc8a
jmp 0xbcce
movq 0x2f337(%rip), %rdi     # 0x3afc8
leaq 0x1b5be(%rip), %rsi     # 0x27256
callq 0x4320
movq %rax, -0x278(%rbp)
jmp 0xbca6
movq -0x278(%rbp), %rdi
movq 0x2f2ec(%rip), %rsi     # 0x3afa0
callq 0x4380
jmp 0xbcbb
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
movl $0x1, -0x1dc(%rbp)
jmp 0xbd4a
jmp 0xbcd0
jmp 0xbcd2
movl -0x1c4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1c4(%rbp)
jmp 0xbb62
movss -0x1ac(%rbp), %xmm1
cvtsi2ssl -0x1c(%rbp), %xmm0
ucomiss %xmm1, %xmm0
jbe 0xbd0a
movss -0x1ac(%rbp), %xmm0
movss %xmm0, -0x27c(%rbp)
jmp 0xbd17
cvtsi2ssl -0x1c(%rbp), %xmm0
movss %xmm0, -0x27c(%rbp)
movss -0x27c(%rbp), %xmm0
cvttss2si %xmm0, %eax
movl %eax, -0x1c(%rbp)
movl -0x164(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x164(%rbp)
jmp 0xb931
movl -0x1c(%rbp), %eax
movl %eax, -0x4(%rbp)
movl $0x1, -0x1dc(%rbp)
leaq -0x160(%rbp), %rdi
callq 0xcd10
leaq -0xf8(%rbp), %rdi
callq 0xca30
leaq -0xd8(%rbp), %rdi
callq 0xcdb0
leaq -0xc0(%rbp), %rdi
callq 0xce10
leaq -0x58(%rbp), %rdi
callq 0xcc90
movl -0x4(%rbp), %eax
addq $0x280, %rsp            # imm = 0x280
popq %rbp
retq
leaq -0xd8(%rbp), %rdi
callq 0xcdb0
leaq -0xc0(%rbp), %rdi
callq 0xce10
leaq -0x58(%rbp), %rdi
callq 0xcc90
movq -0x80(%rbp), %rdi
callq 0x4580
nopl (%rax)