// File: Mengjintao[P]SWAPCounter/src/kmerGraph.cpp
// Function: kmerGraph::dataShuttleBetweenGroupProcs(parameter*, MPIEnviroment*, char*&, long long&, long long)
void  kmerGraph::dataShuttleBetweenGroupProcs(parameter *parameters, MPIEnviroment *MPIcontrol, char *& readBuf, long long int& localEnd, long long int readRound)
{
	int gProc = MPIcontrol->groupProc;
	//divide the sequences data for each group process, then distribute data to all its group processes. 
	if(MPIcontrol->rank%gProc==0)	
	{
		unsigned long long step;
		unsigned long long *start_pos = new unsigned long long [gProc+1];
        	step = (localEnd-1)/gProc + 1;
		for(int k=0;k<gProc;k++)
		{
			long long int i = step*k;
			while(i<localEnd && readBuf[i]!='>') i++; 
			assert(i==localEnd || readBuf[i]=='>');
			start_pos[k] = i;
		}
		start_pos[gProc]=localEnd;
		
		for(int k=1;k<gProc;k++)
		{
			unsigned long long int length = start_pos[k+1]-start_pos[k];
			MPI_Send(&length, 1, MPI_LONG_LONG_INT, MPIcontrol->rank+k, 0, MPI_COMM_WORLD);
			MPI_Send(readBuf+start_pos[k], length, MPI_CHAR, MPIcontrol->rank+k, 1, MPI_COMM_WORLD);
		}
		localEnd = start_pos[1];
		delete [] start_pos;
	}	
	else
	{
		unsigned long long length;
		MPI_Recv(&length, 1, MPI_LONG_LONG_INT, MPIcontrol->rank-MPIcontrol->rank%gProc, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
		char *buffer = new char [length+2];	
		MPI_Recv(buffer, length, MPI_CHAR, MPIcontrol->rank-MPIcontrol->rank%gProc, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
		readBuf = buffer;
		localEnd = length;
	}
}

// Assembly:
subq $0x98, %rsp
movq %rdi, 0x90(%rsp)
movq %rsi, 0x88(%rsp)
movq %rdx, 0x80(%rsp)
movq %rcx, 0x78(%rsp)
movq %r8, 0x70(%rsp)
movq %r9, 0x68(%rsp)
movq 0x80(%rsp), %rax
movl 0x278(%rax), %eax
movl %eax, 0x64(%rsp)
movq 0x80(%rsp), %rax
movl (%rax), %eax
cltd
idivl 0x64(%rsp)
cmpl $0x0, %edx
jne 0xb28b
movl 0x64(%rsp), %eax
addl $0x1, %eax
cltq
movl $0x8, %ecx
mulq %rcx
movq %rax, %rdi
seto %cl
movq $-0x1, %rax
testb $0x1, %cl
cmovneq %rax, %rdi
callq 0x8030
movq %rax, 0x50(%rsp)
movq 0x70(%rsp), %rax
movq (%rax), %rax
subq $0x1, %rax
movslq 0x64(%rsp), %rcx
cqto
idivq %rcx
addq $0x1, %rax
movq %rax, 0x58(%rsp)
movl $0x0, 0x4c(%rsp)
movl 0x4c(%rsp), %eax
cmpl 0x64(%rsp), %eax
jge 0xb187
movq 0x58(%rsp), %rax
movslq 0x4c(%rsp), %rcx
imulq %rcx, %rax
movq %rax, 0x40(%rsp)
movq 0x40(%rsp), %rcx
movq 0x70(%rsp), %rdx
xorl %eax, %eax
cmpq (%rdx), %rcx
movb %al, 0x1f(%rsp)
jge 0xb0ef
movq 0x78(%rsp), %rax
movq (%rax), %rax
movq 0x40(%rsp), %rcx
movsbl (%rax,%rcx), %eax
cmpl $0x3e, %eax
setne %al
movb %al, 0x1f(%rsp)
movb 0x1f(%rsp), %al
testb $0x1, %al
jne 0xb0f9
jmp 0xb109
movq 0x40(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x40(%rsp)
jmp 0xb0bf
movq 0x40(%rsp), %rcx
movq 0x70(%rsp), %rdx
movb $0x1, %al
cmpq (%rdx), %rcx
movb %al, 0x1e(%rsp)
je 0xb139
movq 0x78(%rsp), %rax
movq (%rax), %rax
movq 0x40(%rsp), %rcx
movsbl (%rax,%rcx), %eax
cmpl $0x3e, %eax
sete %al
movb %al, 0x1e(%rsp)
movb 0x1e(%rsp), %al
testb $0x1, %al
jne 0xb143
jmp 0xb145
jmp 0xb164
leaq 0xb267(%rip), %rdi      # 0x163b3
leaq 0xaf00(%rip), %rsi      # 0x16053
movl $0x1a4, %edx            # imm = 0x1A4
leaq 0xb273(%rip), %rcx      # 0x163d2
callq 0x83d0
movq 0x40(%rsp), %rdx
movq 0x50(%rsp), %rax
movslq 0x4c(%rsp), %rcx
movq %rdx, (%rax,%rcx,8)
movl 0x4c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x4c(%rsp)
jmp 0xb09e
movq 0x70(%rsp), %rax
movq (%rax), %rdx
movq 0x50(%rsp), %rax
movslq 0x64(%rsp), %rcx
movq %rdx, (%rax,%rcx,8)
movl $0x1, 0x3c(%rsp)
movl 0x3c(%rsp), %eax
cmpl 0x64(%rsp), %eax
jge 0xb25b
movq 0x50(%rsp), %rax
movl 0x3c(%rsp), %ecx
addl $0x1, %ecx
movslq %ecx, %rcx
movq (%rax,%rcx,8), %rax
movq 0x50(%rsp), %rcx
movslq 0x3c(%rsp), %rdx
subq (%rcx,%rdx,8), %rax
movq %rax, 0x30(%rsp)
movq 0x80(%rsp), %rax
movl (%rax), %ecx
addl 0x3c(%rsp), %ecx
leaq 0x30(%rsp), %rdi
movl $0x1, %esi
movq 0x11da8(%rip), %rdx     # 0x1cfa0
xorl %r8d, %r8d
movq 0x11d8e(%rip), %r9      # 0x1cf90
callq 0x81c0
movq 0x78(%rsp), %rax
movq (%rax), %rdi
movq 0x50(%rsp), %rax
movslq 0x3c(%rsp), %rcx
addq (%rax,%rcx,8), %rdi
movq 0x30(%rsp), %rax
movl %eax, %esi
movq 0x80(%rsp), %rax
movl (%rax), %ecx
addl 0x3c(%rsp), %ecx
movq 0x11d3f(%rip), %rdx     # 0x1cf78
movl $0x1, %r8d
movq 0x11d4a(%rip), %r9      # 0x1cf90
callq 0x81c0
movl 0x3c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x3c(%rsp)
jmp 0xb1a5
movq 0x50(%rsp), %rax
movq 0x8(%rax), %rcx
movq 0x70(%rsp), %rax
movq %rcx, (%rax)
movq 0x50(%rsp), %rax
movq %rax, 0x10(%rsp)
cmpq $0x0, %rax
je 0xb286
movq 0x10(%rsp), %rdi
callq 0x8870
jmp 0xb347
movq 0x80(%rsp), %rax
movl (%rax), %ecx
movq 0x80(%rsp), %rax
movl (%rax), %eax
cltd
idivl 0x64(%rsp)
subl %edx, %ecx
leaq 0x28(%rsp), %rdi
movl $0x1, %esi
movq 0x11ce9(%rip), %rdx     # 0x1cfa0
xorl %r8d, %r8d
movq 0x11ccf(%rip), %r9      # 0x1cf90
xorl %eax, %eax
movq $0x0, (%rsp)
callq 0x8550
movq 0x28(%rsp), %rdi
addq $0x2, %rdi
callq 0x8030
movq %rax, 0x20(%rsp)
movq 0x20(%rsp), %rdi
movq 0x28(%rsp), %rax
movl %eax, %esi
movq 0x80(%rsp), %rax
movl (%rax), %ecx
movq 0x80(%rsp), %rax
movl (%rax), %eax
cltd
idivl 0x64(%rsp)
subl %edx, %ecx
movq 0x11c67(%rip), %rdx     # 0x1cf78
movl $0x1, %r8d
movq 0x11c72(%rip), %r9      # 0x1cf90
xorl %eax, %eax
movq $0x0, (%rsp)
callq 0x8550
movq 0x20(%rsp), %rcx
movq 0x78(%rsp), %rax
movq %rcx, (%rax)
movq 0x28(%rsp), %rcx
movq 0x70(%rsp), %rax
movq %rcx, (%rax)
addq $0x98, %rsp
retq
nop