// File: /workspace/github_c_makefile_star2_O2/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, 0xc0(%rsp)
movl %r8d, %r15d
movl %r8d, 0xac(%rsp)
movq %rdx, %r14
movq %rsi, %r13
callq 0x29598
movq %rax, %rbx
leaq 0xbadb(%rip), %rsi      # 0x51314
leaq 0xc2f0(%rip), %rdx      # 0x51b30
movq %rax, %rdi
callq 0x29737
movq %rax, 0xb8(%rsp)
leaq 0xbb0e(%rip), %rsi      # 0x51365
leaq 0xb875(%rip), %rdx      # 0x510d3
movq %rbx, %rdi
callq 0x29737
movq %rax, 0xd8(%rsp)
xorl %ebp, %ebp
xorl %edi, %edi
callq 0x32c0
movl %eax, %edi
callq 0x3220
movq %r13, %rdi
callq 0x41c8
movq %rax, 0xd0(%rsp)
movq %rax, %rdi
callq 0x30b0
movslq %r15d, %r15
movl $0x110, %esi            # imm = 0x110
movq %r15, %rdi
callq 0x3250
movq %rax, %r12
xorl %edi, %edi
callq 0x32c0
movl %eax, %edi
callq 0x3220
callq 0x34e0
movl %eax, %ebx
cvtsi2ss %r15d, %xmm0
movss %xmm0, 0xb0(%rsp)
testl %r15d, %r15d
movl $0x0, %r15d
cmovgl 0xac(%rsp), %r15d
cmpq %rbp, %r15
je 0x45918
movl %ebx, %edi
callq 0x3220
movq %r13, %rdi
movq %r14, %rsi
movl 0xc0(%rsp), %edx
callq 0x22658
movq %rax, (%r12,%rbp,8)
movss 0x34(%rax), %xmm0
mulss 0xb0(%rsp), %xmm0
movss %xmm0, 0x34(%rax)
incq %rbp
jmp 0x458de
xorl %edi, %edi
callq 0x32c0
movl %eax, %edi
callq 0x3220
movq (%r12), %rbp
movl 0xac(%rsp), %r13d
imull 0x4(%rbp), %r13d
imull 0x1c(%rbp), %r13d
cvtss2sd 0x34(%rbp), %xmm0
cvtss2sd 0x38(%rbp), %xmm1
cvtss2sd 0x3c(%rbp), %xmm2
leaq 0xb57e(%rip), %rdi      # 0x50ed0
movb $0x3, %al
callq 0x3160
movq 0x20(%rbp), %rax
movslq (%rbp), %rcx
imulq $0x4a0, %rcx, %rcx      # imm = 0x4A0
movl -0x418(%rax,%rcx), %edx
movl %edx, 0xc0(%rsp)
movss -0x3c8(%rax,%rcx), %xmm0
movss %xmm0, 0xb0(%rsp)
movl -0x3a4(%rax,%rcx), %edx
movl %edx, 0xf0(%rsp)
movl -0x3a0(%rax,%rcx), %edx
movl %edx, 0xe8(%rsp)
movl -0x348(%rax,%rcx), %eax
movl %eax, 0xfc(%rsp)
movq 0xb8(%rsp), %rdi
callq 0x1c8c8
movq %rax, %rbx
movq %rax, %rdi
callq 0x72f5
movq %rax, 0xb8(%rsp)
leaq 0x198(%rsp), %r14
movq %r14, %rdi
movq %rbp, %rsi
callq 0x225e4
movl 0xe8(%rsp), %eax
movl %eax, 0x60(%r14)
movq 0xb8(%rsp), %rax
movq %rax, 0x8(%r14)
movl %r13d, 0xac(%rsp)
movl %r13d, 0x18(%r14)
movl (%rbx), %eax
movl %eax, 0x1c(%r14)
movl 0xf0(%rsp), %eax
movl %eax, 0x50(%r14)
movss 0xb0(%rsp), %xmm0
movss %xmm0, 0x64(%r14)
movl 0xc0(%rsp), %eax
movl %eax, 0x40(%r14)
leaq 0x158(%rsp), %rax
movq %rax, 0x80(%r14)
movl $0x1, 0x98(%r14)
movl $0x40, (%r14)
pushq $0x15
popq %rcx
movq %rsp, %rdi
movq %r14, %rsi
rep  movsq (%rsi), %es:(%rdi)
movss 0x67fc(%rip), %xmm0     # 0x4c264
movaps %xmm0, 0xc0(%rsp)
callq 0x20e7b
movq %rax, 0xb0(%rsp)
pushq $0xa
popq %r13
movq $0x0, 0xe0(%rsp)
movq %r15, 0x148(%rsp)
movq %rbp, %rdi
callq 0x22693
movslq 0x54(%rbp), %rcx
cmpq %rcx, %rax
jae 0x45ea3
cmpl $0x0, 0xfc(%rsp)
je 0x45bf8
movq 0xe0(%rsp), %rax
leal 0x1(%rax), %r14d
cltd
idivl %r13d
testl %edx, %edx
jne 0x45bed
leaq 0xc1e6(%rip), %rdi      # 0x51cbd
callq 0x30b0
callq 0x34e0
cltd
idivl %r13d
movl %edx, %ebx
shll $0x5, %ebx
addl $0x140, %ebx            # imm = 0x140
movq %rbp, %rdi
callq 0x22693
addq $0xc8, %rax
movslq 0x54(%rbp), %rcx
cmpq %rcx, %rax
movl $0x260, %eax            # imm = 0x260
cmoval %eax, %ebx
leaq 0xb93d(%rip), %rdi      # 0x51451
movl %ebx, %esi
xorl %eax, %eax
callq 0x3160
movl %ebx, 0x1c4(%rsp)
movl %ebx, 0x1c0(%rsp)
movq 0xb0(%rsp), %rdi
xorl %esi, %esi
callq 0x3470
movups 0x158(%rsp), %xmm0
movups 0x168(%rsp), %xmm1
movups 0x178(%rsp), %xmm2
movups 0x188(%rsp), %xmm3
movaps %xmm0, 0x100(%rsp)
movaps %xmm1, 0x110(%rsp)
movaps %xmm2, 0x120(%rsp)
movaps %xmm3, 0x130(%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 0x1e69d
pushq $0x15
popq %rcx
movq %rsp, %rdi
leaq 0x198(%rsp), %rsi
rep  movsq (%rsi), %es:(%rdi)
callq 0x20e7b
movq %rax, 0xb0(%rsp)
xorl %ebp, %ebp
cmpq %rbp, %r15
je 0x45be9
movq (%r12,%rbp,8), %rdi
movl %ebx, %esi
movl %ebx, %edx
callq 0x22f25
incq %rbp
jmp 0x45bd2
movq (%r12), %rbp
movl %r14d, %eax
movq %rax, 0xe0(%rsp)
xorl %eax, %eax
callq 0x3bc0
movsd %xmm0, 0xb8(%rsp)
movq 0xb0(%rsp), %rdi
xorl %esi, %esi
callq 0x3470
movupd 0x158(%rsp), %xmm0
movups 0x168(%rsp), %xmm1
movups 0x178(%rsp), %xmm2
movups 0x188(%rsp), %xmm3
movapd %xmm0, 0x100(%rsp)
movaps %xmm1, 0x110(%rsp)
movaps %xmm2, 0x120(%rsp)
movaps %xmm3, 0x130(%rsp)
pushq $0x15
popq %rcx
movq %rsp, %rdi
leaq 0x198(%rsp), %rsi
rep  movsq (%rsi), %es:(%rdi)
callq 0x20e7b
movq %rax, 0xb0(%rsp)
xorl %eax, %eax
callq 0x3bc0
subsd 0xb8(%rsp), %xmm0
leaq 0xb2b0(%rip), %rdi      # 0x50f3e
movb $0x1, %al
callq 0x3160
xorl %eax, %eax
callq 0x3bc0
movsd %xmm0, 0xb8(%rsp)
movaps 0x100(%rsp), %xmm0
movaps 0x110(%rsp), %xmm1
movaps 0x120(%rsp), %xmm2
movaps 0x130(%rsp), %xmm3
movups %xmm3, 0x30(%rsp)
movups %xmm2, 0x20(%rsp)
movups %xmm1, 0x10(%rsp)
movups %xmm0, (%rsp)
movq %rbp, %rdi
callq 0x22df8
movaps 0xc0(%rsp), %xmm3
movaps %xmm3, %xmm1
cmpltss 0x6384(%rip), %xmm1     # 0x4c078
movaps %xmm1, %xmm2
andnps %xmm3, %xmm2
andps %xmm0, %xmm1
orps %xmm2, %xmm1
cvtss2sd %xmm1, %xmm1
cvtss2sd %xmm0, %xmm0
movsd %xmm0, 0xf0(%rsp)
mulsd 0x98b7(%rip), %xmm0     # 0x4f5d0
mulsd 0xb1a7(%rip), %xmm1     # 0x50ec8
addsd %xmm0, %xmm1
cvtsd2ss %xmm1, %xmm0
movaps %xmm0, 0xc0(%rsp)
movq %rbp, %rdi
callq 0x22693
movq %rax, %rbx
movq %rbp, %rdi
callq 0x22693
movq %rax, %r14
cvtss2sd 0xc0(%rsp), %xmm0
movsd %xmm0, 0xe8(%rsp)
movq %rbp, %rdi
callq 0x226ae
cvtss2sd %xmm0, %xmm0
movsd %xmm0, 0x150(%rsp)
xorl %eax, %eax
callq 0x3bc0
movaps %xmm0, %xmm3
subsd 0xb8(%rsp), %xmm3
movl 0xac(%rsp), %edx
imull %ebx, %edx
leaq 0xc392(%rip), %rdi      # 0x52124
movq %r14, %rsi
movsd 0xf0(%rsp), %xmm0
movsd 0xe8(%rsp), %xmm1
movsd 0x150(%rsp), %xmm2
movb $0x4, %al
callq 0x3160
movl %ebx, %eax
cltd
pushq $0x64
popq %rcx
idivl %ecx
movl %edx, %r14d
testl %edx, %edx
jne 0x45e0e
movq %r12, %r15
movl %r13d, %r12d
leaq 0x240(%rsp), %r13
movq %r13, %rdi
leaq 0xb340(%rip), %rsi      # 0x5111e
movq 0xd8(%rsp), %rdx
movq 0xd0(%rsp), %rcx
xorl %eax, %eax
callq 0x3420
movq %rbp, %rdi
movq %r13, %rsi
movl %r12d, %r13d
movq %r15, %r12
movq 0x148(%rsp), %r15
callq 0x28aed
testl %r14d, %r14d
setne %cl
movl %ebx, %eax
cltd
movl $0x2710, %esi           # imm = 0x2710
idivl %esi
cmpl $0x3e8, %ebx            # imm = 0x3E8
setge %al
testl %edx, %edx
je 0x45e2f
orb %cl, %al
jne 0x45e66
leaq 0x240(%rsp), %r14
movq %r14, %rdi
leaq 0xb2cc(%rip), %rsi      # 0x5110d
movq 0xd8(%rsp), %rdx
movq 0xd0(%rsp), %rcx
movl %ebx, %r8d
xorl %eax, %eax
callq 0x3420
movq %rbp, %rdi
movq %r14, %rsi
callq 0x28aed
movaps 0x100(%rsp), %xmm0
movaps 0x110(%rsp), %xmm1
movaps 0x120(%rsp), %xmm2
movaps 0x130(%rsp), %xmm3
movups %xmm3, 0x30(%rsp)
movups %xmm2, 0x20(%rsp)
movups %xmm1, 0x10(%rsp)
movups %xmm0, (%rsp)
callq 0x1e69d
jmp 0x45a95
leaq 0xb281(%rip), %rsi      # 0x5112b
leaq 0x240(%rsp), %rbx
movq %rbx, %rdi
movq 0xd8(%rsp), %rdx
movq 0xd0(%rsp), %rcx
xorl %eax, %eax
callq 0x3420
movq %rbp, %rdi
movq %rbx, %rsi
callq 0x28aed
addq $0x348, %rsp            # imm = 0x348
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq