// File: /workspace/github_cpp_makefile_star2_O2/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
pushq $0x18
popq %rcx
cqto
idivq %rcx
movslq 0xc(%rdi), %rcx
xorl %edx, %edx
divq %rcx
leaq -0x44(%rbp), %rdi
movl %eax, (%rdi)
leaq -0x2c(%rbp), %rsi
andl $0x0, (%rsi)
movq 0x346b(%rip), %rcx      # 0x5fd8
movq 0x3434(%rip), %r8       # 0x5fa8
movq 0x3435(%rip), %r15      # 0x5fb0
pushq $0x1
popq %rdx
movq %r15, %r9
callq 0x2200
xorl %r12d, %r12d
leaq 0x50(%rbx), %r13
leaq 0x28(%rbx), %rax
movq %rax, -0x40(%rbp)
movq 0x3424(%rip), %r14      # 0x5fc0
cmpl 0x8(%rbx), %r12d
jge 0x2d2d
andl $0x0, 0x50(%rbx)
movq 0x341f(%rip), %rdi      # 0x5fd0
leaq 0x14bc(%rip), %rsi      # 0x4074
callq 0x21a0
movl 0x84(%rbx), %esi
movq %rax, %rdi
callq 0x22c0
movq %rax, %rdi
leaq 0x14ec(%rip), %rsi      # 0x40c1
callq 0x21a0
movq %rax, %rdi
movl %r12d, %esi
callq 0x22c0
movq %rax, %rdi
leaq 0x14da(%rip), %rsi      # 0x40c9
callq 0x21a0
movq %rax, %rdi
xorl %esi, %esi
callq 0x22c0
movq %rax, %rdi
callq 0x20f0
movq (%rbx), %rsi
movq 0x48(%rbx), %rdi
callq 0x2d3c
cmpl $0x1, -0x2c(%rbp)
je 0x2d2d
movq %r12, -0x38(%rbp)
movslq 0x50(%rbx), %rcx
movq 0x40(%rbx), %rdx
movq 0x210(%rdx), %rax
subq 0x208(%rdx), %rax
cqto
pushq $0x18
popq %rsi
idivq %rsi
cmpq %rcx, %rax
jbe 0x2d21
movq %rbx, %rdi
movq %r13, %rsi
callq 0x35c6
movq 0x40(%rbx), %rax
movq 0x58(%rbx), %rdi
movq 0x2a0(%rax), %rsi
cvtsi2ssl 0xc(%rbx), %xmm0
testq %rsi, %rsi
movl $0x0, %eax
cmovgq %rsi, %rax
xorl %ecx, %ecx
cmpq %rcx, %rax
je 0x2c8c
movss (%rdi,%rcx,4), %xmm1
divss %xmm0, %xmm1
movss %xmm1, (%rdi,%rcx,4)
incq %rcx
jmp 0x2c74
cmpl $0x0, 0x84(%rbx)
je 0x2ca8
movq %r14, %rdx
xorl %ecx, %ecx
pushq $0x63
popq %r8
movq %r15, %r9
callq 0x20b0
jmp 0x2cb0
movq %rbx, %rdi
callq 0x36b0
cmpl $0x0, 0x84(%rbx)
je 0x2cee
movq (%rbx), %rdi
movq 0x40(%rbx), %rax
movl 0x2a0(%rax), %esi
movq -0x40(%rbp), %rax
movq %rax, (%rsp)
movq %r14, %rdx
xorl %ecx, %ecx
movl $0x3e7, %r8d            # imm = 0x3E7
movq %r15, %r9
callq 0x2160
movq %r15, %rdi
callq 0x2130
jmp 0x2c20
pushq $0x1
popq %r12
cmpl 0x80(%rbx), %r12d
jge 0x2ce1
movq (%rbx), %rdi
movq 0x40(%rbx), %rax
movl 0x2a0(%rax), %esi
movq %r14, %rdx
movl %r12d, %ecx
movl $0x3e7, %r8d            # imm = 0x3E7
movq %r15, %r9
callq 0x20b0
incl %r12d
jmp 0x2cf2
movq -0x38(%rbp), %r12
incl %r12d
jmp 0x2b9c
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq