// File: cannam[P]mini-cpp-convnet/flower.cpp
// Function: main
int main(int argc, char **argv)
{
    if (argc != 2) {
        cerr << "Usage: " << argv[0] << " <filename.png>" << endl;
        return 2;
    }

    auto image = read_image(argv[1]);

    size_t expected_width = 128;
    size_t expected_height = 128;

    if (image.size() != expected_height ||
        image[0].size() != expected_width) {
        cerr << "Image has wrong size: must be exactly " << expected_width
             << "x" << expected_height << " pixels" << endl;
        throw runtime_error("Image has wrong size");
    }

    auto before = chrono::high_resolution_clock::now();
    
    auto result = classify(image);

    auto after = chrono::high_resolution_clock::now();

    chrono::duration<double> diff = after - before;
    
    cerr << "Classification took " << diff.count() << " sec" << endl;

    vector<string> labels {
        "daisy", "dandelion", "roses", "sunflowers", "tulips"
    };

    map<float, string> ranking;
    
    for (size_t i = 0; i < result.size(); ++i) {
        if (i >= labels.size()) {
            throw logic_error("Too many result categories!");
        }
        ranking[- result[i] * 100.0] = labels[i];
    }

    for (auto r = ranking.begin(); r != ranking.end(); ++r) {
        cout << r->second << ": " << -r->first << "%" << endl;
    }
    
    return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x320, %rsp            # imm = 0x320
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
cmpl $0x2, -0x8(%rbp)
je 0x49d9b
movq 0x9f292(%rip), %rdi     # 0xe8fe8
leaq 0x944a(%rip), %rsi      # 0x531a7
callq 0x3250
movq %rax, %rdi
movq -0x10(%rbp), %rax
movq (%rax), %rsi
callq 0x3250
movq %rax, %rdi
leaq 0x9434(%rip), %rsi      # 0x531af
callq 0x3250
movq %rax, %rdi
movq 0x9f216(%rip), %rsi     # 0xe8fa0
callq 0x3290
movl $0x2, -0x4(%rbp)
jmp 0x4a6d3
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x1e0(%rbp)
leaq -0x49(%rbp), %rdi
movq %rdi, -0x1d8(%rbp)
callq 0x33c0
movq -0x1e0(%rbp), %rsi
movq -0x1d8(%rbp), %rdx
leaq -0x48(%rbp), %rdi
callq 0x4b000
jmp 0x49dd3
leaq -0x28(%rbp), %rdi
leaq -0x48(%rbp), %rsi
callq 0x49730
jmp 0x49de2
leaq -0x48(%rbp), %rdi
callq 0x3180
leaq -0x49(%rbp), %rdi
callq 0x32b0
movq $0x80, -0x68(%rbp)
movq $0x80, -0x70(%rbp)
leaq -0x28(%rbp), %rdi
callq 0x4a740
cmpq -0x70(%rbp), %rax
jne 0x49e32
leaq -0x28(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x4ab20
movq %rax, %rdi
callq 0x4a7d0
cmpq -0x68(%rbp), %rax
je 0x49f70
movq 0x9f1af(%rip), %rdi     # 0xe8fe8
leaq 0x937f(%rip), %rsi      # 0x531bf
callq 0x3250
movq %rax, -0x1e8(%rbp)
jmp 0x49e4e
movq -0x1e8(%rbp), %rdi
movq -0x68(%rbp), %rsi
callq 0x3080
movq %rax, -0x1f0(%rbp)
jmp 0x49e67
movq -0x1f0(%rbp), %rdi
leaq 0x92f8(%rip), %rsi      # 0x5316d
callq 0x3250
movq %rax, -0x1f8(%rbp)
jmp 0x49e83
movq -0x1f8(%rbp), %rdi
movq -0x70(%rbp), %rsi
callq 0x3080
movq %rax, -0x200(%rbp)
jmp 0x49e9c
movq -0x200(%rbp), %rdi
leaq 0x933c(%rip), %rsi      # 0x531e6
callq 0x3250
movq %rax, -0x208(%rbp)
jmp 0x49eb8
movq -0x208(%rbp), %rdi
movq 0x9f0da(%rip), %rsi     # 0xe8fa0
callq 0x3290
jmp 0x49ecd
movl $0x10, %edi
callq 0x3120
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x210(%rbp)
leaq 0x9303(%rip), %rsi      # 0x531ee
callq 0x30d0
jmp 0x49ef2
movq -0x210(%rbp), %rdi
movq 0x9f0f0(%rip), %rsi     # 0xe8ff0
movq 0x9f0a9(%rip), %rdx     # 0xe8fb0
callq 0x3390
jmp 0x4a6e8
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
jmp 0x49f34
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
leaq -0x48(%rbp), %rdi
callq 0x3180
leaq -0x49(%rbp), %rdi
callq 0x32b0
jmp 0x4a6df
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
jmp 0x4a6c8
movq -0x210(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
callq 0x31d0
jmp 0x4a6c8
callq 0x3040
movq %rax, -0x78(%rbp)
leaq -0x90(%rbp), %rdi
leaq -0x28(%rbp), %rsi
callq 0x48e20
jmp 0x49f8b
callq 0x3040
movq %rax, -0x98(%rbp)
leaq -0x98(%rbp), %rdi
leaq -0x78(%rbp), %rsi
callq 0x4b380
movq %rax, -0x218(%rbp)
jmp 0x49fb0
movq -0x218(%rbp), %rax
movq %rax, -0xa8(%rbp)
leaq -0xa0(%rbp), %rdi
leaq -0xa8(%rbp), %rsi
callq 0x4b3d0
jmp 0x49fd3
movq 0x9f00e(%rip), %rdi     # 0xe8fe8
leaq 0x9222(%rip), %rsi      # 0x53203
callq 0x3250
movq %rax, -0x220(%rbp)
jmp 0x49fef
leaq -0xa0(%rbp), %rdi
callq 0x4b410
movsd %xmm0, -0x228(%rbp)
jmp 0x4a005
movsd -0x228(%rbp), %xmm0
movq -0x220(%rbp), %rdi
callq 0x33e0
movq %rax, -0x230(%rbp)
jmp 0x4a022
movq -0x230(%rbp), %rdi
leaq 0x91e8(%rip), %rsi      # 0x53218
callq 0x3250
movq %rax, -0x238(%rbp)
jmp 0x4a03e
movq -0x238(%rbp), %rdi
movq 0x9ef54(%rip), %rsi     # 0xe8fa0
callq 0x3290
jmp 0x4a053
movb $0x1, -0x17e(%rbp)
leaq -0x170(%rbp), %rax
movq %rax, -0x248(%rbp)
movq %rax, -0x178(%rbp)
leaq -0x179(%rbp), %rdi
movq %rdi, -0x240(%rbp)
callq 0x33c0
movq -0x248(%rbp), %rdi
movq -0x240(%rbp), %rdx
leaq 0x9186(%rip), %rsi      # 0x5321d
callq 0x4b000
jmp 0x4a09e
leaq -0x150(%rbp), %rax
movq %rax, -0x258(%rbp)
movq %rax, -0x178(%rbp)
leaq -0x17a(%rbp), %rdi
movq %rdi, -0x250(%rbp)
callq 0x33c0
movq -0x258(%rbp), %rdi
movq -0x250(%rbp), %rdx
leaq 0x9148(%rip), %rsi      # 0x53223
callq 0x4b000
jmp 0x4a0e2
leaq -0x130(%rbp), %rax
movq %rax, -0x268(%rbp)
movq %rax, -0x178(%rbp)
leaq -0x17b(%rbp), %rdi
movq %rdi, -0x260(%rbp)
callq 0x33c0
movq -0x268(%rbp), %rdi
movq -0x260(%rbp), %rdx
leaq 0x910e(%rip), %rsi      # 0x5322d
callq 0x4b000
jmp 0x4a126
leaq -0x110(%rbp), %rax
movq %rax, -0x278(%rbp)
movq %rax, -0x178(%rbp)
leaq -0x17c(%rbp), %rdi
movq %rdi, -0x270(%rbp)
callq 0x33c0
movq -0x278(%rbp), %rdi
movq -0x270(%rbp), %rdx
leaq 0x90d0(%rip), %rsi      # 0x53233
callq 0x4b000
jmp 0x4a16a
leaq -0xf0(%rbp), %rax
movq %rax, -0x288(%rbp)
movq %rax, -0x178(%rbp)
leaq -0x17d(%rbp), %rdi
movq %rdi, -0x280(%rbp)
callq 0x33c0
movq -0x288(%rbp), %rdi
movq -0x280(%rbp), %rdx
leaq 0x9097(%rip), %rsi      # 0x5323e
callq 0x4b000
jmp 0x4a1ae
movb $0x0, -0x17e(%rbp)
leaq -0x170(%rbp), %rax
movq %rax, -0xd0(%rbp)
movq $0x5, -0xc8(%rbp)
leaq -0x17f(%rbp), %rdi
movq %rdi, -0x290(%rbp)
callq 0x4b430
movq -0x290(%rbp), %rcx
movq -0xd0(%rbp), %rsi
movq -0xc8(%rbp), %rdx
leaq -0xc0(%rbp), %rdi
callq 0x4b450
jmp 0x4a204
leaq -0x17f(%rbp), %rdi
callq 0x4b4d0
leaq -0x170(%rbp), %rax
movq %rax, -0x2a0(%rbp)
addq $0xa0, %rax
movq %rax, -0x298(%rbp)
movq -0x298(%rbp), %rdi
addq $-0x20, %rdi
movq %rdi, -0x2a8(%rbp)
callq 0x3180
movq -0x2a0(%rbp), %rcx
movq -0x2a8(%rbp), %rax
cmpq %rcx, %rax
movq %rax, -0x298(%rbp)
jne 0x4a22b
leaq -0x17d(%rbp), %rdi
callq 0x32b0
leaq -0x17c(%rbp), %rdi
callq 0x32b0
leaq -0x17b(%rbp), %rdi
callq 0x32b0
leaq -0x17a(%rbp), %rdi
callq 0x32b0
leaq -0x179(%rbp), %rdi
callq 0x32b0
leaq -0x1b0(%rbp), %rdi
callq 0x4b4f0
movq $0x0, -0x1b8(%rbp)
movq -0x1b8(%rbp), %rax
movq %rax, -0x2b0(%rbp)
leaq -0x90(%rbp), %rdi
callq 0x4a7b0
movq %rax, %rcx
movq -0x2b0(%rbp), %rax
cmpq %rcx, %rax
jae 0x4a574
movq -0x1b8(%rbp), %rax
movq %rax, -0x2b8(%rbp)
leaq -0xc0(%rbp), %rdi
callq 0x4b510
movq %rax, %rcx
movq -0x2b8(%rbp), %rax
cmpq %rcx, %rax
jb 0x4a4dd
movl $0x10, %edi
callq 0x3120
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x2c0(%rbp)
leaq 0x8f1e(%rip), %rsi      # 0x53245
callq 0x3310
jmp 0x4a32e
movq -0x2c0(%rbp), %rdi
movq 0x9ec94(%rip), %rsi     # 0xe8fd0
movq 0x9ec75(%rip), %rdx     # 0xe8fb8
callq 0x3390
jmp 0x4a6e8
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
jmp 0x4a6bc
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
jmp 0x4a446
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
jmp 0x4a43a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
jmp 0x4a42e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
jmp 0x4a422
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
jmp 0x4a416
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
leaq -0x17f(%rbp), %rdi
callq 0x4b4d0
leaq -0x170(%rbp), %rax
movq %rax, -0x2d0(%rbp)
addq $0xa0, %rax
movq %rax, -0x2c8(%rbp)
movq -0x2c8(%rbp), %rdi
addq $-0x20, %rdi
movq %rdi, -0x2d8(%rbp)
callq 0x3180
movq -0x2d0(%rbp), %rcx
movq -0x2d8(%rbp), %rax
cmpq %rcx, %rax
movq %rax, -0x2c8(%rbp)
jne 0x4a3e3
jmp 0x4a416
leaq -0x17d(%rbp), %rdi
callq 0x32b0
leaq -0x17c(%rbp), %rdi
callq 0x32b0
leaq -0x17b(%rbp), %rdi
callq 0x32b0
leaq -0x17a(%rbp), %rdi
callq 0x32b0
leaq -0x179(%rbp), %rdi
callq 0x32b0
testb $0x1, -0x17e(%rbp)
jne 0x4a45d
jmp 0x4a4aa
movq -0x178(%rbp), %rax
leaq -0x170(%rbp), %rcx
cmpq %rax, %rcx
movq %rax, -0x2e0(%rbp)
je 0x4a4a8
movq -0x2e0(%rbp), %rdi
addq $-0x20, %rdi
movq %rdi, -0x2e8(%rbp)
callq 0x3180
movq -0x2e8(%rbp), %rax
leaq -0x170(%rbp), %rcx
cmpq %rcx, %rax
movq %rax, -0x2e0(%rbp)
jne 0x4a477
jmp 0x4a4aa
jmp 0x4a6bc
movq -0x2c0(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
callq 0x31d0
jmp 0x4a6a4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
jmp 0x4a6a4
movq -0x1b8(%rbp), %rsi
leaq -0xc0(%rbp), %rdi
callq 0x4b530
movq %rax, -0x2f8(%rbp)
movq -0x1b8(%rbp), %rsi
leaq -0x90(%rbp), %rdi
callq 0x4ab60
movss (%rax), %xmm0
cvtss2sd %xmm0, %xmm0
movsd 0x8b06(%rip), %xmm1     # 0x53020
mulsd %xmm1, %xmm0
cvtsd2ss %xmm0, %xmm0
movss %xmm0, -0x1bc(%rbp)
leaq -0x1b0(%rbp), %rdi
leaq -0x1bc(%rbp), %rsi
callq 0x4b550
movq %rax, -0x2f0(%rbp)
jmp 0x4a546
movq -0x2f8(%rbp), %rsi
movq -0x2f0(%rbp), %rdi
callq 0x3030
jmp 0x4a55b
jmp 0x4a55d
movq -0x1b8(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x1b8(%rbp)
jmp 0x4a2af
leaq -0x1b0(%rbp), %rdi
callq 0x4b630
movq %rax, -0x1c8(%rbp)
leaq -0x1b0(%rbp), %rdi
callq 0x4b690
movq %rax, -0x1d0(%rbp)
leaq -0x1c8(%rbp), %rdi
leaq -0x1d0(%rbp), %rsi
callq 0x4b660
testb $0x1, %al
jne 0x4a5b6
jmp 0x4a66e
leaq -0x1c8(%rbp), %rdi
callq 0x4b6c0
movq %rax, %rsi
addq $0x8, %rsi
movq 0x9e9f0(%rip), %rdi     # 0xe8fc0
callq 0x3240
movq %rax, -0x300(%rbp)
jmp 0x4a5de
movq -0x300(%rbp), %rdi
leaq 0x8bc0(%rip), %rsi      # 0x531ac
callq 0x3250
movq %rax, -0x308(%rbp)
jmp 0x4a5fa
leaq -0x1c8(%rbp), %rdi
callq 0x4b6c0
movq -0x308(%rbp), %rdi
movss (%rax), %xmm0
movaps 0x89f8(%rip), %xmm1     # 0x53010
pxor %xmm1, %xmm0
callq 0x31e0
movq %rax, -0x310(%rbp)
jmp 0x4a62a
movq -0x310(%rbp), %rdi
leaq 0x8c29(%rip), %rsi      # 0x53261
callq 0x3250
movq %rax, -0x318(%rbp)
jmp 0x4a646
movq -0x318(%rbp), %rdi
movq 0x9e94c(%rip), %rsi     # 0xe8fa0
callq 0x3290
jmp 0x4a65b
jmp 0x4a65d
leaq -0x1c8(%rbp), %rdi
callq 0x4b6e0
jmp 0x4a587
movl $0x0, -0x4(%rbp)
leaq -0x1b0(%rbp), %rdi
callq 0x4b710
leaq -0xc0(%rbp), %rdi
callq 0x4b730
leaq -0x90(%rbp), %rdi
callq 0x4aa80
leaq -0x28(%rbp), %rdi
callq 0x4ab80
jmp 0x4a6d3
leaq -0x1b0(%rbp), %rdi
callq 0x4b710
leaq -0xc0(%rbp), %rdi
callq 0x4b730
leaq -0x90(%rbp), %rdi
callq 0x4aa80
leaq -0x28(%rbp), %rdi
callq 0x4ab80
jmp 0x4a6df
movl -0x4(%rbp), %eax
addq $0x320, %rsp            # imm = 0x320
popq %rbp
retq
movq -0x58(%rbp), %rdi
callq 0x33b0
nopl (%rax,%rax)