// File: /workspace/github_c_makefile_star2_O3/SimpleDoger[P]Darknet_CPU_Only/local_layer.c
// Function: make_local_layer
local_layer make_local_layer(int batch, int h, int w, int c, int n, int size, int stride, int pad, ACTIVATION activation)
{
    int i;
    local_layer l = {0};
    l.type = LOCAL;

    l.h = h;
    l.w = w;
    l.c = c;
    l.n = n;
    l.batch = batch;
    l.stride = stride;
    l.size = size;
    l.pad = pad;

    int out_h = local_out_height(l);
    int out_w = local_out_width(l);
    int locations = out_h*out_w;
    l.out_h = out_h;
    l.out_w = out_w;
    l.out_c = n;
    l.outputs = l.out_h * l.out_w * l.out_c;
    l.inputs = l.w * l.h * l.c;

    l.weights = calloc(c*n*size*size*locations, sizeof(float));
    l.weight_updates = calloc(c*n*size*size*locations, sizeof(float));

    l.biases = calloc(l.outputs, sizeof(float));
    l.bias_updates = calloc(l.outputs, sizeof(float));

    // float scale = 1./sqrt(size*size*c);
    float scale = sqrt(2./(size*size*c));
    for(i = 0; i < c*n*size*size; ++i) l.weights[i] = scale*rand_uniform(-1,1);

    l.output = calloc(l.batch*out_h * out_w * n, sizeof(float));
    l.delta  = calloc(l.batch*out_h * out_w * n, sizeof(float));

    l.workspace_size = out_h*out_w*size*size*c;
    
    l.forward = forward_local_layer;
    l.backward = backward_local_layer;
    l.update = update_local_layer;

    l.activation = activation;

    fprintf(stderr, "Local Layer: %d x %d x %d image, %d filters -> %d x %d x %d image\n", h,w,c,n, out_h, out_w, n);

    return l;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x38, %rsp
movl %r9d, %r13d
movl %r8d, 0x8(%rsp)
movl %ecx, 0x4(%rsp)
movl %edx, %r14d
movl %esi, %ebp
movq %rdi, %rbx
movl 0x80(%rsp), %r12d
xorl %r15d, %r15d
movl $0x4a0, %edx            # imm = 0x4A0
xorl %esi, %esi
callq 0x31c0
movl $0xc, (%rbx)
movl %r14d, 0x6c(%rbx)
movl 0x4(%rsp), %r8d
movl %r8d, 0x70(%rbx)
movl 0x8(%rsp), %esi
movl %esi, 0x74(%rbx)
movl %r13d, 0x84(%rbx)
movl %ebp, 0x10(%rsp)
movl %ebp, 0x48(%rbx)
movl 0x78(%rsp), %ecx
movl %ecx, 0x98(%rbx)
movl 0x70(%rsp), %edi
movl %edi, 0x90(%rbx)
movl %r12d, 0xa8(%rbx)
movl %edi, %eax
negl %eax
negl %r12d
sbbl %r15d, %r15d
orl %eax, %r15d
leal (%r15,%r14), %eax
cltd
idivl %ecx
movl %ecx, %r9d
movl %eax, %ecx
incl %ecx
addl %r8d, %r15d
movl %r15d, %eax
cltd
idivl %r9d
incl %eax
movl %eax, %edx
imull %ecx, %edx
movq %rcx, 0x20(%rsp)
movl %ecx, 0x78(%rbx)
movq %rax, 0x18(%rsp)
movl %eax, 0x7c(%rbx)
movl %r13d, 0x80(%rbx)
movl %edx, %r15d
imull %r13d, %r15d
movl %r15d, 0x58(%rbx)
movl %r8d, %eax
movq %r14, 0x28(%rsp)
imull %r14d, %eax
imull %esi, %eax
movl %eax, 0x54(%rbx)
movl %edi, %ebp
imull %esi, %ebp
imull %edi, %ebp
movl %ebp, %r14d
movq %r13, 0x30(%rsp)
imull %r13d, %r14d
movl %edx, 0xc(%rsp)
movl %edx, %eax
imull %r14d, %eax
movslq %eax, %r13
pushq $0x4
popq %rsi
movq %r13, %rdi
callq 0x3250
movq %rax, %r12
movq %rax, 0x250(%rbx)
movq %r13, %rdi
pushq $0x4
popq %rsi
callq 0x3250
movq %rax, 0x258(%rbx)
movslq %r15d, %r13
movq %r13, %rdi
pushq $0x4
popq %rsi
movq %rsi, %r15
callq 0x3250
movq %rax, 0x230(%rbx)
movq %r13, %rdi
movq %r15, %rsi
callq 0x3250
movq %rax, 0x238(%rbx)
cvtsi2sd %ebp, %xmm1
movsd 0x4dcdb(%rip), %xmm0    # 0x551d8
divsd %xmm1, %xmm0
xorpd %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jb 0x7511
sqrtsd %xmm0, %xmm0
jmp 0x7516
callq 0x3460
testl %r14d, %r14d
jle 0x7554
cvtsd2ss %xmm0, %xmm0
movss %xmm0, 0x14(%rsp)
movl %r14d, %r14d
xorl %r15d, %r15d
movss 0x4dd61(%rip), %xmm0    # 0x55294
movss 0x4dacd(%rip), %xmm1    # 0x55008
callq 0xfa10
mulss 0x14(%rsp), %xmm0
movss %xmm0, (%r12,%r15,4)
incq %r15
cmpq %r15, %r14
jne 0x752b
movl 0x10(%rsp), %eax
movl 0xc(%rsp), %r13d
imull %r13d, %eax
movq 0x30(%rsp), %r14
imull %r14d, %eax
movslq %eax, %r15
pushq $0x4
popq %r12
movq %r15, %rdi
movq %r12, %rsi
callq 0x3250
movq %rax, 0x268(%rbx)
movq %r15, %rdi
movq %r12, %rsi
callq 0x3250
movq %rax, 0x260(%rbx)
imull %r13d, %ebp
movslq %ebp, %rax
movq %rax, 0x498(%rbx)
leaq 0x32a44(%rip), %rax     # 0x39fee
movq %rax, 0x10(%rbx)
leaq 0x32ccc(%rip), %rax     # 0x3a281
movq %rax, 0x18(%rbx)
leaq 0x33083(%rip), %rax     # 0x3a643
movq %rax, 0x20(%rbx)
movl 0x88(%rsp), %eax
movl %eax, 0x4(%rbx)
movq 0x64a23(%rip), %rax     # 0x6bff8
movq (%rax), %rdi
subq $0x8, %rsp
leaq 0x525a7(%rip), %rsi     # 0x59b8a
movq 0x30(%rsp), %rdx
movl 0xc(%rsp), %ecx
movl 0x10(%rsp), %r8d
movl %r14d, %r9d
xorl %eax, %eax
pushq %r14
pushq 0x28(%rsp)
pushq 0x38(%rsp)
callq 0x3270
addq $0x20, %rsp
movq %rbx, %rax
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq