From cf050de1d6edbf921d3bd8297a5da11328e7340b Mon Sep 17 00:00:00 2001 From: augustin64 Date: Mon, 24 Oct 2022 12:54:51 +0200 Subject: [PATCH] Move to Makefile --- .github/workflows/tests.yml | 12 +- .gitignore | 4 +- Makefile | 126 ++++++++++++++++++ src/cnn/cnn.c | 8 +- src/cnn/creation.c | 6 +- src/cnn/free.c | 1 + src/cnn/function.c | 1 + src/cnn/include/matrix_multiplication.h | 40 ++++++ src/cnn/include/utils.h | 1 - src/cnn/initialisation.c | 2 +- src/cnn/main.c | 7 +- src/cnn/make.c | 2 +- src/cnn/neuron_io.c | 4 +- src/cnn/train.c | 19 +-- src/cnn/utils.c | 2 +- src/colors.c | 15 +++ src/{ => include}/colors.h | 16 +-- src/mnist/include/main.h | 2 - src/mnist/include/mnist.h | 1 - src/mnist/include/neural_network.h | 1 - src/mnist/include/neuron_io.h | 1 - src/mnist/include/preview.h | 1 - src/webserver/app.py | 4 +- ...cation.cu => cnn_matrix_multiplication.cu} | 2 +- test/cnn_neuron_io.c | 9 +- test/cnn_utils.c | 6 +- test/mnist_utils.sh | 14 +- 27 files changed, 241 insertions(+), 66 deletions(-) create mode 100644 Makefile create mode 100644 src/cnn/include/matrix_multiplication.h create mode 100644 src/colors.c rename src/{ => include}/colors.h (76%) rename test/{matrix_multiplication.cu => cnn_matrix_multiplication.cu} (98%) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 880ebc8..9c05f9c 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -13,13 +13,11 @@ jobs: steps: - uses: actions/checkout@v3 - - name: compile all - run: ./make.sh build all - - name: run tests - run: ./make.sh test run - - name: mnist main test - run: out/mnist_main train + - name: run-tests + run: make run-tests + - name: mnist main train + run: build/mnist-main train --epochs 1 --images data/mnist/t10k-images-idx3-ubyte --labels data/mnist/t10k-labels-idx1-ubyte - --out reseau.bin + --out mnist-reseau.bin diff --git a/.gitignore b/.gitignore index e352a60..1c88866 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,10 @@ -**/out **/a.out **/__pycache__ .cache .test-cache .vscode +build/* *.bin -app-secret + data/50States10K \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..94d0459 --- /dev/null +++ b/Makefile @@ -0,0 +1,126 @@ +BUILDDIR := ./build +SRCDIR := ./src +CACHE_DIR := ./cache +NVCC := nvcc +CC := gcc + + +MNIST_SRCDIR := $(SRCDIR)/mnist +CNN_SRCDIR := $(SRCDIR)/cnn + +MNIST_SRC := $(wildcard $(MNIST_SRCDIR)/*.c) +CNN_SRC := $(wildcard $(CNN_SRCDIR)/*.c) +CNN_SRC_CUDA := $(wildcard $(CNN_SRCDIR)/*.cu) + +MNIST_OBJ = $(filter-out $(BUILDDIR)/mnist_main.o $(BUILDDIR)/mnist_utils.o $(BUILDDIR)/mnist_preview.o, $(MNIST_SRC:$(MNIST_SRCDIR)/%.c=$(BUILDDIR)/mnist_%.o)) +CNN_OBJ = $(filter-out $(BUILDDIR)/cnn_main.o, $(CNN_SRC:$(CNN_SRCDIR)/%.c=$(BUILDDIR)/cnn_%.o)) +CNN_OBJ_CUDA = $(CNN_SRC:$(CNN_SRCDIR)/%.cu=$(BUILDDIR)/cnn_%.o) + + +TEST_SRCDIR := test + +TESTS_SRC = $(wildcard test/*.c) +TESTS_SRC_CU += $(wildcard test/*.cu) + +TESTS_OBJ = $(TESTS_SRC:test/%.c=$(BUILDDIR)/test-%) $(TESTS_SRC_CU:test/%.cu=$(BUILDDIR)/test-%) + +# Compile flags +CFLAGS = -std=c99 -lm -lpthread +NVCCFLAGS = + +# Additional warning rules +CFLAGS += -Wall -Wextra +NVCCFLAGS += +# Remove warnings about unused variables, functions, ... +# -Wno-unused-parameter -Wno-unused-function -Wno-unused-variable -Wno-unused-but-set-variable +# Compile with debug +# -g + +all: mnist cnn; +# +# Build mnist +# +# Executables +mnist: $(BUILDDIR)/mnist-main $(BUILDDIR)/mnist-utils $(BUILDDIR)/mnist-preview; + +$(BUILDDIR)/mnist-main: $(MNIST_SRCDIR)/main.c $(BUILDDIR)/mnist.o $(BUILDDIR)/mnist_neuron_io.o $(BUILDDIR)/mnist_neural_network.o + $(CC) $(CFLAGS) $(MNIST_SRCDIR)/main.c $(BUILDDIR)/mnist.o $(BUILDDIR)/mnist_neuron_io.o $(BUILDDIR)/mnist_neural_network.o -o $(BUILDDIR)/mnist-main + +$(BUILDDIR)/mnist-utils: $(MNIST_SRCDIR)/utils.c $(BUILDDIR)/mnist_neural_network.o $(BUILDDIR)/mnist_neuron_io.o $(BUILDDIR)/mnist.o + $(CC) $(CFLAGS) $^ -o $@ + +$(BUILDDIR)/mnist-preview: $(MNIST_SRCDIR)/preview.c $(BUILDDIR)/mnist.o + $(CC) $(CFLAGS) $^ -o $@ + +# .o files +$(BUILDDIR)/mnist.o: $(MNIST_SRCDIR)/mnist.c $(MNIST_SRCDIR)/include/mnist.h + $(CC) $(CFLAGS) -c $< -o $@ + +$(BUILDDIR)/mnist_%.o: $(MNIST_SRCDIR)/%.c $(MNIST_SRCDIR)/include/%.h + $(CC) $(CFLAGS) -c $< -o $@ + + +# +# Build cnn +# +cnn: $(BUILDDIR)/cnn-main; + +$(BUILDDIR)/cnn-main: $(CNN_SRCDIR)/main.c $(BUILDDIR)/cnn_train.o $(BUILDDIR)/cnn_cnn.o $(BUILDDIR)/cnn_creation.o $(BUILDDIR)/cnn_initialisation.o $(BUILDDIR)/cnn_make.o $(BUILDDIR)/cnn_neuron_io.o $(BUILDDIR)/cnn_function.o $(BUILDDIR)/cnn_utils.o $(BUILDDIR)/cnn_free.o $(BUILDDIR)/colors.o $(BUILDDIR)/mnist.o + $(CC) $(CFLAGS) $^ -o $@ + +$(BUILDDIR)/cnn_%.o: $(CNN_SRCDIR)/%.c $(CNN_SRCDIR)/include/%.h + $(CC) $(CFLAGS) -c $< -o $@ + +$(BUILDDIR)/cnn_%.o: $(CNN_SRCDIR)/%.cu $(CNN_SRCDIR)/include/%.h + $(NVCC) $(NVCCFLAGS) -c $< -o $@ +# +# Build general files +# +$(BUILDDIR)/%.o: $(SRCDIR)/%.c $(SRCDIR)/include/%.h + $(CC) $(CFLAGS) -c $< -o $@ + +# +# Tests +# +run-tests: build-tests + $(foreach file, $(wildcard $(BUILDDIR)/test-*), $(file);) + $(foreach file, $(wildcard $(TEST_SRCDIR)/*.sh), $(file);) + +build-tests: prepare-tests $(TESTS_OBJ) + + +prepare-tests: + @rm -f $(BUILDDIR)/test-* + + +build/test-cnn_%: test/cnn_%.c $(CNN_OBJ) $(BUILDDIR)/colors.o $(BUILDDIR)/mnist.o + $(CC) $(CFLAGS) $^ -o $@ + +# mnist.o est déjà inclus en tant que mnist_mnist.o +build/test-mnist_%: test/mnist_%.c $(MNIST_OBJ) $(BUILDDIR)/colors.o + $(CC) $(CFLAGS) $^ -o $@ + +$(BUILDDIR)/test-cnn_matrix_multiplication: test/cnn_matrix_multiplication.cu $(BUILDDIR)/cnn_matrix_multiplication.o $(BUILDDIR)/colors.o $(BUILDDIR)/mnist.o + $(NVCC) $(NVCCFLAGS) $^ -o $@ + + +# +# Utils +# +webserver: $(CACHE_DIR)/mnist-reseau.bin + FLASK_APP="src/webserver/app.py" flask run + +$(CACHE_DIR)/mnist-reseau.bin: $(BUILDDIR)/mnist-main + @mkdir -p $(CACHE_DIR) + $(BUILDDIR)/mnist-main train \ + --images "data/mnist/train-images-idx3-ubyte" \ + --labels "data/mnist/train-labels-idx1-ubyte" \ + --out "$(CACHE_DIR)/mnist-reseau.bin" + + +# +# Clean project +# +clean: + rm -rf $(BUILDDIR)/* + rm -f $(CACHE_DIR)/* \ No newline at end of file diff --git a/src/cnn/cnn.c b/src/cnn/cnn.c index d28ef6e..3421a52 100644 --- a/src/cnn/cnn.c +++ b/src/cnn/cnn.c @@ -3,12 +3,12 @@ #include #include // Is it used ? -#include "../colors.h" #include "include/initialisation.h" -#include "function.c" -#include "creation.c" -#include "make.c" +#include "include/function.h" +#include "include/creation.h" +#include "include/make.h" +#include "../include/colors.h" #include "include/cnn.h" // Augmente les dimensions de l'image d'entrée diff --git a/src/cnn/creation.c b/src/cnn/creation.c index 93d851a..8162b76 100644 --- a/src/cnn/creation.c +++ b/src/cnn/creation.c @@ -1,8 +1,10 @@ #include #include -#include "include/creation.h" + +#include "include/initialisation.h" #include "include/function.h" -#include "initialisation.c" + +#include "include/creation.h" Network* create_network(int max_size, int learning_rate, int dropout, int initialisation, int input_dim, int input_depth) { if (dropout < 0 || dropout > 100) { diff --git a/src/cnn/free.c b/src/cnn/free.c index e2870b6..5866341 100644 --- a/src/cnn/free.c +++ b/src/cnn/free.c @@ -1,5 +1,6 @@ #include #include + #include "include/free.h" void free_a_cube_input_layer(Network* network, int pos, int depth, int dim) { diff --git a/src/cnn/function.c b/src/cnn/function.c index 58d8be3..6e9a7fd 100644 --- a/src/cnn/function.c +++ b/src/cnn/function.c @@ -1,6 +1,7 @@ #include #include #include + #include "include/function.h" float max(float a, float b) { diff --git a/src/cnn/include/matrix_multiplication.h b/src/cnn/include/matrix_multiplication.h new file mode 100644 index 0000000..71c3ca1 --- /dev/null +++ b/src/cnn/include/matrix_multiplication.h @@ -0,0 +1,40 @@ +#include +#include +#include + +#ifndef DEF_MATRIX_MULTIPLICATION_H +#define DEF_MATRIX_MULTIPLICATION_H + + +#ifdef __CUDACC__ +/* +* Partie entière supérieure de a/b +*/ +int i_div_up(int a, int b); + +/* +* Fonction exécutée par chaque thread lancé dans `matrix_multiplication_device` +*/ +__global__ void matrix_mul_kernel(float* Md, float* Nd, float* Pd, int n, int p, int q, size_t pitch_m, size_t pitch_n, size_t pitch_p); + +/* +* Multiplication de deux matrices sur le GPU +*/ +void matrix_multiplication_device(float** m1, float** m2, float** result, int n, int p, int q); +#endif + +/* +* Vérification de la compatibilité CUDA +*/ +bool check_cuda_compatibility(); + +/* +* Multiplication naïve de matrices sur le CPU (1 seul coeur) +*/ +void matrix_multiplication_host(float** m1, float** m2, float** result, int n, int p, int q); + +/* +* Multiplication de matrices (décide si il faut la faire sur CPU ou GPU) +*/ +void matrix_multiplication(float** m1, float** m2, float** result, int n, int p, int q, bool use_cuda); +#endif \ No newline at end of file diff --git a/src/cnn/include/utils.h b/src/cnn/include/utils.h index 190f0a2..af210b5 100644 --- a/src/cnn/include/utils.h +++ b/src/cnn/include/utils.h @@ -3,7 +3,6 @@ #include #include -#include "../../colors.h" #include "struct.h" #ifndef DEF_UTILS_H diff --git a/src/cnn/initialisation.c b/src/cnn/initialisation.c index 8bb02ca..0995122 100644 --- a/src/cnn/initialisation.c +++ b/src/cnn/initialisation.c @@ -1,7 +1,7 @@ #include #include -#include "../colors.h" +#include "../include/colors.h" #include "include/initialisation.h" diff --git a/src/cnn/main.c b/src/cnn/main.c index 2629fd3..91b6dd0 100644 --- a/src/cnn/main.c +++ b/src/cnn/main.c @@ -4,9 +4,12 @@ #include #include -#include "train.c" +#include "include/initialisation.h" +#include "../include/colors.h" +#include "include/function.h" +#include "include/creation.h" +#include "include/train.h" #include "include/cnn.h" -#include "../colors.h" #include "include/main.h" diff --git a/src/cnn/make.c b/src/cnn/make.c index ad5566f..8d6a50c 100644 --- a/src/cnn/make.c +++ b/src/cnn/make.c @@ -1,6 +1,6 @@ #include -#include "../colors.h" +#include "../include/colors.h" #include "include/make.h" void make_convolution(Kernel_cnn* kernel, float*** input, float*** output, int output_dim) { diff --git a/src/cnn/neuron_io.c b/src/cnn/neuron_io.c index bf570e1..c3935f9 100644 --- a/src/cnn/neuron_io.c +++ b/src/cnn/neuron_io.c @@ -3,7 +3,7 @@ #include #include -#include "../colors.h" +#include "../include/colors.h" #include "include/neuron_io.h" #include "include/struct.h" @@ -170,7 +170,7 @@ Network* read_network(char* filename) { } network->input = (float****)malloc(sizeof(float***)*size); - for (int i=0; i < size; i++) { // input[size][couche->depth][couche->dim][couche->dim] + for (int i=0; i < (int)size; i++) { // input[size][couche->depth][couche->dim][couche->dim] network->input[i] = (float***)malloc(sizeof(float**)*network->depth[i]); for (int j=0; j < network->depth[i]; j++) { network->input[i][j] = (float**)malloc(sizeof(float*)*network->width[i]); diff --git a/src/cnn/train.c b/src/cnn/train.c index 0124e3f..382486f 100644 --- a/src/cnn/train.c +++ b/src/cnn/train.c @@ -4,12 +4,15 @@ #include #include -#include "../mnist/mnist.c" -#include "../colors.h" -#include "neuron_io.c" -#include "utils.c" -#include "free.c" -#include "cnn.c" +#include "../mnist/include/mnist.h" +#include "include/initialisation.h" +#include "include/neuron_io.h" +#include "../include/colors.h" +#include "include/function.h" +#include "include/creation.h" +#include "include/utils.h" +#include "include/free.h" +#include "include/cnn.h" #include "include/train.h" @@ -19,7 +22,7 @@ void* train_thread(void* parameters) { Network* network = param->network; int*** images = param->images; - int* labels = param->labels; + int* labels = (int*)param->labels; int width = param->width; int height = param->height; @@ -32,7 +35,7 @@ void* train_thread(void* parameters) { if (dataset_type == 0) { write_image_in_network_32(images[i], height, width, network->input[0][0]); forward_propagation(network); - //backward_propagation(network, labels[i]); + backward_propagation(network, labels[i]); // TODO get_indice_max(network last layer) // TODO if indice_max == labels[i] then accuracy += 1. diff --git a/src/cnn/utils.c b/src/cnn/utils.c index f834529..d794f6a 100644 --- a/src/cnn/utils.c +++ b/src/cnn/utils.c @@ -3,7 +3,7 @@ #include #include -#include "../colors.h" +#include "../include/colors.h" #include "include/struct.h" #define copyVar(var) network_cp->var = network->var diff --git a/src/colors.c b/src/colors.c new file mode 100644 index 0000000..05c7328 --- /dev/null +++ b/src/colors.c @@ -0,0 +1,15 @@ +#include + +#include "include/colors.h" + +void printf_error(char* string) { + printf(BOLDRED "[ ERROR ]" RESET " %s", string); +} + +void printf_warning(char* string) { + printf(BOLDYELLOW "[WARNING]" RESET " %s", string); +} + +void printf_info(char* string) { + printf(BOLDBLUE "[ INFO ]" RESET " %s", string); +} \ No newline at end of file diff --git a/src/colors.h b/src/include/colors.h similarity index 76% rename from src/colors.h rename to src/include/colors.h index 459220a..58ad2fd 100644 --- a/src/colors.h +++ b/src/include/colors.h @@ -1,3 +1,5 @@ +#include + #ifndef DEF_COLORS_H #define DEF_COLORS_H @@ -19,16 +21,8 @@ #define BOLDCYAN "\033[1m\033[36m" /* Bold Cyan */ #define BOLDWHITE "\033[1m\033[37m" /* Bold White */ -void printf_error(char* string) { - printf(BOLDRED "[ ERROR ]" RESET " %s", string); -} - -void printf_warning(char* string) { - printf(BOLDYELLOW "[WARNING]" RESET " %s", string); -} - -void printf_info(char* string) { - printf(BOLDBLUE "[ INFO ]" RESET " %s", string); -} +void printf_error(char* string); +void printf_warning(char* string); +void printf_info(char* string); #endif \ No newline at end of file diff --git a/src/mnist/include/main.h b/src/mnist/include/main.h index f1d31fa..fb69e8c 100644 --- a/src/mnist/include/main.h +++ b/src/mnist/include/main.h @@ -1,8 +1,6 @@ #ifndef DEF_MAIN_H #define DEF_MAIN_H -#include "../main.c" - /* * Affiche une image ainsi que les prévisions faites par le réseau de neurones sur sa valeur * width, height: dimensions de l'image diff --git a/src/mnist/include/mnist.h b/src/mnist/include/mnist.h index 9b56104..4ececd3 100644 --- a/src/mnist/include/mnist.h +++ b/src/mnist/include/mnist.h @@ -6,7 +6,6 @@ #ifndef DEF_MNIST_H #define DEF_MNIST_H -#include "../mnist.c" uint32_t swap_endian(uint32_t val); diff --git a/src/mnist/include/neural_network.h b/src/mnist/include/neural_network.h index 9941262..c392691 100644 --- a/src/mnist/include/neural_network.h +++ b/src/mnist/include/neural_network.h @@ -10,7 +10,6 @@ #ifndef DEF_NEURAL_NETWORK_H #define DEF_NEURAL_NETWORK_H -#include "../neural_network.c" /* * Fonction max pour les floats diff --git a/src/mnist/include/neuron_io.h b/src/mnist/include/neuron_io.h index 2d7c1b1..27aefff 100644 --- a/src/mnist/include/neuron_io.h +++ b/src/mnist/include/neuron_io.h @@ -8,7 +8,6 @@ #ifndef DEF_NEURON_IO_H #define DEF_NEURON_IO_H -#include "../neuron_io.c" // Lecture d'un réseau neuronal diff --git a/src/mnist/include/preview.h b/src/mnist/include/preview.h index 6156699..c661e39 100644 --- a/src/mnist/include/preview.h +++ b/src/mnist/include/preview.h @@ -6,7 +6,6 @@ #ifndef DEF_PREVIEW_H #define DEF_PREVIEW_H -#include "../preview.c" /* * Affiche un chiffre de taille width x height diff --git a/src/webserver/app.py b/src/webserver/app.py index 8af9be0..8b50735 100644 --- a/src/webserver/app.py +++ b/src/webserver/app.py @@ -38,9 +38,9 @@ def recognize_mnist(image): try: output = subprocess.check_output([ - 'out/mnist_main', + 'build/mnist-main', 'recognize', - '--modele', '.cache/reseau.bin', + '--modele', '.cache/mnist-reseau.bin', '--in', '.cache/image-idx3-ubyte', '--out', 'json' ]).decode("utf-8") diff --git a/test/matrix_multiplication.cu b/test/cnn_matrix_multiplication.cu similarity index 98% rename from test/matrix_multiplication.cu rename to test/cnn_matrix_multiplication.cu index ee45431..e4035ee 100644 --- a/test/matrix_multiplication.cu +++ b/test/cnn_matrix_multiplication.cu @@ -4,7 +4,7 @@ #include #include -#include "../src/cnn/matrix_multiplication.cu" +#include "../src/cnn/include/matrix_multiplication.h" float random_float(float low, float high) { diff --git a/test/cnn_neuron_io.c b/test/cnn_neuron_io.c index 9821295..78be082 100644 --- a/test/cnn_neuron_io.c +++ b/test/cnn_neuron_io.c @@ -3,11 +3,10 @@ #include #include -#include "../src/colors.h" -#include "../src/cnn/neuron_io.c" -#include "../src/cnn/creation.c" -#include "../src/cnn/utils.c" - +#include "../src/include/colors.h" +#include "../src/cnn/include/neuron_io.h" +#include "../src/cnn/include/creation.h" +#include "../src/cnn/include/utils.h" int main() { diff --git a/test/cnn_utils.c b/test/cnn_utils.c index 1783958..d08635a 100644 --- a/test/cnn_utils.c +++ b/test/cnn_utils.c @@ -1,9 +1,9 @@ #include #include -#include "../src/colors.h" -#include "../src/cnn/creation.c" -#include "../src/cnn/utils.c" +#include "../src/include/colors.h" +#include "../src/cnn/include/creation.h" +#include "../src/cnn/include/utils.h" int main() { printf("Création du réseau\n"); diff --git a/test/mnist_utils.sh b/test/mnist_utils.sh index 3c699b2..fed2f21 100755 --- a/test/mnist_utils.sh +++ b/test/mnist_utils.sh @@ -2,21 +2,21 @@ set -e -OUT="$1" -[[ -f "$OUT/mnist_utils" ]] || "$2" build mnist-utils +OUT="build" +[[ -f "$OUT/mnist-utils" ]] || make $OUT/mnist-utils echo "Compte des labels" -"$OUT/mnist_utils" count-labels -l data/mnist/t10k-labels-idx1-ubyte > /dev/null +"$OUT/mnist-utils" count-labels -l data/mnist/t10k-labels-idx1-ubyte > /dev/null echo "OK" echo "Création du réseau" -"$OUT/mnist_utils" creer-reseau -n 3 -o .test-cache/reseau.bin > /dev/null +"$OUT/mnist-utils" creer-reseau -n 3 -o .test-cache/reseau.bin > /dev/null echo "OK" echo "Affichage poids" -"$OUT/mnist_utils" print-poids -r .test-cache/reseau.bin > /dev/null +"$OUT/mnist-utils" print-poids -r .test-cache/reseau.bin > /dev/null echo "OK" echo "Affichage biais" -"$OUT/mnist_utils" print-biais -r .test-cache/reseau.bin > /dev/null -echo "OK" \ No newline at end of file +"$OUT/mnist-utils" print-biais -r .test-cache/reseau.bin > /dev/null +echo "OK"