// File: /workspace/github_cpp_makefile_star2_O3/hey-yahei[P]ConvNet/src/Convolution.cpp
// Function: Convolution::Run(float*, bool)
float* Convolution::Run(float* in_data, bool keep_in){
	int idx_gp;
	int start_h, start_w;
	int idx_ih, idx_iw;
	float wt, dat, result;

	out_data = (float*)malloc(sizeof(float) * in_shape[0] * out_chw);

	// Do convolution
	for (int idx_bs = 0; idx_bs < in_shape[0]; idx_bs++) {
		for (int idx_oc = 0; idx_oc < out_shape[1]; idx_oc++) {
			idx_gp = idx_oc / oc_per_gp;
			for (int idx_oh = 0; idx_oh < out_shape[2]; idx_oh++) {
				for (int idx_ow = 0; idx_ow < out_shape[3]; idx_ow++) {
					start_h = idx_oh * stride - pad;
					start_w = idx_ow * stride - pad;
					result = 0;
					for (int idx_ic = ic_per_gp * idx_gp; idx_ic < ic_per_gp * (idx_gp + 1); idx_ic++) {
						for (int idx_kh = 0; idx_kh < kernel; idx_kh++) {
							for (int idx_kw = 0; idx_kw < kernel; idx_kw++) {
								idx_ih = start_h + idx_kh;
								idx_iw = start_w + idx_kw;
								if ((idx_ih < 0) || (idx_iw < 0) || (idx_ih >= in_shape[2]) || (idx_iw >= in_shape[3]))
									dat = 0.;
								else
									dat = get_in_data(in_data, idx_bs, idx_ic, idx_ih, idx_iw);
								wt = get_weight_data(idx_oc, idx_ic - idx_gp * ic_per_gp, idx_kh, idx_kw);
								result += dat * wt;
							}
						}
					}
					if (with_bias)
						result += bias_data[idx_oc];
					if (with_relu && result < 0)
						result = 0;
					set_out_data(idx_bs, idx_oc, idx_oh, idx_ow, result);
				}
			}
		}
	}

	if (!keep_in)
		free(in_data);

	return out_data;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x108, %rsp            # imm = 0x108
movl %edx, -0x6c(%rbp)
movq %rsi, %r14
movq %rdi, %rbx
movslq 0x20(%rdi), %r15
movslq 0x58(%rdi), %rcx
movq %r15, %rdi
movq %rcx, -0xd0(%rbp)
imulq %rcx, %rdi
shlq $0x2, %rdi
callq 0x2240
movq %rbx, -0xa0(%rbp)
movq %rax, -0x68(%rbp)
movq %rax, 0x78(%rbx)
movq %r15, -0xd8(%rbp)
testq %r15, %r15
jle 0x3bc3
movq -0xa0(%rbp), %rax
movl 0x34(%rax), %ecx
movq %rcx, -0xa8(%rbp)
movl 0x1c(%rax), %ecx
movl %ecx, -0x80(%rbp)
movl 0x38(%rax), %ecx
movl %ecx, -0x38(%rbp)
movl 0x4(%rax), %ecx
movl 0x8(%rax), %edx
movl 0x18(%rax), %esi
movl 0x44(%rax), %edi
movl 0x48(%rax), %r8d
movb 0x65(%rax), %r9b
movb %r9b, -0x2a(%rbp)
movb 0x64(%rax), %r9b
movb %r9b, -0x29(%rbp)
movl %edx, %r9d
negl %r9d
movq %r9, -0xe8(%rbp)
movq %rcx, -0xb0(%rbp)
imull %r8d, %ecx
movq %rcx, -0xf0(%rbp)
movq %r8, -0x128(%rbp)
movl %r8d, %ecx
notl %ecx
movl %edx, -0x88(%rbp)
imull %edx, %ecx
movl %ecx, -0x34(%rbp)
movq %rdi, -0x110(%rbp)
movl %edi, %ecx
movl %esi, -0x7c(%rbp)
imull %esi, %ecx
movl %ecx, -0x78(%rbp)
movl 0x3c(%rax), %ecx
movq %rcx, -0xb8(%rbp)
movl (%rax), %edi
movl 0x28(%rax), %r9d
movl 0x2c(%rax), %r15d
movl 0x40(%rax), %ecx
movl %ecx, -0x70(%rbp)
movq 0x68(%rax), %rsi
movl 0x4c(%rax), %ecx
movq %rcx, -0xe0(%rbp)
movl 0x50(%rax), %ecx
movq %rcx, -0x108(%rbp)
movl 0x54(%rax), %r12d
movq 0x70(%rax), %rcx
movq %rcx, -0xf8(%rbp)
movl 0x5c(%rax), %ecx
movl %ecx, -0x74(%rbp)
movl 0x60(%rax), %eax
movl %eax, -0x84(%rbp)
movq $0x0, -0x50(%rbp)
cmpl $0x0, -0xa8(%rbp)
jle 0x3ba7
movq -0x50(%rbp), %rax
imull -0xd0(%rbp), %eax
movq %rax, -0x100(%rbp)
movq $0x0, -0x60(%rbp)
movq $0x0, -0x48(%rbp)
cmpl $0x0, -0x38(%rbp)
jle 0x3b80
movq -0x48(%rbp), %rcx
movl %ecx, %eax
cltd
idivl -0x80(%rbp)
movl -0x7c(%rbp), %edx
movl %edx, %r8d
imull %eax, %r8d
movl %r8d, -0x3c(%rbp)
leal 0x1(%rax), %r8d
imull %edx, %r8d
movl %r8d, -0x40(%rbp)
movl -0x74(%rbp), %edx
imull %ecx, %edx
movl %edx, -0x8c(%rbp)
imull -0x78(%rbp), %eax
addl -0x34(%rbp), %eax
movq %rax, -0x58(%rbp)
movl $0x0, -0x30(%rbp)
cmpl $0x0, -0xb8(%rbp)
jle 0x3b60
movq -0xb0(%rbp), %r10
movl -0x30(%rbp), %eax
imull %eax, %r10d
subl -0x88(%rbp), %r10d
movl -0x84(%rbp), %ecx
imull %eax, %ecx
movl %ecx, -0x90(%rbp)
movq -0x58(%rbp), %rax
movq %rax, -0xc0(%rbp)
movq -0xe8(%rbp), %r8
xorl %edx, %edx
movq %rdx, -0xc8(%rbp)
xorps %xmm0, %xmm0
movl -0x40(%rbp), %eax
cmpl %eax, -0x3c(%rbp)
jge 0x3af2
movq -0xc0(%rbp), %rdx
movq -0x60(%rbp), %r11
movl -0x3c(%rbp), %eax
movl %eax, -0x94(%rbp)
testl %edi, %edi
movq %rdx, -0x120(%rbp)
movq %r11, -0x118(%rbp)
jle 0x3ac5
xorl %ecx, %ecx
movq %rdx, %rax
movq %r11, %rdx
leal (%rcx,%r10), %r11d
xorl %r13d, %r13d
xorps %xmm1, %xmm1
testl %r11d, %r11d
js 0x3a9d
movl %r8d, %ebx
addl %r13d, %ebx
js 0x3a9d
cmpl %r9d, %r11d
jge 0x3a9d
cmpl %r15d, %ebx
jge 0x3a9d
leal (%rax,%r13), %ebx
movslq %ebx, %rbx
movss (%r14,%rbx,4), %xmm1
leal (%rdx,%r13), %ebx
movslq %ebx, %rbx
mulss (%rsi,%rbx,4), %xmm1
addss %xmm1, %xmm0
incq %r13
cmpq %r13, %rdi
jne 0x3a76
incl %ecx
addq %r12, %rdx
addq -0x128(%rbp), %rax
cmpl %edi, %ecx
jne 0x3a6f
movl -0x94(%rbp), %eax
incl %eax
movq -0x118(%rbp), %r11
addq -0x108(%rbp), %r11
movq -0x120(%rbp), %rdx
addq -0x110(%rbp), %rdx
cmpl -0x40(%rbp), %eax
jne 0x3a4f
testb $0x1, -0x2a(%rbp)
je 0x3b08
movq -0xf8(%rbp), %rax
movq -0x48(%rbp), %rcx
addss (%rax,%rcx,4), %xmm0
movq -0xc8(%rbp), %rdx
testb $0x1, -0x29(%rbp)
je 0x3b1f
xorps %xmm1, %xmm1
maxss %xmm0, %xmm1
movaps %xmm1, %xmm0
movq -0x100(%rbp), %rax
addl %edx, %eax
addl -0x8c(%rbp), %eax
addl -0x90(%rbp), %eax
cltq
movq -0x68(%rbp), %rcx
movss %xmm0, (%rcx,%rax,4)
incq %rdx
movq -0xb0(%rbp), %rax
addq %rax, %r8
addq %rax, -0xc0(%rbp)
cmpq -0xb8(%rbp), %rdx
jne 0x3a2b
movl -0x30(%rbp), %ecx
incl %ecx
movq -0x58(%rbp), %rax
addq -0xf0(%rbp), %rax
movq %rax, -0x58(%rbp)
movl %ecx, -0x30(%rbp)
cmpl -0x38(%rbp), %ecx
jne 0x39e6
movq -0x48(%rbp), %rcx
incq %rcx
movq -0x60(%rbp), %rax
addq -0xe0(%rbp), %rax
movq %rax, -0x60(%rbp)
movq %rcx, -0x48(%rbp)
cmpq -0xa8(%rbp), %rcx
jne 0x399a
movq -0x50(%rbp), %rcx
incl %ecx
movl -0x70(%rbp), %eax
addl %eax, -0x34(%rbp)
movq %rcx, -0x50(%rbp)
cmpl -0xd8(%rbp), %ecx
jne 0x396b
cmpb $0x0, -0x6c(%rbp)
jne 0x3be0
movq %r14, %rdi
callq 0x2200
movq -0xa0(%rbp), %rax
movq 0x78(%rax), %rax
movq %rax, -0x68(%rbp)
movq -0x68(%rbp), %rax
addq $0x108, %rsp            # imm = 0x108
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq