// File: /workspace/github_cpp_makefile_star2_O3/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, %r15
movq %rdx, %r8
movq %rdi, 0x8(%rsp)
movq (%rsi), %r9
movq %rsi, 0x48(%rsp)
movq 0x8(%rsi), %rcx
subq %r9, %rcx
sarq $0x3, %rcx
movabsq $-0x5555555555555555, %rdi # imm = 0xAAAAAAAAAAAAAAAB
imulq %rdi, %rcx
movq %rcx, %rax
xorl %edx, %edx
divq %r8
movq %rax, 0x10(%rsp)
movq %r8, 0x18(%rsp)
cmpq %r8, %rcx
jb 0x1c52f
movq (%r9), %r8
movq 0x8(%r9), %rcx
subq %r8, %rcx
sarq $0x3, %rcx
imulq %rdi, %rcx
movq %rcx, %rax
xorl %edx, %edx
divq %r15
movq %rax, 0x20(%rsp)
cmpq %r15, %rcx
jb 0x1c54d
movq (%r8), %r14
movq 0x8(%r8), %rbx
movq %rbx, %r13
subq %r14, %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 0x1e4b6
leaq 0x70(%rsp), %rdi
leaq 0x50(%rsp), %rdx
leaq 0x6(%rsp), %rcx
movq 0x20(%rsp), %rsi
callq 0x1e640
leaq 0x70(%rsp), %rdx
leaq 0x5(%rsp), %rcx
movq 0x8(%rsp), %rdi
movq 0x10(%rsp), %rsi
callq 0x1e6d8
leaq 0x70(%rsp), %rdi
callq 0x1e770
movq 0x50(%rsp), %rdi
testq %rdi, %rdi
je 0x1c41c
movq 0x60(%rsp), %rsi
subq %rdi, %rsi
callq 0x21e0
cmpq $0x1, %r13
adcq $0x0, %r13
cmpq $0x1, %r15
movq %r15, %rax
adcq $0x0, %rax
movq 0x18(%rsp), %rcx
cmpq $0x1, %rcx
adcq $0x0, %rcx
movq %rcx, 0x40(%rsp)
xorl %edx, %edx
movq %r15, 0x30(%rsp)
movq %rdx, %rcx
imulq 0x18(%rsp), %rcx
leaq (%rcx,%rcx,2), %rsi
shlq $0x3, %rsi
movq %rdx, 0x28(%rsp)
leaq (%rdx,%rdx,2), %rdi
shlq $0x3, %rdi
xorl %edx, %edx
movq %rdx, %rcx
imulq %r15, %rcx
leaq (%rcx,%rcx,2), %r9
shlq $0x3, %r9
movq %rdx, 0x38(%rsp)
leaq (%rdx,%rdx,2), %r10
xorl %r11d, %r11d
movq 0x48(%rsp), %rcx
movq (%rcx), %rcx
addq %rsi, %rcx
leaq (%r11,%r11,2), %rdx
leaq (%rcx,%rdx,8), %rdx
movq 0x8(%rsp), %rcx
movq (%rcx), %rbp
addq %rdi, %rbp
xorl %r8d, %r8d
cmpq %r14, %rbx
je 0x1c4db
movq (%rdx), %rcx
addq %r9, %rcx
leaq (%r8,%r8,2), %r15
movq (%rcx,%r15,8), %r15
movq (%rbp), %rcx
movq (%rcx,%r10,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 0x1c4c1
incq %r8
cmpq %rax, %r8
jne 0x1c4a4
incq %r11
cmpq 0x40(%rsp), %r11
jne 0x1c483
movq 0x38(%rsp), %rdx
incq %rdx
cmpq 0x20(%rsp), %rdx
movq 0x30(%rsp), %r15
jb 0x1c468
movq 0x28(%rsp), %rdx
incq %rdx
cmpq 0x10(%rsp), %rdx
jb 0x1c448
movq 0x8(%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 0x3b80(%rip), %rsi      # 0x200c3
movq %rax, %rdi
callq 0x20b0
jmp 0x1c569
movl $0x10, %edi
callq 0x20f0
movq %rax, %r14
leaq 0x3b62(%rip), %rsi      # 0x200c3
movq %rax, %rdi
callq 0x20b0
movq 0x94a80(%rip), %rsi     # 0xb0ff0
movq 0x94a39(%rip), %rdx     # 0xb0fb0
movq %r14, %rdi
callq 0x22c0
jmp 0x1c581
movq %rax, %rbx
movq %r14, %rdi
callq 0x2180
jmp 0x1c5bc
movq %rax, %rbx
leaq 0x70(%rsp), %rdi
callq 0x1e770
jmp 0x1c5a0
movq %rax, %rbx
movq 0x50(%rsp), %rdi
testq %rdi, %rdi
je 0x1c5bc
movq 0x60(%rsp), %rsi
subq %rdi, %rsi
callq 0x21e0
jmp 0x1c5bc
movq %rax, %rbx
movq %rbx, %rdi
callq 0x22d0