// File: /workspace/github_cpp_makefile_star2_O3/ADAPTLab[P]MuDBSCAN/partition.cpp
// Function: start_partitioning(std::vector<std::vector<double, std::allocator<double>>, std::allocator<std::vector<double, std::allocator<double>>>>&, int*)
void start_partitioning(vector< vector<double> >& objects, int* num_points)
{
	int r_count, s_count, rank, nproc, i, j, k;
	MPI_Comm_rank(MPI_COMM_WORLD, &rank);
	MPI_Comm_size(MPI_COMM_WORLD, &nproc);

	interval* box = new interval[DIMENSION];

	for(i = 0; i < DIMENSION; i++)
	{	
		box[i].upper = MAXGRIDSIZEglobal[i];
		box[i].lower = MINGRIDSIZEglobal[i];
	}

	interval* gbox = new interval[DIMENSION];
	compute_global_bounding_box(box, gbox, nproc);
	delete [] box;

	int internal_nodes, partner_rank, loops, b, color, sub_rank, d, max, sub_nprocs;
	MPI_Comm new_comm;
	MPI_Status status;

	loops = 0;
	i = nproc;
	internal_nodes = 1;

	while((i = i >> 1) > 0)
	{
		loops++;
		internal_nodes = internal_nodes << 1;
	}

	internal_nodes = internal_nodes << 1;

	interval** nodes_gbox = new interval*[internal_nodes];
	for(i = 0; i < internal_nodes; i++)
		nodes_gbox[i] = new interval[DIMENSION];

	copy_global_box_to_each_node(nodes_gbox, gbox, internal_nodes);
	// now each node in the tree has gbox

	vector <double> send_buf;
	vector <int>   invalid_pos_as;
	vector <double> recv_buf;

	int pow2_i;
	double median;

	for(i = 0; i < loops; i++)
	{
		pow2_i = POW2(i);
		b  = nproc - (int) (nproc / pow2_i);
		color = (int)((rank & b) / POW2(loops - i ));
		partner_rank = rank ^ (int)(nproc/POW2(i + 1));

		MPI_Comm new_comm;
		MPI_Comm_split(MPI_COMM_WORLD, color, rank, &new_comm);
		MPI_Comm_rank(new_comm, &sub_rank);

		if(sub_rank == 0)
		{
			d = 0;
			for(j = 1; j < DIMENSION; j++)
			{
				if(nodes_gbox[pow2_i + color][j].upper - nodes_gbox[pow2_i + color][j].lower > 
						nodes_gbox[pow2_i + color][d].upper - nodes_gbox[pow2_i + color][d].lower)
					d = j;
			}
		}	

		MPI_Bcast(&d, 1, MPI_INT, 0, new_comm);

		double median  = get_median(objects, num_points, d, new_comm);		

		s_count = get_points_to_send(objects, num_points,send_buf, invalid_pos_as, median, d, rank, partner_rank);

		if (rank < partner_rank)
		{
			MPI_Sendrecv(&s_count, 1, MPI_INT, partner_rank, 4, &r_count, 1, MPI_INT, partner_rank, 5, MPI_COMM_WORLD, &status);
			recv_buf.resize(r_count * DIMENSION, 0.0);
			MPI_Sendrecv(&send_buf[0], s_count * DIMENSION, MPI_DOUBLE, partner_rank, 2,
					&recv_buf[0], r_count * DIMENSION, MPI_DOUBLE, partner_rank, 3, MPI_COMM_WORLD, &status);
			send_buf.clear();
		}
		else
		{
			MPI_Sendrecv(&s_count, 1, MPI_INT, partner_rank, 5, &r_count, 1, MPI_INT, partner_rank, 4, MPI_COMM_WORLD, &status);

			recv_buf.resize(r_count * DIMENSION, 0.0);

			MPI_Sendrecv(&send_buf[0], s_count * DIMENSION, MPI_DOUBLE, partner_rank, 3, 
					&recv_buf[0], r_count * DIMENSION, MPI_DOUBLE, partner_rank, 2, MPI_COMM_WORLD, &status);

			send_buf.clear();
		}

		update_points(objects, num_points, s_count, invalid_pos_as, recv_buf);
		recv_buf.clear();

		copy_box(nodes_gbox[LOWER(pow2_i+color)], nodes_gbox[pow2_i+color]);
		nodes_gbox[LOWER(pow2_i+color)][d].upper =  median;
		copy_box(nodes_gbox[UPPER(pow2_i+color)], nodes_gbox[pow2_i+color]);
		nodes_gbox[UPPER(pow2_i+color)][d].lower =  median;	

		MPI_Comm_free(&new_comm);
	}
	for(i = 0; i < internal_nodes; i++)
		delete [] nodes_gbox[i];

	delete nodes_gbox;

	delete [] gbox;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xd8, %rsp
movq %rsi, -0xb0(%rbp)
movq %rdi, -0xa8(%rbp)
movq 0xce81(%rip), %rbx      # 0x16fa8
leaq -0x40(%rbp), %rsi
movq %rbx, %rdi
callq 0x33e0
leaq -0x3c(%rbp), %rsi
movq %rbx, %rdi
callq 0x32e0
leaq 0xd21e(%rip), %r12      # 0x17364
movslq (%r12), %r15
movq %r15, %rax
shlq $0x4, %rax
testq %r15, %r15
movq $-0x1, %r14
cmovnsq %rax, %r14
movq %r14, %rdi
callq 0x3030
movq %rax, %rbx
testq %r15, %r15
jle 0xa1a7
leaq 0xd28a(%rip), %rax      # 0x17400
movq (%rax), %rax
leaq 0xd278(%rip), %rcx      # 0x173f8
movq (%rcx), %rcx
shlq $0x3, %r15
xorl %edx, %edx
movsd (%rax,%rdx), %xmm0
movsd %xmm0, 0x8(%rbx,%rdx,2)
movsd (%rcx,%rdx), %xmm0
movsd %xmm0, (%rbx,%rdx,2)
addq $0x8, %rdx
cmpq %rdx, %r15
jne 0xa189
movq %r14, %rdi
callq 0x3030
movq %rax, %r13
movl -0x3c(%rbp), %edx
movq %rbx, %rdi
movq %rax, %rsi
callq 0x98c9
movq %rbx, %rdi
callq 0x3370
movl -0x3c(%rbp), %eax
sarl %eax
testl %eax, %eax
movq %r13, -0xc8(%rbp)
jle 0xa22b
xorl %r14d, %r14d
movl $0x1, %edx
movl %eax, %ecx
movl %edx, %r15d
incl %r14d
leal (%r15,%r15), %edx
shrl %ecx
cmpl $0x1, %eax
movl %ecx, %eax
ja 0xa1e2
shll $0x2, %r15d
movslq %r15d, %rbx
leaq (,%rbx,8), %rax
testl %ebx, %ebx
movq $-0x1, %rdi
cmovnsq %rax, %rdi
callq 0x3030
movq %rax, -0x48(%rbp)
testl %ebx, %ebx
movl %r14d, -0x38(%rbp)
jg 0xa246
movl $0x0, -0x4c(%rbp)
jmp 0xa290
movl $0x10, %edi
callq 0x3030
movq %rax, -0x48(%rbp)
movl $0x2, %r15d
movl $0x0, -0x38(%rbp)
movslq (%r12), %rax
movq %rax, %rcx
shlq $0x4, %rcx
testq %rax, %rax
movq $-0x1, %rbx
cmovnsq %rcx, %rbx
movq %r15, %r12
movl %r15d, %r14d
xorl %r15d, %r15d
movq -0x48(%rbp), %r13
movq %rbx, %rdi
callq 0x3030
movq %rax, (%r13,%r15,8)
incq %r15
cmpq %r15, %r14
jne 0xa26c
movb $0x1, %al
movl %eax, -0x4c(%rbp)
movq %r12, %r15
movq -0xc8(%rbp), %r13
movq -0x48(%rbp), %rdi
movq %r13, %rsi
movq %r15, -0xe8(%rbp)
movl %r15d, %edx
callq 0x99c8
xorl %r15d, %r15d
movq %r15, -0x90(%rbp)
xorpd %xmm0, %xmm0
movapd %xmm0, -0xa0(%rbp)
movq %r15, -0xd0(%rbp)
movapd %xmm0, -0xe0(%rbp)
movq %r15, -0x70(%rbp)
movapd %xmm0, -0x80(%rbp)
movl -0x38(%rbp), %edi
testl %edi, %edi
je 0xa6ba
movl $0x1, %r12d
movl %r15d, %ecx
shll %cl, %r12d
movl -0x3c(%rbp), %esi
movl %esi, %eax
cltd
idivl %r12d
movl %esi, %edx
subl %eax, %edx
movl -0x40(%rbp), %r13d
andl %r13d, %edx
movl %edi, %ecx
subl %r15d, %ecx
movl $0x1, %edi
shll %cl, %edi
movl %edx, %eax
cltd
idivl %edi
movl %eax, %ebx
movl $0x2, %edi
movl %r15d, %ecx
shll %cl, %edi
movl %esi, %eax
cltd
idivl %edi
movl %eax, %r14d
movq 0xcc7d(%rip), %rdi      # 0x16fa8
movl %ebx, %esi
movl %r13d, %edx
leaq -0x60(%rbp), %rcx
callq 0x3470
movq -0x60(%rbp), %rdi
leaq -0xbc(%rbp), %rsi
callq 0x33e0
cmpl $0x0, -0xbc(%rbp)
jne 0xa3b7
movl $0x0, -0x2c(%rbp)
leaq 0xd004(%rip), %rax      # 0x17364
movslq (%rax), %rax
cmpq $0x2, %rax
jl 0xa3b7
leal (%rbx,%r12), %ecx
movslq %ecx, %rcx
movq -0x48(%rbp), %rdx
movq (%rdx,%rcx,8), %rcx
leaq 0x18(%rcx), %rdx
xorl %edi, %edi
movl $0x1, %esi
movsd (%rdx), %xmm0
subsd -0x8(%rdx), %xmm0
movslq %edi, %r8
shlq $0x4, %r8
movsd 0x8(%rcx,%r8), %xmm1
subsd (%rcx,%r8), %xmm1
ucomisd %xmm1, %xmm0
jbe 0xa3ab
movl %esi, -0x2c(%rbp)
movl %esi, %edi
incq %rsi
addq $0x10, %rdx
cmpq %rsi, %rax
jne 0xa383
movq -0x60(%rbp), %r8
leaq -0x2c(%rbp), %rdi
movl $0x1, %esi
movq 0xcc05(%rip), %rdx      # 0x16fd0
xorl %ecx, %ecx
callq 0x3070
movl -0x2c(%rbp), %edx
movq -0xa8(%rbp), %rdi
movq -0xb0(%rbp), %rsi
leaq -0x60(%rbp), %rcx
callq 0x9ac0
movsd %xmm0, -0x58(%rbp)
xorl %r13d, %r14d
movl -0x2c(%rbp), %r8d
movl -0x40(%rbp), %r9d
subq $0x8, %rsp
movq -0xa8(%rbp), %rdi
movq -0xb0(%rbp), %rsi
leaq -0xa0(%rbp), %rdx
leaq -0xe0(%rbp), %rcx
movsd -0x58(%rbp), %xmm0
pushq %r14
callq 0x9c1e
addq $0x10, %rsp
movl %eax, -0x30(%rbp)
cmpl %r14d, -0x40(%rbp)
jge 0xa4ee
leaq -0x30(%rbp), %rdi
movl $0x1, %esi
movq 0xcb87(%rip), %rdx      # 0x16fd0
movl %r14d, %ecx
movl $0x4, %r8d
leaq -0x34(%rbp), %r9
leaq -0x100(%rbp), %rax
pushq %rax
pushq 0xcb44(%rip)            # 0x16fa8
pushq $0x5
pushq %r14
pushq %rdx
pushq $0x1
callq 0x3200
addq $0x30, %rsp
movslq -0x34(%rbp), %rax
leaq 0xcee5(%rip), %r13      # 0x17364
movslq (%r13), %rsi
imulq %rax, %rsi
movq $0x0, -0xb8(%rbp)
leaq -0x80(%rbp), %rdi
leaq -0xb8(%rbp), %rdx
callq 0xb566
movq -0xa0(%rbp), %rdi
movl (%r13), %eax
movl -0x30(%rbp), %esi
imull %eax, %esi
movq -0x80(%rbp), %r9
imull -0x34(%rbp), %eax
movq 0xcaf6(%rip), %rdx      # 0x16fb8
movl %r14d, %ecx
movl $0x2, %r8d
leaq -0x100(%rbp), %r10
pushq %r10
pushq 0xcace(%rip)            # 0x16fa8
pushq $0x3
pushq %r14
pushq %rdx
pushq %rax
callq 0x3200
addq $0x30, %rsp
jmp 0xa59e
leaq -0x30(%rbp), %rdi
movl $0x1, %esi
movq 0xcad2(%rip), %rdx      # 0x16fd0
movl %r14d, %ecx
movl $0x5, %r8d
leaq -0x34(%rbp), %r9
leaq -0x100(%rbp), %rax
pushq %rax
pushq 0xca8f(%rip)            # 0x16fa8
pushq $0x4
pushq %r14
pushq %rdx
pushq $0x1
callq 0x3200
addq $0x30, %rsp
movslq -0x34(%rbp), %rax
leaq 0xce30(%rip), %r13      # 0x17364
movslq (%r13), %rsi
imulq %rax, %rsi
movq $0x0, -0xb8(%rbp)
leaq -0x80(%rbp), %rdi
leaq -0xb8(%rbp), %rdx
callq 0xb566
movq -0xa0(%rbp), %rdi
movl (%r13), %eax
movl -0x30(%rbp), %esi
imull %eax, %esi
movq -0x80(%rbp), %r9
imull -0x34(%rbp), %eax
movq 0xca41(%rip), %rdx      # 0x16fb8
movl %r14d, %ecx
movl $0x3, %r8d
leaq -0x100(%rbp), %r10
pushq %r10
pushq 0xca19(%rip)            # 0x16fa8
pushq $0x2
pushq %r14
pushq %rdx
pushq %rax
callq 0x3200
addq $0x30, %rsp
movq -0xa0(%rbp), %rax
cmpq %rax, -0x98(%rbp)
je 0xa5b5
movq %rax, -0x98(%rbp)
movl -0x30(%rbp), %edx
movq -0xa8(%rbp), %rdi
movq -0xb0(%rbp), %rsi
leaq -0xe0(%rbp), %rcx
leaq -0x80(%rbp), %r8
callq 0x9e33
movq -0x80(%rbp), %rax
cmpq %rax, -0x78(%rbp)
je 0xa5e4
movq %rax, -0x78(%rbp)
addl %r12d, %ebx
leal (%rbx,%rbx), %ecx
movslq %ecx, %rax
movq -0x48(%rbp), %r9
movq (%r9,%rax,8), %rdi
leaq 0xcd68(%rip), %rax      # 0x17364
movslq (%rax), %rax
testq %rax, %rax
jle 0xa679
movslq %ebx, %rdx
movq (%r9,%rdx,8), %rsi
shlq $0x4, %rax
xorl %edx, %edx
movsd 0x8(%rsi,%rdx), %xmm0
movsd %xmm0, 0x8(%rdi,%rdx)
movsd (%rsi,%rdx), %xmm0
movsd %xmm0, (%rdi,%rdx)
addq $0x10, %rdx
cmpq %rdx, %rax
jne 0xa611
movslq -0x2c(%rbp), %rdx
movq %rdx, %r8
shlq $0x4, %r8
movsd -0x58(%rbp), %xmm0
movsd %xmm0, 0x8(%rdi,%r8)
orl $0x1, %ecx
movslq %ecx, %rcx
movq (%r9,%rcx,8), %rcx
xorl %edi, %edi
movsd 0x8(%rsi,%rdi), %xmm0
movsd %xmm0, 0x8(%rcx,%rdi)
movsd (%rsi,%rdi), %xmm0
movsd %xmm0, (%rcx,%rdi)
addq $0x10, %rdi
cmpq %rdi, %rax
jne 0xa653
movsd -0x58(%rbp), %xmm0
jmp 0xa699
movslq -0x2c(%rbp), %rdx
movq %rdx, %rax
shlq $0x4, %rax
movsd -0x58(%rbp), %xmm0
movsd %xmm0, 0x8(%rdi,%rax)
orl $0x1, %ecx
movslq %ecx, %rax
movq (%r9,%rax,8), %rcx
shlq $0x4, %rdx
movsd %xmm0, (%rcx,%rdx)
leaq -0x60(%rbp), %rdi
callq 0x3460
incl %r15d
movl -0x38(%rbp), %edi
cmpl %edi, %r15d
jne 0xa2df
cmpb $0x0, -0x4c(%rbp)
movq -0xc8(%rbp), %r15
movq -0x48(%rbp), %r12
je 0xa6ea
movl -0xe8(%rbp), %ebx
xorl %r14d, %r14d
movq (%r12,%r14,8), %rdi
testq %rdi, %rdi
je 0xa6e2
callq 0x3370
incq %r14
cmpq %r14, %rbx
jne 0xa6d4
movq %r12, %rdi
callq 0x3270
movq %r15, %rdi
callq 0x3370
movq -0x80(%rbp), %rdi
testq %rdi, %rdi
je 0xa708
callq 0x3270
movq -0xe0(%rbp), %rdi
testq %rdi, %rdi
je 0xa719
callq 0x3270
movq -0xa0(%rbp), %rdi
testq %rdi, %rdi
je 0xa72a
callq 0x3270
addq $0xd8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0xa742
jmp 0xa742
jmp 0xa742
movq %rax, %rbx
movq -0x80(%rbp), %rdi
testq %rdi, %rdi
je 0xa753
callq 0x3270
movq -0xe0(%rbp), %rdi
testq %rdi, %rdi
je 0xa764
callq 0x3270
movq -0xa0(%rbp), %rdi
testq %rdi, %rdi
je 0xa775
callq 0x3270
movq %rbx, %rdi
callq 0x34c0