// File: liujan[P]MPI_multi_thread_randomforest/main.cpp
// Function: main
int main(int argc,  char * argv[]) {
	// insert code here...
	std::cout << "Hello, World!\n";

	int mypid, size, namelen;
    char name[MPI_MAX_PROCESSOR_NAME];
    MPI_Status status;
    MPI_Init(&argc, &argv);

    MPI_Datatype ctype;

    new_type(&ctype);

    MPI_Comm_rank(MPI_COMM_WORLD, &mypid); 
    MPI_Comm_size(MPI_COMM_WORLD, &size);
    MPI_Get_processor_name(name, &namelen);
    cout << mypid << " of process " << size << " from " << name << endl;   


    if (mypid == 0){
        double result[numOfTest][numOfTypes+1];
        memset(result, 0, sizeof(result));
        ofstream out("result.csv");
        out << "Id,label" << "\n";

        for (int i = 1; i < size; i++) {
            struct Sample *sample = new Sample();
            MPI_Recv(sample, 1, ctype, i, 1, MPI_COMM_WORLD, &status);

            for (int j = 0; j < numOfTest; j++){
                for (int k = 0; k <= numOfTypes; k++){
                    result[j][k] += sample->result[j][k];
                }
            }
            delete sample;
        }
        cout << "writing to file result.csv of " << name << " ..."<< endl;
        for (int i = 0; i < numOfTest; i++){
            int max_value = -10, index = 0;
            for (int j = 0; j <= numOfTypes; j++){
                if (result[i][j] >= max_value){
                    max_value = result[i][j];
                    index = j;
                }
            }
            out << i << "," << index << "\n";
        }
        cout << "writing over" << endl;
        out.close();

        int *tmp = new int;
        *tmp = 23;
        for (int i = 1; i < size; i++)
            MPI_Send(tmp, 1, MPI_INT, i, 0, MPI_COMM_WORLD);
    }
    else{
        struct Sample *sample = new Sample();

        RandomForest forest;
        forest.readTrainSample("train.csv");
		forest.readTestSample("test.csv");
	    forest.buildTree(1200);
	    int **result = forest.predict();

        for (int i = 0; i < numOfTest; i++) {
            for (int j = 0; j <= numOfTypes; j++){
                sample->result[i][j] = result[i][j];
            }
        }
        
        MPI_Send(sample, 1, ctype, 0, 1, MPI_COMM_WORLD);
        int *tmp = new int;
        MPI_Recv(tmp, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, &status);
        
    }


	
	return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x52830, %rsp          # imm = 0x52830
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq 0x12230(%rip), %rdi     # 0x28fd0
leaq 0x643a(%rip), %rsi      # 0x1d1e1
callq 0x9660
leaq -0x8(%rbp), %rdi
leaq -0x10(%rbp), %rsi
callq 0x99c0
leaq -0x140(%rbp), %rdi
callq 0x16d20
movq 0x121e4(%rip), %rdi     # 0x28fb0
leaq -0x14(%rbp), %rsi
callq 0x99b0
movq 0x121d4(%rip), %rdi     # 0x28fb0
leaq -0x18(%rbp), %rsi
callq 0x97e0
leaq -0x120(%rbp), %rdi
leaq -0x1c(%rbp), %rsi
callq 0x97c0
movl -0x14(%rbp), %esi
movq 0x121d1(%rip), %rdi     # 0x28fd0
callq 0x9be0
movq %rax, %rdi
leaq 0x63e2(%rip), %rsi      # 0x1d1f0
callq 0x9660
movq %rax, %rdi
movl -0x18(%rbp), %esi
callq 0x9be0
movq %rax, %rdi
leaq 0x63d5(%rip), %rsi      # 0x1d1fd
callq 0x9660
movq %rax, %rdi
leaq -0x120(%rbp), %rsi
callq 0x9660
movq %rax, %rdi
movq 0x12162(%rip), %rsi     # 0x28fa8
callq 0x96b0
cmpl $0x0, -0x14(%rbp)
jne 0x172ae
leaq -0x524b0(%rbp), %rdi
xorl %esi, %esi
movl $0x52368, %edx          # imm = 0x52368
callq 0x9310
leaq 0x6395(%rip), %rsi      # 0x1d204
leaq -0x526b0(%rbp), %rdi
movq %rdi, -0x527a8(%rbp)
movl $0x10, %edx
callq 0x9740
movq -0x527a8(%rbp), %rdi
leaq 0x637a(%rip), %rsi      # 0x1d20f
callq 0x9660
movq %rax, -0x527a0(%rbp)
jmp 0x16ea3
movq -0x527a0(%rbp), %rdi
leaq 0x633d(%rip), %rsi      # 0x1d1ee
callq 0x9660
jmp 0x16eb8
movl $0x1, -0x526c0(%rbp)
movl -0x526c0(%rbp), %eax
cmpl -0x18(%rbp), %eax
jge 0x17039
movl $0x291b4, %edi          # imm = 0x291B4
callq 0x9670
movq %rax, -0x527b0(%rbp)
jmp 0x16ee4
movq -0x527b0(%rbp), %rdi
xorl %esi, %esi
movl $0x291b4, %edx          # imm = 0x291B4
callq 0x9310
movq -0x527b0(%rbp), %rax
movq %rax, -0x526c8(%rbp)
movq -0x526c8(%rbp), %rdi
movq -0x140(%rbp), %rdx
movl -0x526c0(%rbp), %ecx
movq %rsp, %rax
leaq -0x138(%rbp), %rsi
movq %rsi, (%rax)
movq 0x12083(%rip), %r9      # 0x28fb0
movl $0x1, %r8d
movl %r8d, %esi
callq 0x9550
jmp 0x16f3d
movl $0x0, -0x526cc(%rbp)
cmpl $0x617, -0x526cc(%rbp)  # imm = 0x617
jge 0x16ffe
movl $0x0, -0x526d0(%rbp)
cmpl $0x1a, -0x526d0(%rbp)
jg 0x16fe8
movq -0x526c8(%rbp), %rax
movslq -0x526cc(%rbp), %rcx
imulq $0x6c, %rcx, %rcx
addq %rcx, %rax
movslq -0x526d0(%rbp), %rcx
cvtsi2sdl (%rax,%rcx,4), %xmm0
movslq -0x526cc(%rbp), %rcx
leaq -0x524b0(%rbp), %rax
imulq $0xd8, %rcx, %rcx
addq %rcx, %rax
movslq -0x526d0(%rbp), %rcx
addsd (%rax,%rcx,8), %xmm0
movsd %xmm0, (%rax,%rcx,8)
movl -0x526d0(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x526d0(%rbp)
jmp 0x16f61
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x526b8(%rbp)
movl %eax, -0x526bc(%rbp)
leaq -0x526b0(%rbp), %rdi
callq 0x9a30
jmp 0x175b2
jmp 0x16fea
movl -0x526cc(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x526cc(%rbp)
jmp 0x16f47
movq -0x526c8(%rbp), %rax
movq %rax, -0x527b8(%rbp)
cmpq $0x0, %rax
je 0x17023
movq -0x527b8(%rbp), %rdi
movl $0x291b4, %esi          # imm = 0x291B4
callq 0x9690
jmp 0x17025
movl -0x526c0(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x526c0(%rbp)
jmp 0x16ec2
movq 0x11f90(%rip), %rdi     # 0x28fd0
leaq 0x61d1(%rip), %rsi      # 0x1d218
callq 0x9660
movq %rax, -0x527c0(%rbp)
jmp 0x17055
movq -0x527c0(%rbp), %rdi
leaq -0x120(%rbp), %rsi
callq 0x9660
movq %rax, -0x527c8(%rbp)
jmp 0x17071
movq -0x527c8(%rbp), %rdi
leaq 0x600b(%rip), %rsi      # 0x1d08a
callq 0x9660
movq %rax, -0x527d0(%rbp)
jmp 0x1708d
movq -0x527d0(%rbp), %rdi
movq 0x11f0d(%rip), %rsi     # 0x28fa8
callq 0x96b0
jmp 0x170a2
movl $0x0, -0x526d4(%rbp)
cmpl $0x617, -0x526d4(%rbp)  # imm = 0x617
jge 0x171de
movl $0xfffffff6, -0x526d8(%rbp) # imm = 0xFFFFFFF6
movl $0x0, -0x526dc(%rbp)
movl $0x0, -0x526e0(%rbp)
cmpl $0x1a, -0x526e0(%rbp)
jg 0x17161
movslq -0x526d4(%rbp), %rcx
leaq -0x524b0(%rbp), %rax
imulq $0xd8, %rcx, %rcx
addq %rcx, %rax
movslq -0x526e0(%rbp), %rcx
movsd (%rax,%rcx,8), %xmm0
cvtsi2sdl -0x526d8(%rbp), %xmm1
ucomisd %xmm1, %xmm0
jb 0x1714b
movslq -0x526d4(%rbp), %rcx
leaq -0x524b0(%rbp), %rax
imulq $0xd8, %rcx, %rcx
addq %rcx, %rax
movslq -0x526e0(%rbp), %rcx
cvttsd2si (%rax,%rcx,8), %eax
movl %eax, -0x526d8(%rbp)
movl -0x526e0(%rbp), %eax
movl %eax, -0x526dc(%rbp)
jmp 0x1714d
movl -0x526e0(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x526e0(%rbp)
jmp 0x170da
movl -0x526d4(%rbp), %esi
leaq -0x526b0(%rbp), %rdi
callq 0x9be0
movq %rax, -0x527d8(%rbp)
jmp 0x1717c
movq -0x527d8(%rbp), %rdi
leaq 0x60ad(%rip), %rsi      # 0x1d237
callq 0x9660
movq %rax, -0x527e0(%rbp)
jmp 0x17198
movq -0x527e0(%rbp), %rdi
movl -0x526dc(%rbp), %esi
callq 0x9be0
movq %rax, -0x527e8(%rbp)
jmp 0x171b3
movq -0x527e8(%rbp), %rdi
leaq 0x602d(%rip), %rsi      # 0x1d1ee
callq 0x9660
jmp 0x171c8
jmp 0x171ca
movl -0x526d4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x526d4(%rbp)
jmp 0x170ac
movq 0x11deb(%rip), %rdi     # 0x28fd0
leaq 0x604d(%rip), %rsi      # 0x1d239
callq 0x9660
movq %rax, -0x527f0(%rbp)
jmp 0x171fa
movq -0x527f0(%rbp), %rdi
movq 0x11da0(%rip), %rsi     # 0x28fa8
callq 0x96b0
jmp 0x1720f
leaq -0x526b0(%rbp), %rdi
callq 0x99d0
jmp 0x1721d
movl $0x4, %edi
callq 0x9670
movq %rax, -0x527f8(%rbp)
jmp 0x17230
movq -0x527f8(%rbp), %rax
movq %rax, -0x526e8(%rbp)
movq -0x526e8(%rbp), %rax
movl $0x17, (%rax)
movl $0x1, -0x526ec(%rbp)
movl -0x526ec(%rbp), %eax
cmpl -0x18(%rbp), %eax
jge 0x1729d
movq -0x526e8(%rbp), %rdi
movl -0x526ec(%rbp), %ecx
movq 0x11d64(%rip), %rdx     # 0x28fd8
movq 0x11d35(%rip), %r9      # 0x28fb0
movl $0x1, %esi
xorl %r8d, %r8d
callq 0x9200
jmp 0x1728a
jmp 0x1728c
movl -0x526ec(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x526ec(%rbp)
jmp 0x17255
leaq -0x526b0(%rbp), %rdi
callq 0x9a30
jmp 0x175a7
movl $0x291b4, %edi          # imm = 0x291B4
movq %rdi, -0x52810(%rbp)
callq 0x9670
movq -0x52810(%rbp), %rdx
movq %rax, %rdi
movq %rdi, -0x52808(%rbp)
xorl %esi, %esi
callq 0x9310
movq -0x52808(%rbp), %rax
movq %rax, -0x526f8(%rbp)
leaq -0x52730(%rbp), %rdi
callq 0x15570
leaq -0x52751(%rbp), %rdi
movq %rdi, -0x52800(%rbp)
callq 0x9c20
movq -0x52800(%rbp), %rdx
leaq 0x5e39(%rip), %rsi      # 0x1d14b
leaq -0x52750(%rbp), %rdi
callq 0x17ca0
jmp 0x17320
leaq -0x52730(%rbp), %rdi
leaq -0x52750(%rbp), %rsi
callq 0x15b90
jmp 0x17335
leaq -0x52750(%rbp), %rdi
callq 0x93b0
leaq -0x52751(%rbp), %rdi
callq 0x9720
leaq -0x52779(%rbp), %rdi
movq %rdi, -0x52818(%rbp)
callq 0x9c20
movq -0x52818(%rbp), %rdx
leaq 0x5e33(%rip), %rsi      # 0x1d1a1
leaq -0x52778(%rbp), %rdi
callq 0x17ca0
jmp 0x1737c
leaq -0x52730(%rbp), %rdi
leaq -0x52778(%rbp), %rsi
callq 0x15f30
jmp 0x17391
leaq -0x52778(%rbp), %rdi
callq 0x93b0
leaq -0x52779(%rbp), %rdi
callq 0x9720
leaq -0x52730(%rbp), %rdi
movl $0x4b0, %esi            # imm = 0x4B0
callq 0x15860
jmp 0x173bc
leaq -0x52730(%rbp), %rdi
callq 0x15af0
movq %rax, -0x52820(%rbp)
jmp 0x173d1
movq -0x52820(%rbp), %rax
movq %rax, -0x52788(%rbp)
movl $0x0, -0x5278c(%rbp)
cmpl $0x617, -0x5278c(%rbp)  # imm = 0x617
jge 0x1750f
movl $0x0, -0x52790(%rbp)
cmpl $0x1a, -0x52790(%rbp)
jg 0x174f9
movq -0x52788(%rbp), %rax
movslq -0x5278c(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movslq -0x52790(%rbp), %rcx
movl (%rax,%rcx,4), %edx
movq -0x526f8(%rbp), %rax
movslq -0x5278c(%rbp), %rcx
imulq $0x6c, %rcx, %rcx
addq %rcx, %rax
movslq -0x52790(%rbp), %rcx
movl %edx, (%rax,%rcx,4)
movl -0x52790(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x52790(%rbp)
jmp 0x17403
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x526b8(%rbp)
movl %eax, -0x526bc(%rbp)
jmp 0x1748e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x526b8(%rbp)
movl %eax, -0x526bc(%rbp)
leaq -0x52750(%rbp), %rdi
callq 0x93b0
leaq -0x52751(%rbp), %rdi
callq 0x9720
jmp 0x17599
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x526b8(%rbp)
movl %eax, -0x526bc(%rbp)
jmp 0x174d1
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x526b8(%rbp)
movl %eax, -0x526bc(%rbp)
leaq -0x52778(%rbp), %rdi
callq 0x93b0
leaq -0x52779(%rbp), %rdi
callq 0x9720
jmp 0x17599
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x526b8(%rbp)
movl %eax, -0x526bc(%rbp)
jmp 0x17599
jmp 0x174fb
movl -0x5278c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x5278c(%rbp)
jmp 0x173e9
movq -0x526f8(%rbp), %rdi
movq -0x140(%rbp), %rdx
movq 0x11a8c(%rip), %r9      # 0x28fb0
xorl %ecx, %ecx
movl $0x1, %r8d
movl %r8d, %esi
callq 0x9200
jmp 0x17536
movl $0x4, %edi
callq 0x9670
movq %rax, -0x52828(%rbp)
jmp 0x17549
movq -0x52828(%rbp), %rax
movq %rax, -0x52798(%rbp)
movq -0x52798(%rbp), %rdi
movq %rsp, %rax
leaq -0x138(%rbp), %rcx
movq %rcx, (%rax)
movq 0x11a66(%rip), %rdx     # 0x28fd8
movq 0x11a37(%rip), %r9      # 0x28fb0
movl $0x1, %esi
xorl %r8d, %r8d
movl %r8d, %ecx
callq 0x9550
jmp 0x1758b
leaq -0x52730(%rbp), %rdi
callq 0x162c0
jmp 0x175a7
leaq -0x52730(%rbp), %rdi
callq 0x162c0
jmp 0x175b2
xorl %eax, %eax
addq $0x52830, %rsp          # imm = 0x52830
popq %rbp
retq
movq -0x526b8(%rbp), %rdi
callq 0x9c10
nop