// File: /workspace/github_cpp_makefile_star2_O1/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, -0x98(%rbp)
movq %rdi, -0x90(%rbp)
movq 0xce11(%rip), %rbx      # 0x16fa8
leaq -0x3c(%rbp), %rsi
movq %rbx, %rdi
callq 0x33e0
leaq -0x38(%rbp), %rsi
movq %rbx, %rdi
callq 0x32e0
leaq 0xd1ae(%rip), %rax      # 0x17364
movslq (%rax), %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 0xa216
leaq 0xd21b(%rip), %rax      # 0x17400
movq (%rax), %rax
leaq 0xd209(%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 0xa1f8
movq %r14, %rdi
callq 0x3030
movl -0x38(%rbp), %edx
movq %rbx, %rdi
movq %rax, -0xc0(%rbp)
movq %rax, %rsi
callq 0x9931
movq %rbx, %rdi
callq 0x3370
movl -0x38(%rbp), %eax
sarl %eax
testl %eax, %eax
jle 0xa267
xorl %r13d, %r13d
movl $0x1, %edx
movl %eax, %ecx
movl %edx, %r12d
incl %r13d
leal (%r12,%r12), %edx
shrl %ecx
cmpl $0x1, %eax
movl %ecx, %eax
ja 0xa24e
shll $0x2, %r12d
jmp 0xa270
movl $0x2, %r12d
xorl %r13d, %r13d
movslq %r12d, %rbx
leaq (,%rbx,8), %rdi
testl %ebx, %ebx
movq $-0x1, %r14
cmovsq %r14, %rdi
callq 0x3030
movq %rax, %r15
movq %r12, -0xb8(%rbp)
movl %r12d, %r12d
testl %ebx, %ebx
jle 0xa2cd
leaq 0xd0bf(%rip), %rax      # 0x17364
movslq (%rax), %rax
movq %rax, %rbx
shlq $0x4, %rbx
testq %rax, %rax
cmovsq %r14, %rbx
xorl %r14d, %r14d
movq %rbx, %rdi
callq 0x3030
movq %rax, (%r15,%r14,8)
incq %r14
cmpq %r14, %r12
jne 0xa2b9
movq %r12, -0xe8(%rbp)
movq %r15, -0x88(%rbp)
movq %r15, %rdi
movq -0xc0(%rbp), %rsi
movq -0xb8(%rbp), %rdx
callq 0x9a3d
xorl %r15d, %r15d
movq %r15, -0x50(%rbp)
xorpd %xmm0, %xmm0
movapd %xmm0, -0x60(%rbp)
movq %r15, -0xd0(%rbp)
movapd %xmm0, -0xe0(%rbp)
movq %r15, -0x70(%rbp)
movapd %xmm0, -0x80(%rbp)
testl %r13d, %r13d
je 0xa6f0
movl %r13d, -0xac(%rbp)
movl $0x1, %r12d
movl %r15d, %ecx
shll %cl, %r12d
movl -0x38(%rbp), %esi
movl %esi, %eax
cltd
idivl %r12d
movl %esi, %edx
subl %eax, %edx
movl %r13d, %ecx
movl -0x3c(%rbp), %r13d
andl %r13d, %edx
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 0xcc32(%rip), %rdi      # 0x16fa8
movl %ebx, %esi
movl %r13d, %edx
leaq -0x48(%rbp), %rcx
callq 0x3470
movq -0x48(%rbp), %rdi
leaq -0xb0(%rbp), %rsi
callq 0x33e0
cmpl $0x0, -0xb0(%rbp)
jne 0xa406
movl $0x0, -0x2c(%rbp)
leaq 0xcfb9(%rip), %rax      # 0x17364
movslq (%rax), %rax
cmpq $0x2, %rax
jl 0xa406
movl -0x2c(%rbp), %ecx
leal (%rbx,%r12), %edx
movslq %edx, %rdx
movq -0x88(%rbp), %rsi
movq (%rsi,%rdx,8), %rdx
leaq 0x18(%rdx), %rsi
movl $0x1, %edi
movsd (%rsi), %xmm0
subsd -0x8(%rsi), %xmm0
movslq %ecx, %r8
shlq $0x4, %r8
movsd 0x8(%rdx,%r8), %xmm1
subsd (%rdx,%r8), %xmm1
ucomisd %xmm1, %xmm0
jbe 0xa3fa
movl %edi, -0x2c(%rbp)
movl %edi, %ecx
incq %rdi
addq $0x10, %rsi
cmpq %rdi, %rax
jne 0xa3d2
movq -0x48(%rbp), %r8
leaq -0x2c(%rbp), %rdi
movl $0x1, %esi
movq 0xcbb6(%rip), %rdx      # 0x16fd0
xorl %ecx, %ecx
callq 0x3070
movl -0x2c(%rbp), %edx
movq -0x90(%rbp), %rdi
movq -0x98(%rbp), %rsi
leaq -0x48(%rbp), %rcx
callq 0x9b32
movsd %xmm0, -0xa0(%rbp)
xorl %r13d, %r14d
movl -0x2c(%rbp), %r8d
movl -0x3c(%rbp), %r9d
subq $0x8, %rsp
movq -0x90(%rbp), %rdi
movq -0x98(%rbp), %rsi
leaq -0x60(%rbp), %rdx
leaq -0xe0(%rbp), %rcx
movsd -0xa0(%rbp), %xmm0
pushq %r14
callq 0x9c90
addq $0x10, %rsp
movl %eax, -0x30(%rbp)
cmpl %r14d, -0x3c(%rbp)
jge 0xa53d
leaq -0x30(%rbp), %rdi
movl $0x1, %esi
movq 0xcb35(%rip), %rdx      # 0x16fd0
movl %r14d, %ecx
movl $0x4, %r8d
leaq -0x34(%rbp), %r9
leaq -0x100(%rbp), %rax
pushq %rax
pushq 0xcaf2(%rip)            # 0x16fa8
pushq $0x5
pushq %r14
pushq %rdx
pushq $0x1
callq 0x3200
addq $0x30, %rsp
movslq -0x34(%rbp), %rax
leaq 0xce93(%rip), %r13      # 0x17364
movslq (%r13), %rsi
imulq %rax, %rsi
movq $0x0, -0xa8(%rbp)
leaq -0x80(%rbp), %rdi
leaq -0xa8(%rbp), %rdx
callq 0xb5ce
movq -0x60(%rbp), %rdi
movl (%r13), %eax
movl -0x30(%rbp), %esi
imull %eax, %esi
movq -0x80(%rbp), %r9
imull -0x34(%rbp), %eax
movq 0xcaa7(%rip), %rdx      # 0x16fb8
movl %r14d, %ecx
movl $0x2, %r8d
leaq -0x100(%rbp), %r10
pushq %r10
pushq 0xca7f(%rip)            # 0x16fa8
pushq $0x3
pushq %r14
pushq %rdx
pushq %rax
callq 0x3200
addq $0x30, %rsp
jmp 0xa5ea
leaq -0x30(%rbp), %rdi
movl $0x1, %esi
movq 0xca83(%rip), %rdx      # 0x16fd0
movl %r14d, %ecx
movl $0x5, %r8d
leaq -0x34(%rbp), %r9
leaq -0x100(%rbp), %rax
pushq %rax
pushq 0xca40(%rip)            # 0x16fa8
pushq $0x4
pushq %r14
pushq %rdx
pushq $0x1
callq 0x3200
addq $0x30, %rsp
movslq -0x34(%rbp), %rax
leaq 0xcde1(%rip), %r13      # 0x17364
movslq (%r13), %rsi
imulq %rax, %rsi
movq $0x0, -0xa8(%rbp)
leaq -0x80(%rbp), %rdi
leaq -0xa8(%rbp), %rdx
callq 0xb5ce
movq -0x60(%rbp), %rdi
movl (%r13), %eax
movl -0x30(%rbp), %esi
imull %eax, %esi
movq -0x80(%rbp), %r9
imull -0x34(%rbp), %eax
movq 0xc9f5(%rip), %rdx      # 0x16fb8
movl %r14d, %ecx
movl $0x3, %r8d
leaq -0x100(%rbp), %r10
pushq %r10
pushq 0xc9cd(%rip)            # 0x16fa8
pushq $0x2
pushq %r14
pushq %rdx
pushq %rax
callq 0x3200
addq $0x30, %rsp
movq -0x60(%rbp), %rax
cmpq %rax, -0x58(%rbp)
je 0xa5f8
movq %rax, -0x58(%rbp)
movl -0x30(%rbp), %edx
movq -0x90(%rbp), %rdi
movq -0x98(%rbp), %rsi
leaq -0xe0(%rbp), %rcx
leaq -0x80(%rbp), %r8
callq 0x9ea0
movq -0x80(%rbp), %rax
cmpq %rax, -0x78(%rbp)
je 0xa627
movq %rax, -0x78(%rbp)
addl %r12d, %ebx
leal (%rbx,%rbx), %edx
movslq %edx, %rax
movq -0x88(%rbp), %r9
movq (%r9,%rax,8), %rsi
movslq %ebx, %rax
movq (%r9,%rax,8), %rax
leaq 0xcd1b(%rip), %rcx      # 0x17364
movslq (%rcx), %rcx
testq %rcx, %rcx
jle 0xa67e
movq %rcx, %rdi
shlq $0x4, %rdi
xorl %r8d, %r8d
movsd 0x8(%rax,%r8), %xmm0
movsd %xmm0, 0x8(%rsi,%r8)
movsd (%rax,%r8), %xmm0
movsd %xmm0, (%rsi,%r8)
addq $0x10, %r8
cmpq %r8, %rdi
jne 0xa65b
movslq -0x2c(%rbp), %rdi
shlq $0x4, %rdi
orl $0x1, %edx
movsd -0xa0(%rbp), %xmm0
movsd %xmm0, 0x8(%rsi,%rdi)
movslq %edx, %rdx
movq (%r9,%rdx,8), %rdx
testl %ecx, %ecx
jle 0xa6c7
shlq $0x4, %rcx
xorl %esi, %esi
movsd 0x8(%rax,%rsi), %xmm0
movsd %xmm0, 0x8(%rdx,%rsi)
movsd (%rax,%rsi), %xmm0
movsd %xmm0, (%rdx,%rsi)
addq $0x10, %rsi
cmpq %rsi, %rcx
jne 0xa6a8
movsd -0xa0(%rbp), %xmm0
movsd %xmm0, (%rdx,%rdi)
leaq -0x48(%rbp), %rdi
callq 0x3460
incl %r15d
movl -0xac(%rbp), %r13d
cmpl %r13d, %r15d
jne 0xa329
cmpl $0x0, -0xb8(%rbp)
movq -0xc0(%rbp), %r14
movq -0x88(%rbp), %r15
movq -0xe8(%rbp), %r12
jle 0xa726
xorl %ebx, %ebx
movq (%r15,%rbx,8), %rdi
testq %rdi, %rdi
je 0xa71e
callq 0x3370
incq %rbx
cmpq %rbx, %r12
jne 0xa710
movq %r15, %rdi
callq 0x3270
movq %r14, %rdi
callq 0x3370
movq -0x80(%rbp), %rdi
testq %rdi, %rdi
je 0xa744
callq 0x3270
movq -0xe0(%rbp), %rdi
testq %rdi, %rdi
je 0xa755
callq 0x3270
movq -0x60(%rbp), %rdi
testq %rdi, %rdi
je 0xa763
callq 0x3270
addq $0xd8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0xa77b
jmp 0xa77b
jmp 0xa77b
movq %rax, %rbx
movq -0x80(%rbp), %rdi
testq %rdi, %rdi
je 0xa78c
callq 0x3270
movq -0xe0(%rbp), %rdi
testq %rdi, %rdi
je 0xa79d
callq 0x3270
movq -0x60(%rbp), %rdi
testq %rdi, %rdi
je 0xa7ab
callq 0x3270
movq %rbx, %rdi
callq 0x34c0