Merge pull request #3 from augustin64/macos

This commit is contained in:
Augustin 2023-07-12 14:19:57 +02:00 committed by GitHub
commit 588aec2fb8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 116 additions and 71 deletions

View File

@ -1,3 +1,4 @@
OS := $(shell uname)
BUILDDIR := ./build BUILDDIR := ./build
SRCDIR := ./src SRCDIR := ./src
CACHE_DIR := ./.cache CACHE_DIR := ./.cache
@ -27,8 +28,8 @@ TESTS_SRC_CU += $(wildcard $(TEST_SRCDIR)/*.cu)
TESTS_OBJ = $(TESTS_SRC:$(TEST_SRCDIR)/%.c=$(BUILDDIR)/$(TEST_SRCDIR)-%) $(TESTS_SRC_CU:$(TEST_SRCDIR)/%.cu=$(BUILDDIR)/$(TEST_SRCDIR)-%) TESTS_OBJ = $(TESTS_SRC:$(TEST_SRCDIR)/%.c=$(BUILDDIR)/$(TEST_SRCDIR)-%) $(TESTS_SRC_CU:$(TEST_SRCDIR)/%.cu=$(BUILDDIR)/$(TEST_SRCDIR)-%)
# Linker only flags # Linker only flags
LD_CFLAGS = -lm -lpthread -ljpeg -fopenmp LD_CFLAGS = -lm -lpthread -ljpeg
LD_NVCCFLAGS = -ljpeg -Xcompiler -fopenmp LD_NVCCFLAGS = -ljpeg
# Compilation flag # Compilation flag
CFLAGS = -Wall -Wextra -std=gnu99 -g -O3 CFLAGS = -Wall -Wextra -std=gnu99 -g -O3
@ -41,6 +42,13 @@ NVCCFLAGS = -g
# -fsanitize=address -lasan # -fsanitize=address -lasan
#! WARNING: test/cnn-neuron_io fails with this option enabled #! WARNING: test/cnn-neuron_io fails with this option enabled
# Specify library path of libjpeg on MacOS
ifeq ($(OS),Darwin)
LD_CFLAGS += -I/opt/homebrew/Cellar/jpeg/9e/include/ -L/opt/homebrew/Cellar/jpeg/9e/lib/
LD_NVCCFLAGS += -L/opt/homebrew/Cellar/jpeg/9e/lib/
CFLAGS += -I/opt/homebrew/Cellar/jpeg/9e/include/
endif
all: dense cnn; all: dense cnn;

View File

@ -178,17 +178,24 @@ Résultats avec VGG16, pour des images de 256x256 pixels (seulement une plus pet
Sur le cloud avec google Colab: bon GPU mais mauvais processeur: [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/drive/1LfwSrQRaoC91yC9mx9BKHzuc7odev5r6?usp=sharing) Sur le cloud avec google Colab: bon GPU mais mauvais processeur: [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/drive/1LfwSrQRaoC91yC9mx9BKHzuc7odev5r6?usp=sharing)
Les distributions suivantes ont étés essayées, il sera sans doute nécessaire de modifier le code pour l'exécuter sous Windows/ MacOS: ## Dépendances
- `cuda` : pour utiliser la carte graphique (NVIDIA seulement)
- `libjpeg-dev` : n'est pas nécessairement installé par défaut
- GNU `make` : installé par défaut sur la majorité des distributions Linux et sur MacOS
- `gcc` : installé par défaut sur la majorité des distributions Linux et sur MacOS
### Linux
Les distributions suivantes ont étés essayées, il faudra parfois installer `libjpeg`
- Arch - Arch
- Fedora - Fedora
- Manjaro - Manjaro
- Ubuntu - Ubuntu: `apt install libjpeg-dev`
## Dépendances ### MacOS
- `cuda` : pour utiliser la carte graphique (NVIDIA seulement) Avec [Homebrew](https://brew.sh/):
- `libjpeg-dev` : n'est pas installé par défaut sur ubuntu notamment ```bash
- GNU `make` : installé par défaut sur la majorité des distributions brew install libjpeg
- `gcc` : installé par défaut sur la majorité des distributions ```
## Compilation ## Compilation

View File

@ -9,11 +9,6 @@
#include "../common/include/colors.h" #include "../common/include/colors.h"
#include "../common/include/utils.h" #include "../common/include/utils.h"
#include "include/backpropagation.h" #include "include/backpropagation.h"
#include "include/initialisation.h"
#include "include/convolution.h"
#include "include/function.h"
#include "include/creation.h"
#include "include/update.h"
#include "include/make.h" #include "include/make.h"
#include "include/cnn.h" #include "include/cnn.h"

View File

@ -7,12 +7,8 @@
#include "../common/include/colors.h" #include "../common/include/colors.h"
#include "include/initialisation.h"
#include "include/test_network.h" #include "include/test_network.h"
#include "include/function.h"
#include "include/creation.h"
#include "include/train.h" #include "include/train.h"
#include "include/cnn.h"
#include "include/main.h" #include "include/main.h"

View File

@ -7,7 +7,6 @@
#include "../common/include/memory_management.h" #include "../common/include/memory_management.h"
#include "../common/include/mnist.h" #include "../common/include/mnist.h"
#include "include/neuron_io.h" #include "include/neuron_io.h"
#include "include/struct.h"
#include "include/jpeg.h" #include "include/jpeg.h"
#include "include/free.h" #include "include/free.h"
#include "include/cnn.h" #include "include/cnn.h"

View File

@ -1,11 +1,18 @@
#include <sys/sysinfo.h>
#include <pthread.h> #include <pthread.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <float.h> #include <float.h>
#include <math.h> #include <math.h>
#include <time.h> #include <time.h>
#include <omp.h> #include <time.h>
#ifdef __linux__
#include <sys/sysinfo.h>
#elif defined(__APPLE__)
#include <sys/sysctl.h>
#else
#error Unknown platform
#endif
#include "../common/include/memory_management.h" #include "../common/include/memory_management.h"
#include "../common/include/colors.h" #include "../common/include/colors.h"
@ -65,7 +72,7 @@ void* train_thread(void* parameters) {
float loss = 0.; float loss = 0.;
#ifdef DETAILED_TRAIN_TIMINGS #ifdef DETAILED_TRAIN_TIMINGS
double start_time; clock_t start_time;
#endif #endif
pthread_t tid; pthread_t tid;
@ -82,16 +89,16 @@ void* train_thread(void* parameters) {
write_image_in_network_32(images[index[i]], height, width, network->input[0][0], param->offset); write_image_in_network_32(images[index[i]], height, width, network->input[0][0], param->offset);
#ifdef DETAILED_TRAIN_TIMINGS #ifdef DETAILED_TRAIN_TIMINGS
start_time = omp_get_wtime(); start_time = clock();
#endif #endif
forward_propagation(network); forward_propagation(network);
#ifdef DETAILED_TRAIN_TIMINGS #ifdef DETAILED_TRAIN_TIMINGS
printf("Temps de forward: "); printf("Temps de forward: ");
printf_time(omp_get_wtime() - start_time); printf_time(clock() - start_time);
printf("\n"); printf("\n");
start_time = omp_get_wtime(); start_time = clock();
#endif #endif
maxi = indice_max(network->input[network->size-1][0][0], 10); maxi = indice_max(network->input[network->size-1][0][0], 10);
@ -109,9 +116,9 @@ void* train_thread(void* parameters) {
#ifdef DETAILED_TRAIN_TIMINGS #ifdef DETAILED_TRAIN_TIMINGS
printf("Temps de backward: "); printf("Temps de backward: ");
printf_time(omp_get_wtime() - start_time); printf_time(clock() - start_time);
printf("\n"); printf("\n");
start_time = omp_get_wtime(); start_time = clock();
#endif #endif
if (maxi == labels[index[i]]) { if (maxi == labels[index[i]]) {
@ -132,16 +139,16 @@ void* train_thread(void* parameters) {
write_256_image_in_network(param->dataset->images[index[i]], width, height, param->dataset->numComponents, network->width[0], network->input[0]); write_256_image_in_network(param->dataset->images[index[i]], width, height, param->dataset->numComponents, network->width[0], network->input[0]);
#ifdef DETAILED_TRAIN_TIMINGS #ifdef DETAILED_TRAIN_TIMINGS
start_time = omp_get_wtime(); start_time = clock();
#endif #endif
forward_propagation(network); forward_propagation(network);
#ifdef DETAILED_TRAIN_TIMINGS #ifdef DETAILED_TRAIN_TIMINGS
printf("Temps de forward: "); printf("Temps de forward: ");
printf_time(omp_get_wtime() - start_time); printf_time(clock() - start_time);
printf("\n"); printf("\n");
start_time = omp_get_wtime(); start_time = clock();
#endif #endif
maxi = indice_max(network->input[network->size-1][0][0], param->dataset->numCategories); maxi = indice_max(network->input[network->size-1][0][0], param->dataset->numCategories);
@ -149,9 +156,9 @@ void* train_thread(void* parameters) {
#ifdef DETAILED_TRAIN_TIMINGS #ifdef DETAILED_TRAIN_TIMINGS
printf("Temps de backward: "); printf("Temps de backward: ");
printf_time(omp_get_wtime() - start_time); printf_time(clock() - start_time);
printf("\n"); printf("\n");
start_time = omp_get_wtime(); start_time = clock();
#endif #endif
@ -180,7 +187,7 @@ void train(int dataset_type, char* images_file, char* labels_file, char* data_di
exit(1); exit(1);
} }
#endif #endif
srand(time(NULL)); srand(clock());
float loss; float loss;
float batch_loss; // May be redundant with loss, but gives more informations float batch_loss; // May be redundant with loss, but gives more informations
float test_accuracy = 0.; // Used to decrease Learning rate float test_accuracy = 0.; // Used to decrease Learning rate
@ -191,12 +198,12 @@ void train(int dataset_type, char* images_file, char* labels_file, char* data_di
//* Différents timers pour mesurer les performance en terme de vitesse //* Différents timers pour mesurer les performance en terme de vitesse
double start_time, end_time; clock_t start_time, end_time;
double elapsed_time; clock_t elapsed_time;
double algo_start = omp_get_wtime(); clock_t algo_start = clock();
start_time = omp_get_wtime(); start_time = clock();
//* Chargement du dataset //* Chargement du dataset
@ -266,7 +273,17 @@ void train(int dataset_type, char* images_file, char* labels_file, char* data_di
#ifdef USE_MULTITHREADING #ifdef USE_MULTITHREADING
int nb_remaining_images; // Nombre d'images restantes à lancer pour une série de threads int nb_remaining_images; // Nombre d'images restantes à lancer pour une série de threads
// Récupération du nombre de threads disponibles // Récupération du nombre de threads disponibles
int nb_threads = get_nprocs(); #ifdef __linux__
int nb_threads = get_nprocs();
#elif defined(__APPLE__)
int nb_threads;
size_t len = sizeof(nb_threads);
if (sysctlbyname("hw.logicalcpu", &nb_threads, &len, NULL, 0) == -1) {
perror("sysctl");
exit(1);
}
#endif
pthread_t *tid = (pthread_t*)malloc(nb_threads * sizeof(pthread_t)); pthread_t *tid = (pthread_t*)malloc(nb_threads * sizeof(pthread_t));
// Création des paramètres donnés à chaque thread dans le cas du multi-threading // Création des paramètres donnés à chaque thread dans le cas du multi-threading
@ -325,7 +342,7 @@ void train(int dataset_type, char* images_file, char* labels_file, char* data_di
train_params->finetuning = finetuning; train_params->finetuning = finetuning;
#endif #endif
end_time = omp_get_wtime(); end_time = clock();
elapsed_time = end_time - start_time; elapsed_time = end_time - start_time;
printf("Taux d'apprentissage initial: %0.2e\n", network->learning_rate); printf("Taux d'apprentissage initial: %0.2e\n", network->learning_rate);
@ -336,7 +353,7 @@ void train(int dataset_type, char* images_file, char* labels_file, char* data_di
//* Boucle d'apprentissage //* Boucle d'apprentissage
for (int i=0; i < epochs; i++) { for (int i=0; i < epochs; i++) {
start_time = omp_get_wtime(); start_time = clock();
// La variable accuracy permet d'avoir une ESTIMATION // La variable accuracy permet d'avoir une ESTIMATION
// du taux de réussite et de l'entraînement du réseau, // du taux de réussite et de l'entraînement du réseau,
// mais n'est en aucun cas une valeur réelle dans le cas // mais n'est en aucun cas une valeur réelle dans le cas
@ -428,7 +445,7 @@ void train(int dataset_type, char* images_file, char* labels_file, char* data_di
#endif #endif
} }
//* Fin d'une époque: affichage des résultats et sauvegarde du réseau //* Fin d'une époque: affichage des résultats et sauvegarde du réseau
end_time = omp_get_wtime(); end_time = clock();
elapsed_time = end_time - start_time; elapsed_time = end_time - start_time;
#ifdef USE_MULTITHREADING #ifdef USE_MULTITHREADING
printf("\rThreads [%d]\tÉpoque [%d/%d]\tImage [%d/%d]\tAccuracy: " GREEN "%0.4f%%" RESET " \tLoss: %lf\tTemps: ", nb_threads, i, epochs, nb_images_total, nb_images_total, accuracy*100, loss); printf("\rThreads [%d]\tÉpoque [%d/%d]\tImage [%d/%d]\tAccuracy: " GREEN "%0.4f%%" RESET " \tLoss: %lf\tTemps: ", nb_threads, i, epochs, nb_images_total, nb_images_total, accuracy*100, loss);
@ -489,7 +506,7 @@ void train(int dataset_type, char* images_file, char* labels_file, char* data_di
free_dataset(dataset); free_dataset(dataset);
} }
end_time = omp_get_wtime(); end_time = clock();
elapsed_time = end_time - algo_start; elapsed_time = end_time - algo_start;
printf("\nTemps total: "); printf("\nTemps total: ");
printf_time(elapsed_time); printf_time(elapsed_time);

View File

@ -1,5 +1,6 @@
#include <stdio.h> #include <stdio.h>
#include <stdbool.h> #include <stdbool.h>
#include <time.h>
#include "include/colors.h" #include "include/colors.h"
@ -15,11 +16,13 @@ void printf_info(char* string) {
printf(BOLDBLUE "[ INFO ]" RESET " %s", string); printf(BOLDBLUE "[ INFO ]" RESET " %s", string);
} }
void printf_time(float time) { void printf_time(clock_t time) {
int hours = time/3600; double real_time = (double) time / CLOCKS_PER_SEC;
int minutes = ((int)time %3600)/60;
int seconds = ((int)time) %60; int hours = real_time/3600;
int milliseconds = (time - (int)time)*1000; int minutes = ((int)real_time %3600)/60;
int seconds = ((int)real_time) %60;
int milliseconds = (real_time - (int)real_time)*1000;
if (hours != 0) { if (hours != 0) {
printf("%dh %dmn", hours, minutes); printf("%dh %dmn", hours, minutes);

View File

@ -1,4 +1,5 @@
#include <stdio.h> #include <stdio.h>
#include <time.h>
#ifndef DEF_COLORS_H #ifndef DEF_COLORS_H
#define DEF_COLORS_H #define DEF_COLORS_H
@ -51,7 +52,7 @@ extern "C"
/* /*
* Affiche un timing en heures minutes secondes millisecondes en limitant la précision aux deux unités les plus significatives * Affiche un timing en heures minutes secondes millisecondes en limitant la précision aux deux unités les plus significatives
*/ */
void printf_time(float time); void printf_time(clock_t time);
#ifdef __CUDACC__ #ifdef __CUDACC__
extern "C" extern "C"

View File

@ -4,7 +4,14 @@
#include <float.h> #include <float.h>
#include <stdbool.h> #include <stdbool.h>
#include <pthread.h> #include <pthread.h>
#include <sys/sysinfo.h>
#ifdef __linux__
#include <sys/sysinfo.h>
#elif defined(__APPLE__)
#include <sys/sysctl.h>
#else
#error Unknown platform
#endif
#include "include/neural_network.h" #include "include/neural_network.h"
#include "../common/include/colors.h" #include "../common/include/colors.h"
@ -201,7 +208,17 @@ void train(int epochs, char* recovery, char* image_file, char* label_file, char*
float accuracy; float accuracy;
float current_accuracy; float current_accuracy;
int nb_threads = get_nprocs(); #ifdef __linux__
int nb_threads = get_nprocs();
#elif defined(__APPLE__)
int nb_threads;
size_t len = sizeof(nb_threads);
if (sysctlbyname("hw.logicalcpu", &nb_threads, &len, NULL, 0) == -1) {
perror("sysctl");
exit(1);
}
#endif
pthread_t *tid = (pthread_t *)malloc(nb_threads * sizeof(pthread_t)); pthread_t *tid = (pthread_t *)malloc(nb_threads * sizeof(pthread_t));
/* /*

View File

@ -4,7 +4,7 @@
#include <assert.h> #include <assert.h>
#include <math.h> #include <math.h>
#include <time.h> #include <time.h>
#include <omp.h> #include <time.h>
#include "../src/common/include/memory_management.h" #include "../src/common/include/memory_management.h"
#include "../src/cnn/include/convolution.h" #include "../src/cnn/include/convolution.h"
@ -121,21 +121,21 @@ void run_convolution_test(int input_width, int output_width, int rows, int colum
// Lancement des calculs // Lancement des calculs
double start_time, end_time; clock_t start_time, end_time;
double cpu_time_used, gpu_time_used; clock_t cpu_time_used, gpu_time_used;
start_time = omp_get_wtime(); start_time = clock();
make_convolution_device(kernel, input, output_gpu, output_width, 1, 0); make_convolution_device(kernel, input, output_gpu, output_width, 1, 0);
end_time = omp_get_wtime(); end_time = clock();
gpu_time_used = end_time - start_time; gpu_time_used = end_time - start_time;
printf("(%d, %d, %d, %d) Time used for GPU: %lf seconds\n", rows, columns, input_width, output_width, gpu_time_used); printf("(%d, %d, %d, %d) Time used for GPU: %lf seconds\n", rows, columns, input_width, output_width, gpu_time_used);
start_time = omp_get_wtime(); start_time = clock();
make_convolution_cpu(kernel, input, output_cpu, output_width, 1, 0); make_convolution_cpu(kernel, input, output_cpu, output_width, 1, 0);
end_time = omp_get_wtime(); end_time = clock();
cpu_time_used = end_time - start_time; cpu_time_used = end_time - start_time;
printf("(%d, %d, %d, %d) Time used for CPU: %lf seconds\n", rows, columns, input_width, output_width, cpu_time_used); printf("(%d, %d, %d, %d) Time used for CPU: %lf seconds\n", rows, columns, input_width, output_width, cpu_time_used);
@ -169,7 +169,7 @@ int main() {
} }
printf(GREEN "OK\n" RESET); printf(GREEN "OK\n" RESET);
srand(time(NULL)); srand(clock());
run_convolution_test(20, 15, 30, 40); run_convolution_test(20, 15, 30, 40);
run_convolution_test(30, 25, 40, 50); run_convolution_test(30, 25, 40, 50);

View File

@ -1,6 +1,6 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <omp.h> #include <time.h>
#include "../src/common/include/colors.h" #include "../src/common/include/colors.h"
@ -21,10 +21,10 @@ int main(int argc, char* argv[]) {
printf("Taille des images: %dx%d\n", dataset->width, dataset->height); printf("Taille des images: %dx%d\n", dataset->width, dataset->height);
// Calcul du temps de chargement des images une à une // Calcul du temps de chargement des images une à une
double start_time, end_time; clock_t start_time, end_time;
int N = min(100000, dataset->numImages); int N = min(100000, dataset->numImages);
start_time = omp_get_wtime(); start_time = clock();
printf("Chargement de %d images\n", N); printf("Chargement de %d images\n", N);
for (int i=0; i < N; i++) { for (int i=0; i < N; i++) {
imgRawImage* image = loadJpegImageFile(dataset->fileNames[i]); imgRawImage* image = loadJpegImageFile(dataset->fileNames[i]);
@ -32,8 +32,10 @@ int main(int argc, char* argv[]) {
free(image); free(image);
} }
printf("OK\n"); printf("OK\n");
end_time = omp_get_wtime(); end_time = clock();
printf("Temps par image (calculé sur une moyenne de %d): %lf s\n", N, (end_time - start_time)/N); printf("Temps par image (calculé sur une moyenne de %d): ", N);
printf_time((end_time - start_time)/N);
printf("\n");
for (int i=0; i < (int)dataset->numImages; i++) { for (int i=0; i < (int)dataset->numImages; i++) {
if (!dataset->fileNames[i]) { if (!dataset->fileNames[i]) {

View File

@ -3,7 +3,7 @@
#include <stdbool.h> #include <stdbool.h>
#include <math.h> #include <math.h>
#include <time.h> #include <time.h>
#include <omp.h> #include <time.h>
#include "../src/cnn/include/matrix_multiplication.h" #include "../src/cnn/include/matrix_multiplication.h"
#include "../src/common/include/memory_management.h" #include "../src/common/include/memory_management.h"
@ -72,8 +72,8 @@ bool check_matrices_equality(float** m1, float** m2, int n, int p, int acceptati
} }
void run_matrices_test(int n, int p, int q) { void run_matrices_test(int n, int p, int q) {
double start_time, end_time; clock_t start_time, end_time;
double cpu_time_used, gpu_time_used; clock_t cpu_time_used, gpu_time_used;
float** matrix1 = create_matrix(n, p); float** matrix1 = create_matrix(n, p);
float** matrix2 = create_matrix(p, q); float** matrix2 = create_matrix(p, q);
@ -81,16 +81,16 @@ void run_matrices_test(int n, int p, int q) {
float** result_cpu = create_empty_matrix(n, q); float** result_cpu = create_empty_matrix(n, q);
printf("(%d,%d)x(%d,%d) Data generation complete.\n", n, p, p, q); printf("(%d,%d)x(%d,%d) Data generation complete.\n", n, p, p, q);
start_time = omp_get_wtime(); start_time = clock();
matrix_multiplication_device(matrix1, matrix2, result_gpu, n, p, q); matrix_multiplication_device(matrix1, matrix2, result_gpu, n, p, q);
end_time = omp_get_wtime(); end_time = clock();
cpu_time_used = end_time - start_time; cpu_time_used = end_time - start_time;
printf("(%d,%d)x(%d,%d) Time used for GPU: %lf seconds\n", n, p, p, q, cpu_time_used); printf("(%d,%d)x(%d,%d) Time used for GPU: %lf seconds\n", n, p, p, q, cpu_time_used);
start_time = omp_get_wtime(); start_time = clock();
matrix_multiplication_host(matrix1, matrix2, result_cpu, n, p, q); matrix_multiplication_host(matrix1, matrix2, result_cpu, n, p, q);
end_time = omp_get_wtime(); end_time = clock();
gpu_time_used = end_time - start_time; gpu_time_used = end_time - start_time;
printf("(%d,%d)x(%d,%d) Time used for CPU: %lf seconds\n", n, p, p, q, gpu_time_used); printf("(%d,%d)x(%d,%d) Time used for CPU: %lf seconds\n", n, p, p, q, gpu_time_used);
@ -134,7 +134,7 @@ int main() {
} }
printf(GREEN "OK\n" RESET); printf(GREEN "OK\n" RESET);
srand(time(NULL)); srand(clock());
run_matrices_test(200, 1000, 200); run_matrices_test(200, 1000, 200);
run_matrices_test(200, 1000, 20); run_matrices_test(200, 1000, 20);
run_matrices_test(20, 1000, 200); run_matrices_test(20, 1000, 200);