// File: /workspace/github_c_makefile_star2_O3/CerfVert94[P]lenet_cnn/main.c
// Function: main
int main(void){
	#if !defined(_CONV_WEIGHTS_)
	char Input[10][29*29] = {};

	//Load gray scale image.
	const char *bmp_path[10] = {"./Data/0.bmp",
								"./Data/1.bmp",
								"./Data/2.bmp",
								"./Data/3.bmp",
								"./Data/4.bmp",
								"./Data/5.bmp",
								"./Data/6.bmp",
								"./Data/7.bmp",
								"./Data/8.bmp",
								"./Data/9.bmp"};
	int nb_idx, input_idx, result;
	
	for (nb_idx = 0; nb_idx < 10; nb_idx++) {
		// Read the image
		read_data(bmp_path[nb_idx], Input[nb_idx]);
		// Print the handwritten digit : 
		for(input_idx = 0; input_idx < IMG_WIDTH * IMG_HEIGHT; input_idx++) {
			if((input_idx % IMG_WIDTH) == 0)
				fputc('\n',stdout);
			
			fputc(Input[nb_idx][input_idx] + '0',stdout);
		}
		fputc('\n',stdout);
		
		// Run the neural network to recognized the digit : 
		result = evaluate(Input[nb_idx]);
		printf("The recognized digit is %d\n", result);	
		if (nb_idx != result) {
			fprintf(stderr, "Recognized digit is a mismatch : %d =/= %d\n", nb_idx, result);
			exit(EXIT_FAILURE);
		}
		
	}
	write_data(Input, 10);
	fprintf(stdout, "Success\n");
	#else
	#define NB_WEIGHTS_LAYER1 ((5 * 5 + 1) * 6)
	#define NB_WEIGHTS_LAYER2 (((5 * 5 + 1) * 6) * 50)
	#define NB_WEIGHTS_LAYER3 ((5 * 5 * 50 + 1) * 100)
	#define NB_WEIGHTS_LAYER4 ((100 + 1) * 10)
	
	FILE *ptr_file1, *ptr_file2;
	// Create new header files.
	ptr_file1 = fopen("short_weight.h", "wb");
	ptr_file2 = fopen("char_weight.h", "wb");
	// Null pointer signifies an error :
	if (!ptr_file1 || !ptr_file2) {
		fprintf(stdout, "Failed creating new header files\n");
		exit(EXIT_FAILURE);
	}
	
	fprintf(ptr_file1, "#ifndef _SHORT_WEIGHT_H_\n#define _SHORT_WEIGHT_H_\n");
	fprintf(ptr_file2, "#ifndef _CHAR_WEIGHT_H_\n#define _CHAR_WEIGHT_H_\n");
	write_weights(ptr_file1, ptr_file2, "Layer1_Weights_CPU", Layer1_Weights_CPU, NB_WEIGHTS_LAYER1);
	write_weights(ptr_file1, ptr_file2, "Layer2_Weights_CPU", Layer2_Weights_CPU, NB_WEIGHTS_LAYER2);
	write_weights(ptr_file1, ptr_file2, "Layer3_Weights_CPU", Layer3_Weights_CPU, NB_WEIGHTS_LAYER3);
	write_weights(ptr_file1, ptr_file2, "Layer4_Weights_CPU", Layer4_Weights_CPU, NB_WEIGHTS_LAYER4);
	fprintf(ptr_file1, "#endif\n");
	fprintf(ptr_file2, "#endif\n");
	fclose(ptr_file1);
	fclose(ptr_file2);
	#endif
	return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x20f8, %rsp           # imm = 0x20F8
leaq -0x2120(%rbp), %rbx
movl $0x20da, %edx           # imm = 0x20DA
movq %rbx, %rdi
xorl %esi, %esi
callq 0x1060
movq 0x2cc7(%rip), %r13      # 0x3fd8
xorl %ecx, %ecx
leaq 0xea6(%rip), %rax       # 0x21c0
movslq (%rax,%rcx,4), %rdi
addq %rax, %rdi
movq %rcx, -0x38(%rbp)
imulq $0x349, %rcx, %rax      # imm = 0x349
leaq (%rax,%rbp), %rsi
addq $-0x2120, %rsi          # imm = 0xDEE0
movq %rsi, -0x30(%rbp)
callq 0x142c
movq $-0x349, %r15           # imm = 0xFCB7
xorl %r12d, %r12d
xorl %r14d, %r14d
movzwl %r12w, %eax
imull $0x469f, %eax, %eax     # imm = 0x469F
shrl $0x13, %eax
leal (%rax,%rax,8), %ecx
leal (%rcx,%rcx,2), %ecx
addl %eax, %eax
addl %ecx, %eax
addw %r14w, %ax
jne 0x1378
movq (%r13), %rsi
movl $0xa, %edi
callq 0x1080
movsbl 0x349(%rbx,%r15), %edi
addl $0x30, %edi
movq (%r13), %rsi
callq 0x1080
decl %r14d
incl %r12d
incq %r15
jne 0x134d
movq (%r13), %rsi
movl $0xa, %edi
callq 0x1080
movq -0x30(%rbp), %rdi
callq 0x122c
movl %eax, %r12d
leaq 0xce1(%rip), %rdi       # 0x209a
movl %eax, %esi
xorl %eax, %eax
callq 0x1040
movl %r12d, %eax
movq -0x38(%rbp), %rcx
cmpq %rax, %rcx
jne 0x1421
incq %rcx
addq $0x349, %rbx            # imm = 0x349
cmpq $0xa, %rcx
jne 0x1313
leaq -0x2120(%rbp), %rdi
movl $0xa, %esi
callq 0x1546
movq (%r13), %rcx
leaq 0xce4(%rip), %rdi       # 0x20e2
movl $0x8, %esi
movl $0x1, %edx
callq 0x10f0
xorl %eax, %eax
addq $0x20f8, %rsp           # imm = 0x20F8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rcx, %rdi
movl %r12d, %esi
callq 0x1110