From 227b5053b4c35a76d24e8babaf809fcce1d6ee89 Mon Sep 17 00:00:00 2001 From: violette Date: Wed, 10 Apr 2024 23:29:23 -0400 Subject: [PATCH] makefile + pdf --- CMakeLists.txt | 22 --- Makefile | 31 ++++ README.md | 1 + logo.png | Bin 0 -> 19302 bytes main.pdf | Bin 0 -> 74867 bytes main.typ | 76 +++++++++ src/mpi.c | 340 +++++++++++++++++++++++++++++++++++++++ src/{main.c => openmp.c} | 10 +- 8 files changed, 454 insertions(+), 26 deletions(-) delete mode 100644 CMakeLists.txt create mode 100644 Makefile create mode 100644 logo.png create mode 100644 main.pdf create mode 100644 main.typ create mode 100644 src/mpi.c rename src/{main.c => openmp.c} (96%) diff --git a/CMakeLists.txt b/CMakeLists.txt deleted file mode 100644 index 896abec..0000000 --- a/CMakeLists.txt +++ /dev/null @@ -1,22 +0,0 @@ -cmake_minimum_required(VERSION 3.14) - -project( - ift630_sts3 - VERSION 0.1.0 - DESCRIPTION "bs project to learn openMPI / openMP" - LANGUAGES C -) - -set(src - src/main.c - ) - -set(CMAKE_DEBUG_POSTFIX d) -add_executable(ift630_sts3 ${src}) - -find_package(OpenMP) #make it REQUIRED, if you want -include_directories(SYSTEM ${OpenMP_INCLUDE_PATH}) -target_link_libraries(ift630_sts3 ${OpenMP_C_LIBRARIES}) - -set_target_properties(ift630_sts3 PROPERTIES DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX}) -target_compile_features(ift630_sts3 PRIVATE c_std_99) diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..4190ab7 --- /dev/null +++ b/Makefile @@ -0,0 +1,31 @@ +.PHONY: all omp mpi runmpi runomp + +SRCMPI = src/mpi.c +SRCOMP = src/openmp.c +OJB = $(SRC:.c=.o) +OUT = build + +CC = /usr/bin/gcc +MPICC = /usr/bin/mpicc +MPIRUN = /usr/bin/mpirun +CFLAGS = -ansi -Wall -std=c99 -O3 +OMP = -fopenmp +RM = /bin/rm -fr + +all: mpi openmp + cp ./stop_times.txt build + +runmpi: mpi + cd build ; $(MPIRUN) -np 8 ./mpi + +runomp: omp + cd build ; ./omp + +mpi: + $(MPICC) $(SRCMPI) $(CFLAGS) -o $(OUT)/mpi + +omp: + $(CC) $(SRCOMP) $(OMP) -o $(OUT)/omp + +clean: + $(RM) $(OUT)/* diff --git a/README.md b/README.md index 8a92ccd..9bbea72 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,3 @@ # ift630_sts3 +[see typst doc](./main.pdf) diff --git a/logo.png b/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..6a6f919f43c8ab860e1cdeb703170e675c8e8e8a GIT binary patch literal 19302 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 literal 0 HcmV?d00001 diff --git a/main.pdf b/main.pdf new file mode 100644 index 0000000000000000000000000000000000000000..3c9b380974724d05e70209904aa1854bc60e4237 GIT binary patch literal 74867 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 NM1ba)m}FJt{ug1YyRZNN literal 0 HcmV?d00001 diff --git a/main.typ b/main.typ new file mode 100644 index 0000000..c79c79f --- /dev/null +++ b/main.typ @@ -0,0 +1,76 @@ +#set page( + numbering: "1 / 1", + header: [ + #set text(8pt) + _IFT630 #h(1fr) Violette Paulin_ + ], +) + +#let title(content) = { + pagebreak(weak:true) + set text(size:17pt, weight: "bold") + set align(center) + v(70pt) + [#content] + v(50pt) +} + +#set par( + first-line-indent: 1em, + justify: true, +) + +#title[ + IFT630 - Projet #3 +] + +#show outline.entry.where( + level: 1 +): it => { + v(14pt, weak: false) + strong(it) +} + + +#v(20pt) + +#image("logo.png") + +#align(center)[ + #text(size: 15pt)[ + Violette PAULIN – PAUM1202\ + _Violette.Paulin\@USherbrooke.ca_\ \ + ] +] + +#v(20pt) + +#pagebreak() += Build et test +Une fois le dossier `build` créé, on peut build directement en exécutant +`make all`. Pour tester MPI, `make runmpi`. Pour tester OpenMP, `make runomp`. +Ces commandes créent des fichiers `OutX.txt`. Ceux-ci montrent la clef testée à +gauche, et le temps pour la trouver à droite, séparée par un ':'. + += Performance +Je ne comprends pas la question de mesure de performance. Dans mon cas, mesurer +les performances revient à mesurer la totalité du temps écoulé, ce qui va +comprendre une part non négligeable d'allocation, ainsi que l'overhead des +différentes librairies. Alors que si je mesure le temps moyen pour trouver une +clef, je mesurerais la même chose dans les deux cas. Il m'est donc impossible de +pouvoir tirer une conclusion satisfaisante sur les performances, pour mon +implémentation. J'ai quand même fait le choix de mesurer le temps pour trouver +une clef, sans prendre en compte l'allocation. + +Cependant, OpenMP peut marcher sur tous les cœurs logiques (thread) de ma +machine, alors que MPI ne fonctionne qu'avec les cœurs physiques (il me semble). +Ainsi, on gagne théoriquement en temps global avec OpenMP. + +De plus, je n'ai pas utilisé OpenMP de la manière la plus optimale, faute de +temps. A la place de diviser sur une boucle, je l'ai divisé comme je l'ai fait +pour MPI. Ceci coute plus de temps en allocation, et l'on est contraint à +utiliser plusieurs fichiers + +Dans les deux cas, on s'aperçoit que plus une clef est loin, plus elle est difficile à charger. +C'est le comportement attendu. De plus, les temps semblent être linéaire, ce +qui est encore une fois attendu. diff --git a/src/mpi.c b/src/mpi.c new file mode 100644 index 0000000..3b0e6da --- /dev/null +++ b/src/mpi.c @@ -0,0 +1,340 @@ +#define _XOPEN_SOURCE 700 +#include + +#include +#include +#include +#include +#include + +enum HEADER { + TRIP_ID = 0, + ARRIVAL_TIME, + DEPARTURE_TIME, + STOP_ID, + STOP_SEQUENCE, + STOP_HEADSIGN, + PICKUP_TYPE, + DROP_OFF_TYPE, + SHAPE_DIST_TRAVELED, + TIMEPOINT, + END +}; + +#define DELIM ',' +#define OVERLAP 100 +#define STOP_FILE "./stop_times.txt" + +// adding key here! +int do_map(char *, size_t, char *, int); +void do_reduce(size_t); +int parprocess(MPI_File *, const int, const int, char *); + +int +main(int argc, char **argv) +{ + // Initialize the MPI environment + MPI_Init(NULL, NULL); + + int world_size, world_rank; + MPI_Comm_size(MPI_COMM_WORLD, &world_size); + MPI_Comm_rank(MPI_COMM_WORLD, &world_rank); + + char *key; + if (argc != 2) { + if (world_rank == 0) + printf("no args ; indexing all\n"); + key = NULL; + } + else + key = argv[2]; + + size_t res = 0; + + int number, size; + ssize_t err; + MPI_File in; + + if ((err = MPI_File_open(MPI_COMM_WORLD, STOP_FILE, MPI_MODE_RDONLY, + MPI_INFO_NULL, &in))) { + fprintf(stderr, "%s: Couldn't open file %s\n", argv[0], + STOP_FILE); + exit(-1); + } + MPI_Comm_size(MPI_COMM_WORLD, &size); + + res = parprocess(&in, world_rank, world_size, key); + + if (world_rank == 0) { + for (char k = 0; k < world_size; k++) { + MPI_Recv(&res, 1, MPI_UNSIGNED_LONG, MPI_ANY_SOURCE, 0, + MPI_COMM_WORLD, MPI_STATUS_IGNORE); + if (res) { + //printf("res: found in %lu ns\n", res); break; + } + else + printf("res: not found\n"); + } + } + + MPI_File_close(&in); + MPI_Finalize(); + exit(0); +} + +time_t +substr_time(struct tm a, struct tm b) +{ + return (a.tm_hour * 3600 + a.tm_min * 60 + a.tm_sec) - + (b.tm_hour * 3600 + b.tm_min * 60 + b.tm_sec); +} + +char * +get_word(char *lines, size_t x, size_t y, size_t num_attr, size_t max_attr) +{ + size_t offset = (x * (num_attr * max_attr) + y * (max_attr)); + return lines + offset; +} + +void +fill_lines(char *chunk, size_t num_char, size_t num_lines, size_t num_attr, + size_t max_attr, char *lines) +{ + size_t attr_pos = 0, line_pos = 0, word_pos = 0; + for (size_t k = 0; k < num_char; ++k) { + if (chunk[k] == DELIM) { + // go to next attrib + char *word = get_word(lines, line_pos, attr_pos, + num_attr, max_attr); + memcpy(word, chunk + k - word_pos, word_pos); + word[word_pos] = '\0'; + ++attr_pos; + word_pos = 0; + } + else if (chunk[k] == '\n') { + ++line_pos; + attr_pos = 0; + word_pos = 0; + } + else if (chunk[k] == '\r') {} + else { + ++word_pos; + } + } +} + +void +get_lines_info(char *chunk, size_t num_char, size_t *max_attr_size, + size_t *num_lines) +{ + // count max line size and number of lines + size_t current_attr_size = 0; + for (int k = 0; k < num_char; ++k) { + // LINE + if (chunk[k] == '\n' || chunk[k] == '\r') + ++(*num_lines); + // ATTRIBUTES + if (chunk[k] == DELIM) { + if (current_attr_size > *max_attr_size) + *max_attr_size = current_attr_size; + current_attr_size = 0; + } else + ++current_attr_size; + } +} + +// get num of cols of csv +size_t +get_num_attr(char *chunk) +{ + size_t num_attr = 0; + for (size_t k = 0 ; chunk[k] != '\n' ; ++k) + if (chunk[k] == DELIM) + ++num_attr; + return num_attr; +} + +int +search_key(char *lines, size_t num_lines, size_t num_attr, size_t max_attr, + char *key) +{ + for (size_t k = 0; k < num_lines; ++k) { + if (!strcmp(get_word(lines, k, TRIP_ID, num_attr, max_attr), + key)) + return 1; + } + return 0; +} + +int +get_max_time(char *lines, size_t num_lines, size_t num_attr, size_t max_attr) +{ + struct tm dep_time, arr_time; + time_t max_time = 0; + for (size_t k = 0; k < num_lines; ++k) { + memcpy(&dep_time, + get_word(lines, k, DEPARTURE_TIME, num_attr, max_attr), + sizeof(struct tm)); + memcpy(&arr_time, + get_word(lines, k, ARRIVAL_TIME, num_attr, max_attr), + sizeof(struct tm)); + + strptime(get_word(lines, k, DEPARTURE_TIME, num_attr, max_attr), + "%H:%M:%S", &dep_time); + + strptime(get_word(lines, k, ARRIVAL_TIME, num_attr, max_attr), + "%H:%M:%S", &arr_time); + time_t tmp = substr_time(arr_time, dep_time); + if (tmp > max_time) + max_time = tmp; + } + return max_time; +} + +int +do_map(char *chunk, size_t num_char, char *key, int rank) +{ + size_t num_lines = 0, num_attr = 0; + size_t max_attr_size = 0; + size_t time, res; + + get_lines_info(chunk, num_char, &max_attr_size, &num_lines); + num_attr = get_num_attr(chunk); + + // allocate lines (just a big continuous chunk) + // is a 2d arr of char* + char *lines; + lines = calloc(1, num_lines * num_attr * max_attr_size); + + fill_lines(chunk, num_char, num_lines, num_attr, max_attr_size, lines); + + struct timespec start_time, stop_time; + + // test all ; print all + if (key == NULL) { + char file_name[10]; + + sprintf(file_name, "Out%d.txt", rank); + FILE *file = fopen(file_name, "w"); + for (size_t k = 0; k < num_lines; ++k) { + char *trip_name = get_word(lines, k, TRIP_ID, num_attr, + max_attr_size); + clock_gettime(CLOCK_MONOTONIC, &start_time); + // int res = get_max_time(lines, num_lines, num_attr, + // max_attr_size); + size_t res = search_key(lines, num_lines, num_attr, + max_attr_size, trip_name); + + clock_gettime(CLOCK_MONOTONIC, &stop_time); + + if (!res) + continue; // dont print if err + time = (stop_time.tv_sec - start_time.tv_sec) * + 100000000 + + (stop_time.tv_nsec - start_time.tv_nsec); + fprintf(file, "%s:%lu\n", trip_name, time); + } + fclose(file); + // just so we dont lock + MPI_Send(&time, 1, MPI_UNSIGNED_LONG, 0, 0, MPI_COMM_WORLD); + } else { // search for key + clock_gettime(CLOCK_MONOTONIC, &start_time); + // int res = get_max_time(lines, num_lines, num_attr, + // max_attr_size); + res = search_key(lines, num_lines, num_attr, max_attr_size, + key); + + clock_gettime(CLOCK_MONOTONIC, &stop_time); + + time = (stop_time.tv_sec - start_time.tv_sec) * 100000000 + + (stop_time.tv_nsec - start_time.tv_nsec); + if (res) + MPI_Send(&time, 1, MPI_UNSIGNED_LONG, 0, 0, + MPI_COMM_WORLD); + else + MPI_Send(&res, 1, MPI_UNSIGNED_LONG, 0, 0, + MPI_COMM_WORLD); + } + free(lines); + free(chunk); + return res; +} + +// help from https://stackoverflow.com/questions/12939279/mpi-reading-from-a-text-file +// is hosted under a permissive licence, ty Jonathan Dursi :) +int +parprocess(MPI_File *in, const int rank, const int size, char *key) +{ + // reads revelant lines from file to chunk. + // IN OUR CASE we will use overlap to reach EOF of this line. + // Duplicates dont matter in our case ; res will be the same either way. + size_t proc_size, total_size, total_size_overlap; + char *chunk; + MPI_Offset globalstart; + MPI_Offset globalend; + MPI_Offset filesize; + + MPI_File_get_size(*in, &filesize); + filesize--; /* get rid of text file eof */ + proc_size = filesize / size; + globalstart = rank * proc_size; + globalend = globalstart + proc_size - 1; + if (rank == size - 1) + globalend = filesize - 1; + + /* add overlap to the end of everyone's chunk except last + * proc... */ + size_t globalend_overlap = globalend; + if (rank != size - 1) + globalend_overlap += OVERLAP; + + total_size_overlap = globalend_overlap - globalstart + 1; + total_size = globalend - globalstart + 1; + + /* allocate memory, filled with 0 */ + chunk = calloc(1, total_size); + + ssize_t err; + { + err = MPI_File_read_at_all_begin(*in, globalstart, chunk, + total_size, MPI_CHAR); + if (err) { + printf("error %lu\n", err); + MPI_Finalize(); + } + err = MPI_File_read_at_all_end(*in, chunk, MPI_STATUS_IGNORE); + if (err) { + printf("error %lu\n", err); + MPI_Finalize(); + } + } + + // eh commenting this out, at worst we'll have one unusable line, but this + // still works w/ padding + // fills the first incoherent bytes with \0 + //size_t k = 0; + //if (rank != 0) { // first has no incoherece at begining + // for (; chunk[k] != '\r' && chunk[k] != '\n'; + // ++k) // get number of incoherent bytes :) + // ; + // // reset + + // memmove(chunk, chunk + k, total_size); // - 2: dont count \n\r + //} + + // fill char after next EOL wiht \0 ; starting from proc_size to end of + // overlap + //if (rank != size) { // last doesnt have padding, dont check it + // for (; (chunk[globalend] != '\n' && chunk[globalend] != '\r') && + // globalend < globalend_overlap; + // ++globalend) + // ; + // memset(chunk + globalend, '\0', OVERLAP); + // // + //} + //chunk[total_size_overlap] = '\0'; // just to be sure! + + int max = do_map(chunk, total_size, key, rank); + + return max; +} diff --git a/src/main.c b/src/openmp.c similarity index 96% rename from src/main.c rename to src/openmp.c index a768773..d104d5a 100644 --- a/src/main.c +++ b/src/openmp.c @@ -26,7 +26,7 @@ enum HEADER { #define STOP_FILE "./stop_times.txt" // adding key here! -int do_map(char *, size_t); +int do_map(char *, size_t, int); void do_reduce(size_t); int parprocess(char *, size_t); @@ -169,7 +169,7 @@ get_max_time(char *lines, size_t num_lines, size_t num_attr, size_t max_attr) } int -do_map(char *chunk, size_t num_char) +do_map(char *chunk, size_t num_char, int rank) { size_t num_lines = 0, num_attr = 0; size_t max_attr_size = 0; @@ -188,7 +188,9 @@ do_map(char *chunk, size_t num_char) struct timespec start_time, stop_time; // test all ; print all - char file_name[] = "Out.txt"; + char file_name[] = "OutXX.txt"; + sprintf(file_name, "Out%d.txt", rank); + FILE *file = fopen(file_name, "w"); for (size_t k = 0; k < num_lines; ++k) { @@ -255,7 +257,7 @@ parprocess(char *buff, size_t file_size) memcpy(chunk, buff + start, proc_size); ssize_t err; - int max = do_map(chunk, total_size); + int max = do_map(chunk, total_size, rank); } return 0; }