// File: /workspace/github_c_makefile_star2_O1/SimpleDoger[P]Darknet_CPU_Only/detector.c
// Function: train_detector
void train_detector(char *datacfg, char *cfgfile, char *weightfile, int *gpus, int ngpus, int clear)
{
    list *options = read_data_cfg(datacfg);
    char *train_images = option_find_str(options, "train", "data/train.list");
    char *backup_directory = option_find_str(options, "backup", "/backup/");

    srand(time(0));
    char *base = basecfg(cfgfile);
    printf("%s\n", base);
    float avg_loss = -1;
    network **nets = calloc(ngpus, sizeof(network));

    srand(time(0));
    int seed = rand();
    int i;
    for(i = 0; i < ngpus; ++i){
        srand(seed);
        nets[i] = load_network(cfgfile, weightfile, clear);
        nets[i]->learning_rate *= ngpus;
    }
    srand(time(0));
    network *net = nets[0];

    int imgs = net->batch * net->subdivisions * ngpus;
    printf("Learning Rate: %g, Momentum: %g, Decay: %g\n", net->learning_rate, net->momentum, net->decay);
    data train, buffer;

    layer l = net->layers[net->n - 1];

    int classes = l.classes;
    float jitter = l.jitter;

    list *plist = get_paths(train_images);
    //int N = plist->size;
    char **paths = (char **)list_to_array(plist);

    load_args args = get_base_args(net);
    args.coords = l.coords;
    args.paths = paths;
    args.n = imgs;
    args.m = plist->size;
    args.classes = classes;
    args.jitter = jitter;
    args.num_boxes = l.max_boxes;
    args.d = &buffer;
    args.type = DETECTION_DATA;
    //args.type = INSTANCE_DATA;
    args.threads = 64;

    pthread_t load_thread = load_data(args);
    double time;
    int count = 0;
    //while(i*imgs < N*120){
    while(get_current_batch(net) < net->max_batches){
        if(l.random && count++%10 == 0){
            printf("Resizing\n");
            int dim = (rand() % 10 + 10) * 32;
            if (get_current_batch(net)+200 > net->max_batches) dim = 608;
            //int dim = (rand() % 4 + 16) * 32;
            printf("%d\n", dim);
            args.w = dim;
            args.h = dim;

            pthread_join(load_thread, 0);
            train = buffer;
            free_data(train);
            load_thread = load_data(args);

            #pragma omp parallel for
            for(i = 0; i < ngpus; ++i){
                resize_network(nets[i], dim, dim);
            }
            net = nets[0];
        }
        time=what_time_is_it_now();
        pthread_join(load_thread, 0);
        train = buffer;
        load_thread = load_data(args);

        /*
           int k;
           for(k = 0; k < l.max_boxes; ++k){
           box b = float_to_box(train.y.vals[10] + 1 + k*5);
           if(!b.x) break;
           printf("loaded: %f %f %f %f\n", b.x, b.y, b.w, b.h);
           }
         */
        /*
           int zz;
           for(zz = 0; zz < train.X.cols; ++zz){
           image im = float_to_image(net->w, net->h, 3, train.X.vals[zz]);
           int k;
           for(k = 0; k < l.max_boxes; ++k){
           box b = float_to_box(train.y.vals[zz] + k*5, 1);
           printf("%f %f %f %f\n", b.x, b.y, b.w, b.h);
           draw_bbox(im, b, 1, 1,0,0);
           }
           show_image(im, "truth11");
           cvWaitKey(0);
           save_image(im, "truth11");
           }
         */

        printf("Loaded: %lf seconds\n", what_time_is_it_now()-time);

        time=what_time_is_it_now();
        float loss = 0;
        loss = train_network(net, train);
        if (avg_loss < 0) avg_loss = loss;
        avg_loss = avg_loss*.9 + loss*.1;

        i = get_current_batch(net);
        printf("%ld: %f, %f avg, %f rate, %lf seconds, %d images\n", get_current_batch(net), loss, avg_loss, get_current_rate(net), what_time_is_it_now()-time, i*imgs);
        if(i%100==0){
            char buff[256];
            sprintf(buff, "%s/%s.backup", backup_directory, base);
            save_weights(net, buff);
        }
        if(i%10000==0 || (i < 1000 && i%100 == 0)){
            char buff[256];
            sprintf(buff, "%s/%s_%d.weights", backup_directory, base, i);
            save_weights(net, buff);
        }
        free_data(train);
    }
    char buff[256];
    sprintf(buff, "%s/%s_final.weights", backup_directory, base);
    save_weights(net, buff);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x348, %rsp            # imm = 0x348
movl %r9d, 0xd0(%rsp)
movl %r8d, %ebp
movq %rdx, %r13
movq %rsi, %rbx
callq 0x34b9c
movq %rax, %r14
leaq 0xadaf(%rip), %rsi      # 0x582dc
leaq 0xb5ec(%rip), %rdx      # 0x58b20
movq %rax, %rdi
callq 0x34d5b
movq %rax, 0xc0(%rsp)
leaq 0xae0a(%rip), %rsi      # 0x58355
leaq 0xab49(%rip), %rdx      # 0x5809b
movq %r14, %rdi
callq 0x34d5b
movq %rax, 0xf0(%rsp)
xorl %edi, %edi
callq 0x32d0
movl %eax, %edi
callq 0x3230
movq %rbx, %rdi
callq 0xe717
movq %rax, 0xe8(%rsp)
movq %rax, %rdi
callq 0x30c0
movslq %ebp, %r15
movl $0x110, %esi            # imm = 0x110
movq %r15, %rdi
callq 0x3260
movq %rax, %r12
xorl %edi, %edi
callq 0x32d0
movl %eax, %edi
callq 0x3230
callq 0x34f0
movl %ebp, 0xbc(%rsp)
movl %ebp, %ebp
testl %r15d, %r15d
jle 0x4d60d
movl %eax, %r14d
cvtsi2ssl 0xbc(%rsp), %xmm0
movss %xmm0, 0xb0(%rsp)
xorl %r15d, %r15d
movl %r14d, %edi
callq 0x3230
movq %rbx, %rdi
movq %r13, %rsi
movl 0xd0(%rsp), %edx
callq 0x2f9e4
movq %rax, (%r12,%r15,8)
movss 0x34(%rax), %xmm0
mulss 0xb0(%rsp), %xmm0
movss %xmm0, 0x34(%rax)
incq %r15
cmpq %r15, %rbp
jne 0x4d5d4
xorl %edi, %edi
callq 0x32d0
movl %eax, %edi
callq 0x3230
movq (%r12), %r13
movl 0x4(%r13), %r14d
imull 0xbc(%rsp), %r14d
imull 0x1c(%r13), %r14d
xorps %xmm0, %xmm0
cvtss2sd 0x34(%r13), %xmm0
cvtss2sd 0x38(%r13), %xmm1
cvtss2sd 0x3c(%r13), %xmm2
leaq 0xa84b(%rip), %rdi      # 0x57e98
movb $0x3, %al
callq 0x3170
movq 0x20(%r13), %rax
movslq (%r13), %rcx
imulq $0x4a0, %rcx, %rcx      # imm = 0x4A0
movl -0x418(%rax,%rcx), %edx
movl %edx, 0xd0(%rsp)
movss -0x3c8(%rax,%rcx), %xmm0
movss %xmm0, 0xb0(%rsp)
movl -0x3a4(%rax,%rcx), %edx
movl %edx, 0x100(%rsp)
movl -0x3a0(%rax,%rcx), %edx
movl %edx, 0xf8(%rsp)
movl -0x348(%rax,%rcx), %eax
movl %eax, 0x108(%rsp)
movq 0xc0(%rsp), %rdi
callq 0x296f8
movq %rax, %rbx
movq %rax, %rdi
callq 0x10fa0
movq %rax, 0xc0(%rsp)
leaq 0x198(%rsp), %r15
movq %r15, %rdi
movq %r13, %rsi
callq 0x2f948
movl 0xf8(%rsp), %eax
movl %eax, 0x60(%r15)
movq 0xc0(%rsp), %rax
movq %rax, 0x8(%r15)
movl %r14d, 0x10c(%rsp)
movl %r14d, 0x18(%r15)
movl (%rbx), %eax
movl %eax, 0x1c(%r15)
movl 0x100(%rsp), %eax
movl %eax, 0x50(%r15)
movss 0xb0(%rsp), %xmm0
movss %xmm0, 0x64(%r15)
movl 0xd0(%rsp), %eax
movl %eax, 0x40(%r15)
leaq 0x158(%rsp), %rax
movq %rax, 0x80(%r15)
movl $0x1, 0x98(%r15)
movl $0x40, (%r15)
movl $0x15, %ecx
movq %rsp, %rdi
movq %r15, %rsi
rep  movsq (%rsi), %es:(%rdi)
callq 0x2e089
movq %rax, %rbx
movq %r13, %rdi
callq 0x2fa22
movslq 0x54(%r13), %rcx
cmpq %rcx, %rax
jae 0x4dbf3
leaq 0x54(%r13), %r15
movss 0x5ae2(%rip), %xmm0     # 0x53268
movaps %xmm0, 0xd0(%rsp)
movl $0x0, 0xcc(%rsp)
movq %r12, 0x150(%rsp)
cmpl $0x0, 0x108(%rsp)
je 0x4d914
movl 0xcc(%rsp), %ecx
imull $0xcccccccd, %ecx, %eax # imm = 0xCCCCCCCD
incl %ecx
movl %ecx, 0xcc(%rsp)
movl $0x19999998, %ecx       # imm = 0x19999998
addl %ecx, %eax
rorl %eax
cmpl %ecx, %eax
ja 0x4d914
leaq 0xb4af(%rip), %rdi      # 0x58c8c
callq 0x30c0
callq 0x34f0
movslq %eax, %r14
imulq $0x66666667, %r14, %rax # imm = 0x66666667
movq %rax, %rcx
shrq $0x3f, %rcx
sarq $0x22, %rax
addl %ecx, %eax
addl %eax, %eax
leal (%rax,%rax,4), %eax
subl %eax, %r14d
shll $0x5, %r14d
addl $0x140, %r14d           # imm = 0x140
movq %r13, %rdi
callq 0x2fa22
addq $0xc8, %rax
movslq (%r15), %rcx
cmpq %rcx, %rax
movl $0x260, %eax            # imm = 0x260
cmoval %eax, %r14d
leaq 0xac0c(%rip), %rdi      # 0x58441
movl %r14d, %esi
xorl %eax, %eax
callq 0x3170
movl %r14d, 0x1c4(%rsp)
movl %r14d, 0x1c0(%rsp)
movq %rbx, %rdi
xorl %esi, %esi
callq 0x3480
movups 0x158(%rsp), %xmm0
movups 0x168(%rsp), %xmm1
movups 0x178(%rsp), %xmm2
movups 0x188(%rsp), %xmm3
movaps %xmm0, 0x110(%rsp)
movaps %xmm1, 0x120(%rsp)
movaps %xmm2, 0x130(%rsp)
movaps %xmm3, 0x140(%rsp)
movups 0x158(%rsp), %xmm0
movups 0x168(%rsp), %xmm1
movups 0x178(%rsp), %xmm2
movups 0x188(%rsp), %xmm3
movups %xmm3, 0x30(%rsp)
movups %xmm2, 0x20(%rsp)
movups %xmm1, 0x10(%rsp)
movups %xmm0, (%rsp)
callq 0x2b6fd
movl $0x15, %ecx
movq %rsp, %rdi
leaq 0x198(%rsp), %rsi
rep  movsq (%rsi), %es:(%rdi)
callq 0x2e089
movq %rax, %rbx
cmpl $0x0, 0xbc(%rsp)
jle 0x4d910
xorl %r15d, %r15d
movq (%r12,%r15,8), %rdi
movl %r14d, %esi
movl %r14d, %edx
callq 0x302fd
incq %r15
cmpq %r15, %rbp
jne 0x4d8f9
movq (%r12), %r13
xorl %eax, %eax
callq 0xdfdc
movsd %xmm0, 0xb0(%rsp)
movq %rbx, %rdi
xorl %esi, %esi
callq 0x3480
movupd 0x158(%rsp), %xmm0
movups 0x168(%rsp), %xmm1
movups 0x178(%rsp), %xmm2
movups 0x188(%rsp), %xmm3
movapd %xmm0, 0x110(%rsp)
movaps %xmm1, 0x120(%rsp)
movaps %xmm2, 0x130(%rsp)
movaps %xmm3, 0x140(%rsp)
movl $0x15, %ecx
movq %rsp, %rdi
leaq 0x198(%rsp), %rsi
rep  movsq (%rsi), %es:(%rdi)
callq 0x2e089
movq %rax, %rbx
xorl %eax, %eax
callq 0xdfdc
subsd 0xb0(%rsp), %xmm0
leaq 0xa564(%rip), %rdi      # 0x57f06
movb $0x1, %al
callq 0x3170
xorl %eax, %eax
callq 0xdfdc
movsd %xmm0, 0xb0(%rsp)
movaps 0x110(%rsp), %xmm0
movaps 0x120(%rsp), %xmm1
movaps 0x130(%rsp), %xmm2
movaps 0x140(%rsp), %xmm3
movups %xmm3, 0x30(%rsp)
movups %xmm2, 0x20(%rsp)
movups %xmm1, 0x10(%rsp)
movups %xmm0, (%rsp)
movq %r13, %rdi
callq 0x301c6
movaps 0xd0(%rsp), %xmm3
movaps %xmm3, %xmm1
cmpltss 0x5670(%rip), %xmm1     # 0x53078
movaps %xmm1, %xmm2
andnps %xmm3, %xmm2
andps %xmm0, %xmm1
orps %xmm2, %xmm1
cvtss2sd %xmm1, %xmm1
cvtss2sd %xmm0, %xmm0
movsd %xmm0, 0xc0(%rsp)
mulsd 0x8b83(%rip), %xmm0     # 0x565b0
mulsd 0xa45b(%rip), %xmm1     # 0x57e90
addsd %xmm0, %xmm1
xorps %xmm0, %xmm0
cvtsd2ss %xmm1, %xmm0
movaps %xmm0, 0xd0(%rsp)
movq %r13, %rdi
callq 0x2fa22
movq %rax, %r14
movq %r13, %rdi
callq 0x2fa22
movq %rax, %r15
xorps %xmm0, %xmm0
cvtss2sd 0xd0(%rsp), %xmm0
movsd %xmm0, 0x100(%rsp)
movq %r13, %rdi
callq 0x2fa3d
cvtss2sd %xmm0, %xmm0
movsd %xmm0, 0xf8(%rsp)
xorl %eax, %eax
callq 0xdfdc
movaps %xmm0, %xmm3
subsd 0xb0(%rsp), %xmm3
movl 0x10c(%rsp), %edx
imull %r14d, %edx
leaq 0xb65f(%rip), %rdi      # 0x5910c
movq %r15, %rsi
movsd 0xc0(%rsp), %xmm0
movsd 0x100(%rsp), %xmm1
movsd 0xf8(%rsp), %xmm2
movb $0x4, %al
callq 0x3170
movslq %r14d, %r15
imulq $0x51eb851f, %r15, %rax # imm = 0x51EB851F
movq %rax, %rcx
shrq $0x3f, %rcx
sarq $0x25, %rax
addl %ecx, %eax
imull $0x64, %eax, %eax
subl %eax, %r15d
jne 0x4db39
movq %rbp, %r12
movq %rbx, %rbp
leaq 0x240(%rsp), %rbx
movq %rbx, %rdi
leaq 0xa5dd(%rip), %rsi      # 0x580e6
movq 0xf0(%rsp), %rdx
movq 0xe8(%rsp), %rcx
xorl %eax, %eax
callq 0x3430
movq %r13, %rdi
movq %rbx, %rsi
movq %rbp, %rbx
movq %r12, %rbp
movq 0x150(%rsp), %r12
callq 0x66cd
testl %r15d, %r15d
setne %al
imull $0x3afb7e91, %r14d, %edx # imm = 0x3AFB7E91
addl $0x346dc0, %edx         # imm = 0x346DC0
rorl $0x4, %edx
cmpl $0x3e8, %r14d           # imm = 0x3E8
setge %cl
cmpl $0x68db9, %edx          # imm = 0x68DB9
jb 0x4db65
orb %al, %cl
jne 0x4dba2
movq %rbx, %r15
leaq 0x240(%rsp), %rbx
movq %rbx, %rdi
leaq 0xa55b(%rip), %rsi      # 0x580d5
movq 0xf0(%rsp), %rdx
movq 0xe8(%rsp), %rcx
movl %r14d, %r8d
xorl %eax, %eax
callq 0x3430
movq %r13, %rdi
movq %rbx, %rsi
movq %r15, %rbx
callq 0x66cd
movaps 0x110(%rsp), %xmm0
movaps 0x120(%rsp), %xmm1
movaps 0x130(%rsp), %xmm2
movaps 0x140(%rsp), %xmm3
movups %xmm3, 0x30(%rsp)
movups %xmm2, 0x20(%rsp)
movups %xmm1, 0x10(%rsp)
movups %xmm0, (%rsp)
callq 0x2b6fd
movq %r13, %rdi
callq 0x2fa22
leaq 0x54(%r13), %r15
movslq 0x54(%r13), %rcx
cmpq %rcx, %rax
jb 0x4d7a1
leaq 0xa4f9(%rip), %rsi      # 0x580f3
leaq 0x240(%rsp), %rbx
movq %rbx, %rdi
movq 0xf0(%rsp), %rdx
movq 0xe8(%rsp), %rcx
xorl %eax, %eax
callq 0x3430
movq %r13, %rdi
movq %rbx, %rsi
callq 0x66cd
addq $0x348, %rsp            # imm = 0x348
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq