// File: /workspace/github_cpp_makefile_star2_O2/xbai0624[P]dnn/src/Neuron.cpp
// Function: Neuron::UpdateZFC(int)
void Neuron::UpdateZFC(int sample_index)
{
    // for fully connected layer, matrix reform are also done in here
    Layer* __previousLayer = __layer->GetPrevLayer();
    std::vector<Images>& _t = __previousLayer -> GetImagesActiveA(); // this line with '&' is 5 times faster than the following line without '&'

    //cout<<"batch size: "<<_t.size()<<endl;
    //cout<<"kernel number: "<<_t[0].GetNumberOfKernels()<<endl;
    //cout<<" image dimension: "<<_t[0].OutputImageFromKernel[0].Dimension()<<endl;
    if(_t.size() < 1 || _t.size() < (size_t)sample_index) 
    {
        std::cout<<"Error: previous layer has not 'A' image."<<std::endl;
        exit(0);
    }
    //Images &images = _t[sample_index]; // get images for current sample


    double z_for_current_neuron = 0;
    // get images for current sample
    Images images;
    if(__previousLayer->GetType() != LayerType::fullyConnected/* && __previousLayer->GetType() != LayerType::input*/ )
    {
        // need vectorization 2D->1D
        // input layer vectorization is already done in DataInterface class
        images = _t[sample_index].Vectorization(); // get images for current sample
    }
    else
    {
        // previous layer is fc, no need to do anything
        images = _t[sample_index];
    }

    if(images.OutputImageFromKernel.size() != 1) 
    {
        std::cout<<"Eroor: layer type not match, expecting FC layer, FC layer should only have 1 kernel."<<std::endl;
        exit(0);
    }

    Matrix &image = images.OutputImageFromKernel[0]; // FC layer has only one "kernel" (equivalent kernel)
    //cout<<"neuron id: "<<__neuron_id<<", image A debug:"<<endl;
    //cout<<image<<endl;


    //cout<<__func__<<" CHECKING HERE!!!! weight matrix dimension: "<<(*__w).Dimension()<<endl;
    //cout<<(*__w)<<endl;
    Matrix res = (*__w) * image;
    //cout<<"res matrix: "<<endl;
    //cout<<res<<endl;
    auto dim = res.Dimension();
    if(dim.first != 1 || dim.second != 1) 
    {
        std::cout<<"Error: wrong dimension, expecting 1D matrix."<<std::endl;
    }
    z_for_current_neuron = res[0][0];

    z_for_current_neuron = z_for_current_neuron + (*__b)[0][0];

    __z[sample_index] = z_for_current_neuron;
    //cout<<__func__<<" finished."<<endl;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
subq $0x40, %rsp
movl %esi, %ebp
movq %rdi, %rbx
movq 0x78(%rdi), %rdi
movq (%rdi), %rax
callq *0x2c8(%rax)
movq %rax, %r15
movq (%rax), %rax
movq %r15, %rdi
callq *0xc8(%rax)
movq %rax, %r14
movq 0x8(%rax), %rax
subq (%r14), %rax
je 0x1c476
pushq $0x18
popq %rcx
cqto
idivq %rcx
movslq %ebp, %r12
cmpq %r12, %rax
jb 0x1c476
xorps %xmm0, %xmm0
movaps %xmm0, (%rsp)
andq $0x0, 0x10(%rsp)
movq (%r15), %rax
movq %r15, %rdi
callq *0x250(%rax)
imulq $0x18, %r12, %rsi
testl %eax, %eax
je 0x1c3bb
addq (%r14), %rsi
leaq 0x20(%rsp), %rdi
callq 0x11b66
movq %rsp, %rdi
leaq 0x20(%rsp), %r14
movq %r14, %rsi
callq 0x1d7ae
movq %r14, %rdi
callq 0x110e4
jmp 0x1c3c6
addq (%r14), %rsi
movq %rsp, %rdi
callq 0x11a9e
movq (%rsp), %rdx
movq 0x8(%rsp), %rax
subq %rdx, %rax
cmpq $0x18, %rax
jne 0x1c498
movq 0x8(%rbx), %rsi
leaq 0x20(%rsp), %rdi
callq 0x17aac
leaq 0x20(%rsp), %rdi
callq 0x17a6a
xorq $0x1, %rax
xorq $0x1, %rdx
orq %rax, %rdx
je 0x1c41c
movq 0x16bd0(%rip), %rdi     # 0x32fd8
leaq 0x881d(%rip), %rsi      # 0x24c2c
callq 0x4240
movq %rax, %rdi
callq 0x4130
leaq 0x20(%rsp), %rdi
xorl %esi, %esi
callq 0x17c46
movq (%rax), %rax
movsd (%rax), %xmm0
movsd %xmm0, 0x38(%rsp)
movq 0x10(%rbx), %rdi
xorl %esi, %esi
callq 0x17c46
movq (%rax), %rax
movsd 0x38(%rsp), %xmm0
addsd (%rax), %xmm0
movq 0x48(%rbx), %rax
movsd %xmm0, (%rax,%r12,8)
leaq 0x20(%rsp), %rdi
callq 0x17a9a
movq %rsp, %rdi
callq 0x110e4
addq $0x40, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
movq 0x16b5b(%rip), %rdi     # 0x32fd8
leaq 0x872a(%rip), %rsi      # 0x24bae
callq 0x4240
movq %rax, %rdi
callq 0x4130
xorl %edi, %edi
callq 0x4260
movq 0x16b39(%rip), %rdi     # 0x32fd8
leaq 0x8731(%rip), %rsi      # 0x24bd7
callq 0x4240
movq %rax, %rdi
callq 0x4130
jmp 0x1c491
jmp 0x1c4b9
jmp 0x1c4b9
movq %rax, %rbx
jmp 0x1c4cb
movq %rax, %rbx
leaq 0x20(%rsp), %rdi
callq 0x17a9a
movq %rsp, %rdi
callq 0x110e4
movq %rbx, %rdi
callq 0x43b0
nop