// File: /workspace/github_cpp_makefile_star2_O2/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 $0x58, %rsp
movl %edx, -0x3c(%rbp)
movq %rsi, -0x68(%rbp)
movq %rdi, %rbx
movslq 0x20(%rdi), %r14
movslq 0x58(%rdi), %rdi
imulq %r14, %rdi
shlq $0x2, %rdi
callq 0x2210
movq %rax, %rcx
movq %rax, 0x78(%rbx)
xorl %edi, %edi
cmpl %r14d, %edi
jge 0x3a74
xorl %r12d, %r12d
movq %rdi, -0x38(%rbp)
movslq 0x34(%rbx), %rax
cmpq %rax, %r12
jge 0x3a69
movl %r12d, %eax
cltd
idivl 0x1c(%rbx)
movq %rax, -0x70(%rbp)
incl %eax
movl %eax, -0x44(%rbp)
xorl %eax, %eax
cmpl 0x38(%rbx), %eax
jge 0x3a61
xorl %r10d, %r10d
movl %eax, -0x40(%rbp)
cmpl 0x3c(%rbx), %r10d
jge 0x3a5a
movl 0x4(%rbx), %edx
movl 0x8(%rbx), %ecx
movl %edx, %edi
imull %eax, %edi
subl %ecx, %edi
movq %rdi, -0x60(%rbp)
movl 0x18(%rbx), %eax
movl %eax, %edi
imull -0x70(%rbp), %edi
imull %r10d, %edx
subl %ecx, %edx
movl %edx, -0x48(%rbp)
xorps %xmm1, %xmm1
movl %r10d, -0x4c(%rbp)
imull -0x44(%rbp), %eax
cmpl %eax, %edi
jge 0x39fe
movl (%rbx), %eax
xorl %edx, %edx
movq -0x60(%rbp), %rcx
movl %ecx, -0x2c(%rbp)
movl %edi, -0x30(%rbp)
cmpl %eax, %edx
jge 0x39f4
movq -0x60(%rbp), %rcx
movq %rdx, -0x78(%rbp)
leal (%rdx,%rcx), %r13d
xorl %r14d, %r14d
movl -0x48(%rbp), %r15d
cmpl %eax, %r14d
jge 0x39df
xorps %xmm0, %xmm0
testl %r13d, %r13d
movl -0x30(%rbp), %edx
movss %xmm1, -0x54(%rbp)
js 0x39a4
testl %r15d, %r15d
js 0x39a4
cmpl 0x28(%rbx), %r13d
jge 0x39a4
cmpl 0x2c(%rbx), %r15d
jge 0x39a4
movl 0x40(%rbx), %eax
imull -0x38(%rbp), %eax
movl 0x44(%rbx), %ecx
imull %edx, %ecx
addl %eax, %ecx
movl 0x48(%rbx), %eax
imull -0x2c(%rbp), %eax
addl %r15d, %eax
addl %ecx, %eax
cltq
movq -0x68(%rbp), %rcx
movss (%rcx,%rax,4), %xmm0
movss %xmm0, -0x50(%rbp)
movl 0x18(%rbx), %eax
imull -0x70(%rbp), %eax
subl %eax, %edx
movq %rbx, %rdi
movl %r12d, %esi
movq -0x78(%rbp), %rcx
movl %r14d, %r8d
callq 0x3b0c
mulss -0x50(%rbp), %xmm0
movss -0x54(%rbp), %xmm1
addss %xmm0, %xmm1
incl %r14d
movl (%rbx), %eax
incl %r15d
jmp 0x3954
movq -0x78(%rbp), %rdx
incl %edx
incl -0x2c(%rbp)
movl -0x4c(%rbp), %r10d
movl -0x30(%rbp), %edi
jmp 0x3939
incl %edi
movl 0x18(%rbx), %eax
jmp 0x391f
cmpb $0x0, 0x65(%rbx)
je 0x3a0e
movq 0x70(%rbx), %rax
addss (%rax,%r12,4), %xmm1
movq -0x38(%rbp), %rdi
cmpb $0x0, 0x64(%rbx)
je 0x3a22
xorps %xmm0, %xmm0
maxss %xmm1, %xmm0
movaps %xmm0, %xmm1
movq 0x78(%rbx), %rcx
movl 0x58(%rbx), %eax
imull %edi, %eax
movl 0x5c(%rbx), %edx
imull %r12d, %edx
movl 0x60(%rbx), %r8d
movl -0x40(%rbp), %r9d
imull %r9d, %r8d
addl %edx, %r8d
addl %r10d, %eax
addl %r8d, %eax
cltq
movss %xmm1, (%rcx,%rax,4)
movl %r9d, %eax
incl %r10d
jmp 0x38eb
incl %eax
jmp 0x38dc
incq %r12
jmp 0x38bd
incl %edi
movl 0x20(%rbx), %r14d
jmp 0x38ad
cmpb $0x0, -0x3c(%rbp)
jne 0x3a87
movq -0x68(%rbp), %rdi
callq 0x21c0
movq 0x78(%rbx), %rcx
movq %rcx, %rax
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop