// File: xbai0624[P]dnn/src/ConstructLayer.cpp
// Function: ConstructLayer::BatchInit()
void ConstructLayer::BatchInit()
{
    // init image dimension before each batch starts
    // the necessity of this function is originated from drop out in fc layer
    // fc layer drop out changes the dimension of the images

    // init drop out filters; reset all filters to true
    //InitFilters();

    if(__use_drop_out)  // drop out
    {
        // use different drop-out branches in a rolling sequence
        __dropOutBranchIndex++;
        __dropOutBranchIndex = __dropOutBranchIndex%__dropOutBranches;
        DropOut();
    }

    // only fc layer; cnn layer image won't change
    if(__type == LayerType::fullyConnected || __type == LayerType::output) 
    {
        UpdateCoordsForActiveNeuronFC();
    }

    // prepare weights and bias
    UpdateActiveWeightsAndBias();

    // assign active weights and bias to neurons
    AssignWeightsAndBiasToNeurons();

    // clear training information from last batch for this layer
    ClearImage();

    int batch_size = __p_data_interface->GetBatchSize();
    __imageA.resize(batch_size);
    __imageZ.resize(batch_size);
    __imageSigmaPrime.resize(batch_size);
    __imageDelta.resize(batch_size);

    __imageAFull.resize(batch_size);
    __imageZFull.resize(batch_size);
    __imageSigmaPrimeFull.resize(batch_size);
    __imageDeltaFull.resize(batch_size);
    __outputLayerCost.resize(batch_size);

    __wGradient.clear(); // these two needs to be cleared, not resized
    __bGradient.clear(); // these two needs to be cleared, not resized

    // clear training information from last batch for neurons inside this layer
    for(auto &pixel_2d: __neurons)
    {
        auto dim = pixel_2d.Dimension();
        for(size_t i=0;i<dim.first;i++)
        {
            for(size_t j=0;j<dim.second;j++)
            {
                pixel_2d[i][j]->ClearPreviousBatch();
            }
        }
    }

    // batch normalization
    __imageZ_BN.resize(batch_size);
    __imageZFull_BN.resize(batch_size);
    __imageY_BN.resize(batch_size);
    __imageYFull_BN.resize(batch_size);
    __imageAverage_BN.resize(1); // each batch has only one \mu and \sigma
    __imageAverageFull_BN.resize(1);
    __imageVariance_BN.resize(1);
    __imageVarianceFull_BN.resize(1);
    __imageDelta_BN.resize(batch_size);
    __imageDeltaFull_BN.resize(batch_size);
}

// Assembly:
subq $0x58, %rsp
movq %rdi, 0x50(%rsp)
movq 0x50(%rsp), %rax
movq %rax, (%rsp)
testb $0x1, 0x3c8(%rax)
je 0x7864
movq (%rsp), %rdi
movq 0x3d0(%rdi), %rax
addq $0x1, %rax
movq %rax, 0x3d0(%rdi)
movq 0x3d0(%rdi), %rax
movslq 0x3cc(%rdi), %rcx
xorl %edx, %edx
divq %rcx
movq %rdx, 0x3d0(%rdi)
movq (%rdi), %rax
callq *0x130(%rax)
movq (%rsp), %rax
cmpl $0x0, 0xc(%rax)
je 0x7878
movq (%rsp), %rax
cmpl $0x4, 0xc(%rax)
jne 0x7885
movq (%rsp), %rdi
movq (%rdi), %rax
callq *0x108(%rax)
movq (%rsp), %rdi
movq (%rdi), %rax
callq *0x110(%rax)
movq (%rsp), %rdi
movq (%rdi), %rax
callq *0x118(%rax)
movq (%rsp), %rdi
movq (%rdi), %rax
callq *0x160(%rax)
movq (%rsp), %rax
movq 0x400(%rax), %rdi
callq 0x1f310
movq (%rsp), %rdi
movl %eax, 0x4c(%rsp)
addq $0x138, %rdi            # imm = 0x138
movslq 0x4c(%rsp), %rsi
callq 0x1f320
movq (%rsp), %rdi
addq $0x150, %rdi            # imm = 0x150
movslq 0x4c(%rsp), %rsi
callq 0x1f320
movq (%rsp), %rdi
addq $0x168, %rdi            # imm = 0x168
movslq 0x4c(%rsp), %rsi
callq 0x1f320
movq (%rsp), %rdi
addq $0x180, %rdi            # imm = 0x180
movslq 0x4c(%rsp), %rsi
callq 0x1f320
movq (%rsp), %rdi
addq $0x198, %rdi            # imm = 0x198
movslq 0x4c(%rsp), %rsi
callq 0x1f320
movq (%rsp), %rdi
addq $0x1b0, %rdi            # imm = 0x1B0
movslq 0x4c(%rsp), %rsi
callq 0x1f320
movq (%rsp), %rdi
addq $0x1c8, %rdi            # imm = 0x1C8
movslq 0x4c(%rsp), %rsi
callq 0x1f320
movq (%rsp), %rdi
addq $0x1e0, %rdi            # imm = 0x1E0
movslq 0x4c(%rsp), %rsi
callq 0x1f320
movq (%rsp), %rdi
addq $0x1f8, %rdi            # imm = 0x1F8
movslq 0x4c(%rsp), %rsi
callq 0x1f3c0
movq (%rsp), %rdi
addq $0x90, %rdi
callq 0x1f460
movq (%rsp), %rdi
addq $0xa8, %rdi
callq 0x1f460
movq (%rsp), %rax
addq $0x40, %rax
movq %rax, 0x40(%rsp)
movq 0x40(%rsp), %rdi
callq 0x1f480
movq %rax, 0x38(%rsp)
movq 0x40(%rsp), %rdi
callq 0x1f4b0
movq %rax, 0x30(%rsp)
leaq 0x38(%rsp), %rdi
leaq 0x30(%rsp), %rsi
callq 0x1f4e0
testb $0x1, %al
jne 0x79e0
jmp 0x7a84
leaq 0x38(%rsp), %rdi
callq 0x1f520
movq %rax, 0x28(%rsp)
movq 0x28(%rsp), %rdi
callq 0x1f530
movq %rax, 0x18(%rsp)
movq %rdx, 0x20(%rsp)
movq $0x0, 0x10(%rsp)
movq 0x10(%rsp), %rax
cmpq 0x18(%rsp), %rax
jae 0x7a73
movq $0x0, 0x8(%rsp)
movq 0x8(%rsp), %rax
cmpq 0x20(%rsp), %rax
jae 0x7a61
movq 0x28(%rsp), %rdi
movq 0x10(%rsp), %rsi
callq 0x1f5c0
movq %rax, %rdi
movq 0x8(%rsp), %rsi
callq 0x1f5f0
movq (%rax), %rdi
callq 0x4a2f0
movq 0x8(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x8(%rsp)
jmp 0x7a21
jmp 0x7a63
movq 0x10(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x10(%rsp)
jmp 0x7a0c
jmp 0x7a75
leaq 0x38(%rsp), %rdi
callq 0x1f610
jmp 0x79c8
movq (%rsp), %rdi
addq $0x218, %rdi            # imm = 0x218
movslq 0x4c(%rsp), %rsi
callq 0x1f320
movq (%rsp), %rdi
addq $0x230, %rdi            # imm = 0x230
movslq 0x4c(%rsp), %rsi
callq 0x1f320
movq (%rsp), %rdi
addq $0x248, %rdi            # imm = 0x248
movslq 0x4c(%rsp), %rsi
callq 0x1f320
movq (%rsp), %rdi
addq $0x260, %rdi            # imm = 0x260
movslq 0x4c(%rsp), %rsi
callq 0x1f320
movq (%rsp), %rdi
addq $0x278, %rdi            # imm = 0x278
movl $0x1, %esi
callq 0x1f320
movq (%rsp), %rdi
addq $0x290, %rdi            # imm = 0x290
movl $0x1, %esi
callq 0x1f320
movq (%rsp), %rdi
addq $0x2a8, %rdi            # imm = 0x2A8
movl $0x1, %esi
callq 0x1f320
movq (%rsp), %rdi
addq $0x2c0, %rdi            # imm = 0x2C0
movl $0x1, %esi
callq 0x1f320
movq (%rsp), %rdi
addq $0x2d8, %rdi            # imm = 0x2D8
movslq 0x4c(%rsp), %rsi
callq 0x1f320
movq (%rsp), %rdi
addq $0x2f0, %rdi            # imm = 0x2F0
movslq 0x4c(%rsp), %rsi
callq 0x1f320
addq $0x58, %rsp
retq
nopl (%rax,%rax)