// File: /workspace/github_cpp_makefile_star2_O1/poseidon1214[P]logistic-regression-ftrl-mpi/src/ftrl.h
// Function: FTRL::ftrl()
void ftrl(){
            int batch_num = data->fea_matrix.size() / batch_size;
            int batch_num_min = 0;
            MPI_Allreduce(&batch_num, &batch_num_min, 1, MPI_INT, MPI_MIN, MPI_COMM_WORLD);
            for(int epoch = 0; epoch < epochs; epoch++){
                row = 0;
                int batches = 0;
                if(epoch % 5 == 0  || batches % 1000 == 0){
                    std::cout<<"rank "<<rank<<" epoch "<<epoch<<" batch "<<batches<<std::endl;
                    pred->run(loc_w);
                }
                if( (batches == batch_num_min - 1) ) break;
                while(row < data->fea_matrix.size()){
                    batch_gradient_calculate(row);
                    for(int col = 0; col < data->glo_fea_dim; col++){
                        loc_g[col] /= batch_size;
                    }

                    if(rank != 0){//slave nodes send gradient to master node;
                        MPI_Send(loc_g, data->glo_fea_dim, MPI_FLOAT, 0, 99, MPI_COMM_WORLD);
                    }
                    else if(rank == 0){//rank 0 is master node
                        update();
                    }
                    //sync w of all nodes in cluster
                    if(rank == 0){
                        for(int r = 1; r < num_proc; r++){
                            MPI_Send(loc_w, data->glo_fea_dim, MPI_FLOAT, r, 999, MPI_COMM_WORLD);
                        }
                    }
                    else if(rank != 0){
                        MPI_Recv(loc_w, data->glo_fea_dim, MPI_FLOAT, 0, 999, MPI_COMM_WORLD, &status);
                    }
                    MPI_Barrier(MPI_COMM_WORLD);//will it make the procedure slowly? is it necessary?
                }//end row while
                batches++;
            }//end epoch for
        }

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movq %rdi, %rbx
movq 0x40(%rdi), %rcx
movq 0x210(%rcx), %rax
subq 0x208(%rcx), %rax
sarq $0x3, %rax
movabsq $-0x5555555555555555, %rcx # imm = 0xAAAAAAAAAAAAAAAB
imulq %rcx, %rax
movslq 0xc(%rdi), %rcx
movq $0x0, -0x30(%rbp)
xorl %edx, %edx
divq %rcx
leaq -0x44(%rbp), %rdi
movl %eax, (%rdi)
leaq -0x38(%rbp), %rsi
movl $0x0, (%rsi)
movq 0x4180(%rip), %rcx      # 0x6fd8
movq 0x4149(%rip), %r8       # 0x6fa8
movq 0x414a(%rip), %r9       # 0x6fb0
movl $0x1, %edx
callq 0x2240
cmpl $0x0, 0x8(%rbx)
jle 0x307c
leaq 0x50(%rbx), %r15
leaq 0x28(%rbx), %rax
movq %rax, -0x40(%rbp)
movq 0x4133(%rip), %r13      # 0x6fc0
movq 0x411c(%rip), %r12      # 0x6fb0
movl $0x0, 0x50(%rbx)
movl $0x5, %edx
movq 0x4129(%rip), %r14      # 0x6fd0
movq %r14, %rdi
leaq 0x21c3(%rip), %rsi      # 0x5074
callq 0x2210
movl 0x84(%rbx), %esi
movq %r14, %rdi
callq 0x2310
movq %rax, %r14
movl $0x7, %edx
movq %rax, %rdi
leaq 0x21eb(%rip), %rsi      # 0x50c1
callq 0x2210
movq %r14, %rdi
movq -0x30(%rbp), %rsi
callq 0x2310
movq %rax, %r14
movl $0x7, %edx
movq %rax, %rdi
leaq 0x21d0(%rip), %rsi      # 0x50c9
callq 0x2210
movq %r14, %rdi
xorl %esi, %esi
callq 0x2310
movq %rax, %r14
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x21b0
movsbl %al, %esi
movq %r14, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2140
movq (%rbx), %rsi
movq 0x48(%rbx), %rdi
callq 0x308c
movl -0x38(%rbp), %eax
cmpl $0x1, %eax
je 0x307c
movl %eax, -0x34(%rbp)
movq 0x40(%rbx), %rax
movq 0x210(%rax), %rcx
subq 0x208(%rax), %rcx
movslq 0x50(%rbx), %rax
sarq $0x3, %rcx
movabsq $-0x5555555555555555, %rdx # imm = 0xAAAAAAAAAAAAAAAB
imulq %rdx, %rcx
cmpq %rax, %rcx
jbe 0x3063
movq %rbx, %rdi
movq %r15, %rsi
callq 0x3920
movq 0x40(%rbx), %rax
movq 0x2a0(%rax), %rsi
testq %rsi, %rsi
jle 0x2fbd
xorps %xmm0, %xmm0
cvtsi2ssl 0xc(%rbx), %xmm0
movq 0x58(%rbx), %rax
xorl %ecx, %ecx
movss (%rax,%rcx,4), %xmm1
divss %xmm0, %xmm1
movss %xmm1, (%rax,%rcx,4)
incq %rcx
cmpq %rcx, %rsi
jne 0x2fa7
cmpl $0x0, 0x84(%rbx)
je 0x2fdf
movq 0x58(%rbx), %rdi
movq %r13, %rdx
xorl %ecx, %ecx
movl $0x63, %r8d
movq %r12, %r9
callq 0x20b0
jmp 0x2fe7
movq %rbx, %rdi
callq 0x3a94
cmpl $0x0, 0x84(%rbx)
je 0x301a
movq (%rbx), %rdi
movq 0x40(%rbx), %rax
movl 0x2a0(%rax), %esi
movq -0x40(%rbp), %rax
movq %rax, (%rsp)
movq %r13, %rdx
xorl %ecx, %ecx
movl $0x3e7, %r8d            # imm = 0x3E7
movq %r12, %r9
callq 0x2180
jmp 0x3056
cmpl $0x2, 0x80(%rbx)
jl 0x3056
movl $0x1, %r14d
movq (%rbx), %rdi
movq 0x40(%rbx), %rax
movl 0x2a0(%rax), %esi
movq %r13, %rdx
movl %r14d, %ecx
movl $0x3e7, %r8d            # imm = 0x3E7
movq %r12, %r9
callq 0x20b0
incl %r14d
cmpl 0x80(%rbx), %r14d
jl 0x3029
movq %r12, %rdi
callq 0x2150
jmp 0x2f4d
cmpl $0x1, -0x34(%rbp)
je 0x307c
movq -0x30(%rbp), %rax
incl %eax
movq %rax, -0x30(%rbp)
cmpl 0x8(%rbx), %eax
jl 0x2e94
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop