// File: /workspace/github_cpp_makefile_star2_O1/cannam[P]mini-cpp-convnet/flower.cpp
// Function: maxPool(std::vector<std::vector<std::vector<float, std::allocator<float>>, std::allocator<std::vector<float, std::allocator<float>>>>, std::allocator<std::vector<std::vector<float, std::allocator<float>>, std::allocator<std::vector<float, std::allocator<float>>>>>> const&, unsigned long, unsigned long)
vector<vector<vector<float>>>
maxPool(const vector<vector<vector<float>>> &in,
        size_t pool_y,
        size_t pool_x)
{
    size_t out_height = in.size() / pool_y;
    if (out_height < 1) {
        throw runtime_error("Input too small in maxPool");
    }

    size_t out_width = in[0].size() / pool_x;
    if (out_width < 1) {
        throw runtime_error("Input too small in maxPool");
    }
    
    size_t depth = in[0][0].size();
    
#ifdef VERBOSE
    cerr << "maxPool: input size " << in[0].size() << "x" << in.size()
         << "; pool size " << pool_x << "x" << pool_y << "; output size "
         << out_width << "x" << out_height << " and depth " << depth << endl;
#endif
    
    auto out =
        vector<vector<vector<float>>>
        (out_height,
         vector<vector<float>>
         (out_width,
          vector<float>
          (depth,
           -INFINITY)));

    for (size_t y = 0; y < out_height; ++y) {
        for (size_t x = 0; x < out_width; ++x) {
            for (size_t i = 0; i < pool_y; ++i) {
                for (size_t j = 0; j < pool_x; ++j) {
                    for (size_t c = 0; c < depth; ++c) {
                        float value = in[y * pool_y + i][x * pool_x + j][c];
                        out[y][x][c] = max(out[y][x][c], value);
                    }
                }
            }
        }
    }

    return out;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x88, %rsp
movq %rcx, %r14
movq %rdx, %r8
movq %rdi, 0x18(%rsp)
movq (%rsi), %rcx
movq %rsi, 0x48(%rsp)
movq 0x8(%rsi), %r15
subq %rcx, %r15
sarq $0x3, %r15
movabsq $-0x5555555555555555, %rsi # imm = 0xAAAAAAAAAAAAAAAB
imulq %rsi, %r15
movq %r15, %rax
xorl %edx, %edx
divq %r8
movq %rax, 0x20(%rsp)
movq %r8, 0x8(%rsp)
cmpq %r8, %r15
jb 0x1cb2c
movq (%rcx), %rdi
movq 0x8(%rcx), %rcx
subq %rdi, %rcx
sarq $0x3, %rcx
imulq %rsi, %rcx
movq %rcx, %rax
xorl %edx, %edx
divq %r14
movq %rax, 0x28(%rsp)
movq %rcx, 0x30(%rsp)
cmpq %r14, %rcx
jb 0x1cb4a
movq (%rdi), %rbp
movq 0x8(%rdi), %rbx
movq %rbx, %r13
subq %rbp, %r13
sarq $0x2, %r13
leaq 0x6c(%rsp), %rdx
movl $0xff800000, (%rdx)     # imm = 0xFF800000
leaq 0x50(%rsp), %rdi
leaq 0x7(%rsp), %rcx
movq %r13, %rsi
callq 0x1ead4
leaq 0x70(%rsp), %rdi
leaq 0x50(%rsp), %rdx
leaq 0x6(%rsp), %rcx
movq 0x28(%rsp), %rsi
callq 0x1eb56
leaq 0x70(%rsp), %rdx
leaq 0x5(%rsp), %rcx
movq 0x18(%rsp), %rdi
movq 0x20(%rsp), %rsi
callq 0x1ebee
leaq 0x70(%rsp), %rdi
callq 0x1ec86
movq 0x50(%rsp), %rdi
testq %rdi, %rdi
je 0x1ca01
movq 0x60(%rsp), %rsi
subq %rdi, %rsi
callq 0x21e0
cmpq 0x8(%rsp), %r15
jb 0x1cb15
cmpq $0x1, %r13
adcq $0x0, %r13
cmpq $0x1, %r14
movq %r14, %rax
adcq $0x0, %rax
movq 0x8(%rsp), %rcx
cmpq $0x1, %rcx
adcq $0x0, %rcx
movq %rcx, 0x40(%rsp)
movq $0x0, 0x10(%rsp)
movq %r14, 0x38(%rsp)
cmpq %r14, 0x30(%rsp)
jb 0x1cafd
movq 0x10(%rsp), %rdx
movq %rdx, %rcx
imulq 0x8(%rsp), %rcx
leaq (%rcx,%rcx,2), %rsi
shlq $0x3, %rsi
leaq (%rdx,%rdx,2), %rdi
shlq $0x3, %rdi
xorl %r8d, %r8d
movq %r8, %rcx
imulq %r14, %rcx
leaq (%rcx,%rcx,2), %r9
shlq $0x3, %r9
xorl %r10d, %r10d
movq 0x48(%rsp), %rcx
movq (%rcx), %rcx
addq %rsi, %rcx
leaq (%r10,%r10,2), %rdx
leaq (%rcx,%rdx,8), %r11
movq 0x18(%rsp), %rcx
movq (%rcx), %rdx
addq %rdi, %rdx
xorl %r14d, %r14d
cmpq %rbp, %rbx
je 0x1cad8
movq (%r11), %rcx
addq %r9, %rcx
leaq (%r14,%r14,2), %r15
movq (%rcx,%r15,8), %r15
movq (%rdx), %rcx
leaq (%r8,%r8,2), %r12
movq (%rcx,%r12,8), %r12
xorl %ecx, %ecx
movss (%r15,%rcx,4), %xmm0
maxss (%r12,%rcx,4), %xmm0
movss %xmm0, (%r12,%rcx,4)
incq %rcx
cmpq %rcx, %r13
jne 0x1cabe
incq %r14
cmpq %rax, %r14
jne 0x1ca9e
incq %r10
cmpq 0x40(%rsp), %r10
jne 0x1ca7d
incq %r8
cmpq 0x28(%rsp), %r8
movq 0x38(%rsp), %r14
jb 0x1ca6b
movq 0x10(%rsp), %rdx
incq %rdx
movq %rdx, 0x10(%rsp)
cmpq 0x20(%rsp), %rdx
jb 0x1ca3f
movq 0x18(%rsp), %rax
addq $0x88, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movl $0x10, %edi
callq 0x20f0
movq %rax, %r14
leaq 0x455b(%rip), %rsi      # 0x2109b
movq %rax, %rdi
callq 0x20b0
jmp 0x1cb66
movl $0x10, %edi
callq 0x20f0
movq %rax, %r14
leaq 0x453d(%rip), %rsi      # 0x2109b
movq %rax, %rdi
callq 0x20b0
movq 0x95483(%rip), %rsi     # 0xb1ff0
movq 0x9543c(%rip), %rdx     # 0xb1fb0
movq %r14, %rdi
callq 0x22c0
jmp 0x1cb7e
movq %rax, %rbx
movq %r14, %rdi
callq 0x2180
jmp 0x1cbb9
movq %rax, %rbx
leaq 0x70(%rsp), %rdi
callq 0x1ec86
jmp 0x1cb9d
movq %rax, %rbx
movq 0x50(%rsp), %rdi
testq %rdi, %rdi
je 0x1cbb9
movq 0x60(%rsp), %rsi
subq %rdi, %rsi
callq 0x21e0
jmp 0x1cbb9
movq %rax, %rbx
movq %rbx, %rdi
callq 0x22d0