From 8daac5c06f43e3e5e1110486075e095cd28be90a Mon Sep 17 00:00:00 2001 From: "nicolas.marie" <nicolas.marie@ensiie.eu> Date: Wed, 20 Dec 2023 22:49:48 +0100 Subject: [PATCH] make things readable again --- Projet/CODE/apm/$ | 318 ------------ Projet/CODE/apm/Makefile | 62 ++- Projet/CODE/apm/src/apm.c | 420 ++++++++-------- Projet/CODE/apm/src/apm_gpu.cu | 880 +++++++++++++++++---------------- Projet/CODE/apm/src/apm_omp.c | 427 ++++++++-------- 5 files changed, 924 insertions(+), 1183 deletions(-) delete mode 100644 Projet/CODE/apm/$ diff --git a/Projet/CODE/apm/$ b/Projet/CODE/apm/$ deleted file mode 100644 index f2ff57b..0000000 --- a/Projet/CODE/apm/$ +++ /dev/null @@ -1,318 +0,0 @@ -/** - * APPROXIMATE PATTERN MATCHING - * - * INF560 X2016 - */ -#include <string.h> -#include <stdio.h> -#include <stdlib.h> -#include <fcntl.h> -#include <unistd.h> -#include <sys/time.h> - -#define APM_DEBUG 0 - -char * read_input_file(char * filename, int * size) -{ - char * buf; - off_t fsize; - int fd = 0; - int n_bytes = 1; - - /* Open the text file */ - fd = open(filename, O_RDONLY); - if (fd == -1) - { - fprintf(stderr, "Unable to open the text file <%s>\n", filename); - return NULL; - } - - /* Get the number of characters in the textfile */ - fsize = lseek(fd, 0, SEEK_END); - lseek(fd, 0, SEEK_SET); - /* TODO check return of lseek */ - -#if APM_DEBUG - printf("File length: %lld\n", fsize); -#endif - - /* Allocate data to copy the target text */ - buf = (char *)malloc(fsize * sizeof (char)); - if (buf == NULL) - { - fprintf(stderr, "Unable to allocate %ld byte(s) for main array\n", - fsize); - return NULL; - } - - n_bytes = read(fd, buf, fsize); - if (n_bytes != fsize) - { - fprintf(stderr, - "Unable to copy %ld byte(s) from text file (%d byte(s) copied)\n", - fsize, n_bytes); - return NULL; - } - -#if APM_DEBUG - printf("Number of read bytes: %d\n", n_bytes); -#endif - - *size = n_bytes; - close(fd); - return buf; -} - -#define MIN3(a, b, c) ((a)<(b) ? ((a)<(c) ? (a) : (c)) : ((b)<(c) ? (b) : (c))) - -int levenshtein(char *s1, char *s2, int len, int * column, int approx_factor) -{ - int x, y, lastdiag, olddiag; - - for (y = 1; y <= len; y++) - { - column[y] = y; - } - for (x = 1; x <= len; x++) - { - column[0] = x; - lastdiag = x-1; - for (y = 1; y <= len; y++) - { - olddiag = column[y]; - column[y] = MIN3(column[y] + 1, - column[y-1] + 1, - lastdiag + (s1[y-1] == s2[x-1] ? 0 : 1)); - lastdiag = olddiag; - } - } - return (column[len] <= approx_factor) ? 1 : 0; -} - -__global__ void levenshtein_cu(char *find, char *buf, int len, int n_bytes - ,int approx_factor, int* g_column, int* result_vec) -{ - int tId = blockIdx.x * blockDim.x + threadIdx.x;//global thread id - if (tId > n_bytes) - {return;}//we are past the buffer length - do not process - - //position s2 and column to the right position in the pre-allocated - //arrays - char* s2 = buf+tId; - int* column = g_column+tId*(len+1); - - //i do not understand this algorithm and god do i not want to. - int x, y, lastdiag, olddiag; - - for (y = 1; y <= len; y++) - { - column[y] = y; - } - for (x = 1; x <= len; x++) - { - column[0] = x; - lastdiag = x-1; - for (y = 1; y <= len; y++) - { - olddiag = column[y]; - column[y] = MIN3(column[y] + 1, - column[y-1] + 1, - lastdiag + (find[y-1] == s2[x-1] ? 0 : 1)); - lastdiag = olddiag; - } - } - - if (column[len] <= approx_factor) - {result_vec[tId] = 1;}//its a match -} - -int main(int argc, char ** argv) -{ - char ** pattern; - char * filename; - int approx_factor = 0; - int nb_patterns = 0; - - char * buf; - struct timeval t1, t2; - double duration; - int n_bytes; - int * n_matches; - - //cuda-related vars - char *buf_dev; - int NTBB = 1024; //Number of threads by blocks - int NB;//Number of blocks - cudaError_t cu_err; - - /* Check number of arguments */ - if (argc < 4) - { - printf("Usage: %s approximation_factor " - "dna_database pattern1 pattern2 ...\n", - argv[0]); - return 1; - } - - approx_factor = atoi(argv[1]);/* Get the distance factor */ - filename = argv[2];/* Grab the filename containing the target text */ - nb_patterns = argc - 3;/* Get the number of patterns to search for */ - - pattern = (char **)malloc(nb_patterns * sizeof(char*)); - if (pattern == NULL)/*Fill the pattern*/ - { - fprintf(stderr, - "Unable to allocate array of pattern of size %d\n", - nb_patterns); - return 1; - } - - for (int i=0; i < nb_patterns; i++) /* Grab the patterns */ - { - int l; - l = strlen(argv[i+3]); - - if (l <= 0) - { - fprintf(stderr, "Error while parsing argument %d\n", i+3); - return 1; - } - - pattern[i] = (char *)malloc((l+1) * sizeof(char)); - if (pattern[i] == NULL) - { - fprintf(stderr, "Unable to allocate string of size %d\n", l); - return 1; - } - - strncpy(pattern[i], argv[i+3], (l+1)); - } - - - printf("Approximate Pattern Mathing: " - "looking for %d pattern(s) in file %s w/ distance of %d\n", - nb_patterns, filename, approx_factor); - - buf = read_input_file(filename, &n_bytes); - if (buf == NULL) - { - fprintf(stderr, "Error: NULL pointer from reading input file."); - return 1; - } - - cudaMalloc((void**)&buf_dev, n_bytes * sizeof(char)); - if ((cu_err = cudaGetLastError()) != cudaSuccess) - { - fprintf(stderr, "Unable to allocate buffer on device: %s.\n" - , cudaGetErrorString(cu_err)); - return ; - } - - cudaMemcpy(NULL, buf, n_bytes, cudaMemcpyHostToDevice); - if ((cu_err = cudaGetLastError()) != cudaSuccess) - { - fprintf(stderr, "Unable to copy buffer onto device: %s.\n" - , cudaGetErrorString(cu_err)); - return ; - } - - - n_matches = (int *)malloc(nb_patterns * sizeof(int));/*Alloc the matches*/ - if (n_matches == NULL) - { - fprintf(stderr, "Error: unable to allocate memory for %ldB\n", - nb_patterns * sizeof(int)); - return 1; - } - - /***** - * BEGIN MAIN LOOP - ******/ - - /* Timer start */ - gettimeofday(&t1, NULL); - - for (int i = 0; i < nb_patterns; i++) - { - n_matches[i] = 0; - - //TODO err check - int size_pattern = strlen(pattern[i]); - char* pattern_dev; - cudaMalloc((void**)&pattern_dev, size_pattern); - - cudaMemcpy(pattern_dev, pattern[i] - , size_pattern, cudaMemcpyHostToDevice); - - NB = (n_bytes / NTBB) + (((n_bytes % NTBB) > 0) ? 1 : 0); - //printf("n_bytes : %i, NB : %i ; nb_threads : %i\n" - // , n_bytes, NB, NB*NTBB); - - //TODO err check - int * column_dev; - cudaMalloc((void**)&column_dev, (size_pattern+1)*NTBB*NB*sizeof(int)); - - - - //TODO err check - int * result_vec_dev; //result vectors. - cudaMalloc((void**)&result_vec_dev, NTBB*NB*sizeof(int)); - - int * result_vec =(int*) malloc(NTBB*NB*sizeof(int)); - memset(result_vec, 0, NTBB*NB*sizeof(int)); - - cudaMemcpy(result_vec_dev, result_vec - , NTBB*NB, cudaMemcpyHostToDevice); - - - - levenshtein_cu<<<NB,NTBB>>>(pattern_dev, buf_dev, size_pattern - , n_bytes, approx_factor, column_dev, result_vec_dev); - - //get result - cudaMemcpy(result_vec, result_vec_dev - , NTBB*NB*sizeof(int), cudaMemcpyDeviceToHost); - - for (int j = 0 ; j<n_bytes ; j++) - { - /* Highly advanced debbugging (printfs) - int column[size_pattern+1]; - int d = - levenshtein(pattern[i], buf+j, size_pattern, column, approx_factor); - //printf("%d",d); - if (d != result_vec[j]) - { - printf("MISMATCH FOUND %s should have match at %i :" - ,pattern[i], j); - printf("%.*s\n",size_pattern,&buf[j]); - } - */ - n_matches[i] += result_vec[j]; - } - - //free memory - and then get onto the next pattern. - cudaFree(pattern_dev); - cudaFree(column_dev); - cudaFree(result_vec_dev); - free(result_vec); - } - - /* Timer stop */ - gettimeofday(&t2, NULL); - - duration = (t2.tv_sec -t1.tv_sec)+((t2.tv_usec-t1.tv_usec)/1e6); - - printf("APM done in %lf s\n", duration); - - /***** - * END MAIN LOOP - ******/ - - for (int i=0; i < nb_patterns; i++) - { - printf("Number of matches for pattern <%s>: %d\n", - pattern[i], n_matches[i]); - } - - return 0; -} diff --git a/Projet/CODE/apm/Makefile b/Projet/CODE/apm/Makefile index 41bb027..0273c75 100644 --- a/Projet/CODE/apm/Makefile +++ b/Projet/CODE/apm/Makefile @@ -1,34 +1,64 @@ INCLUDED=include CC=gcc +NVCC=nvcc CFLAGS=-O3 -I $(INCLUDED) -pg -g -Wall CFLAGS_OMP= -fopenmp -DUSE_OMP $(CFLAGS) CFLAGS_CU=-O3 -Xcompiler "$(CFLAGS)" LDFLAGS= -OBJ=obj/apm.o - .PHONY: all -all: dir apm apm_omp apm_gpu - -dir: - mkdir -p obj - -obj/apm_omp.o : src/apm_omp.c - $(CC) $(CFLAGS_OMP) -c -o $@ $^ +all: + $(MAKE) apm + $(MAKE) apm_omp + $(MAKE) apm_gpu -obj/%.o: src/%.c - $(CC) $(CFLAGS) -c -o $@ $^ - -apm: obj/apm.o +apm: src/apm.c $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ -apm_omp: obj/apm_omp.o +apm_omp: src/apm_omp.c $(CC) $(CFLAGS_OMP) $(LDFLAGS) -o $@ $^ apm_gpu: src/apm_gpu.cu - nvcc $(CFLAGS_CU) $(LDFLAGS) -o $@ $^ + $(NVCC) $(CFLAGS_CU) $(LDFLAGS) -o $@ $^ .PHONY: clean clean: - rm -rf apm apm_omp apm_gpu obj/ *.out + rm -rf apm apm_omp apm_gpu + +.PHONY: style +style: + astyle src/*.c src/*.cu \ + --style=allman \ + --indent=tab=4 \ + --indent-switches \ + --indent-cases \ + --indent-after-parens \ + --indent-continuation=2 \ + --indent-labels \ + --indent-preproc-block \ + --indent-preproc-define \ + --min-conditional-indent=1 \ + --max-continuation-indent=80 \ + --break-blocks \ + --pad-oper \ + --pad-comma \ + --pad-header \ + --unpad-paren \ + --unpad-brackets \ + --delete-empty-lines \ + --squeeze-lines=4 \ + --squeeze-ws \ + --align-pointer=name \ + --align-reference=name \ + --break-one-line-headers \ + --add-braces \ + --break-return-type \ + --max-code-length=80 \ + --suffix=none +# --style=kr / google / mozilla / webkit +# + + + + diff --git a/Projet/CODE/apm/src/apm.c b/Projet/CODE/apm/src/apm.c index f1bde78..ff45f73 100644 --- a/Projet/CODE/apm/src/apm.c +++ b/Projet/CODE/apm/src/apm.c @@ -12,230 +12,234 @@ #define APM_DEBUG 0 -char * read_input_file(char * filename, int * size) +char * +read_input_file(char *filename, int *size) { - char * buf; - off_t fsize; - int fd = 0; - int n_bytes = 1; - - /* Open the text file */ - fd = open(filename, O_RDONLY); - if (fd == -1) - { - fprintf(stderr, "Unable to open the text file <%s>\n", filename); - return NULL; - } - - /* Get the number of characters in the textfile */ - fsize = lseek(fd, 0, SEEK_END); - lseek(fd, 0, SEEK_SET); - /* TODO check return of lseek */ - + char *buf; + off_t fsize; + int fd = 0; + int n_bytes = 1; + /* Open the text file */ + fd = open(filename, O_RDONLY); + + if (fd == -1) + { + fprintf(stderr, "Unable to open the text file <%s>\n", filename); + return NULL; + } + + /* Get the number of characters in the textfile */ + fsize = lseek(fd, 0, SEEK_END); + lseek(fd, 0, SEEK_SET); + /* TODO check return of lseek */ #if APM_DEBUG - printf("File length: %lld\n", fsize); + printf("File length: %lld\n", fsize); #endif - - /* Allocate data to copy the target text */ - buf = (char *)malloc(fsize * sizeof (char)); - if (buf == NULL) - { - fprintf(stderr, "Unable to allocate %ld byte(s) for main array\n", - fsize); - return NULL; - } - - n_bytes = read(fd, buf, fsize); - if (n_bytes != fsize) - { - fprintf(stderr, - "Unable to copy %ld byte(s) from text file (%d byte(s) copied)\n", - fsize, n_bytes); - return NULL; - } + /* Allocate data to copy the target text */ + buf = (char *)malloc(fsize * sizeof(char)); + + if (buf == NULL) + { + fprintf(stderr, "Unable to allocate %ld byte(s) for main array\n", + fsize); + return NULL; + } + + n_bytes = read(fd, buf, fsize); + + if (n_bytes != fsize) + { + fprintf(stderr, + "Unable to copy %ld byte(s) from text file " + "(%d byte(s) copied)\n", + fsize, n_bytes); + return NULL; + } #if APM_DEBUG - printf("Number of read bytes: %d\n", n_bytes); + printf("Number of read bytes: %d\n", n_bytes); #endif - - *size = n_bytes; - close(fd); - return buf; + *size = n_bytes; + close(fd); + return buf; } #define MIN3(a, b, c) ((a)<(b) ? ((a)<(c) ? (a) : (c)) : ((b)<(c) ? (b) : (c))) -int levenshtein(char *s1, char *s2, int len, int * column) +int +levenshtein(char *s1, char *s2, int len, int *column) { - unsigned int x, y, lastdiag, olddiag; - - for (y = 1; y <= len; y++) - { - column[y] = y; - } - for (x = 1; x <= len; x++) - { - column[0] = x; - lastdiag = x-1; - for (y = 1; y <= len; y++) - { - olddiag = column[y]; - column[y] = MIN3(column[y] + 1, - column[y-1] + 1, - lastdiag + (s1[y-1] == s2[x-1] ? 0 : 1)); - lastdiag = olddiag; - } - } - return(column[len]); + unsigned int x, y, lastdiag, olddiag; + + for (y = 1; y <= len; y++) + { + column[y] = y; + } + + for (x = 1; x <= len; x++) + { + column[0] = x; + lastdiag = x - 1; + + for (y = 1; y <= len; y++) + { + olddiag = column[y]; + column[y] = MIN3(column[y] + 1, + column[y - 1] + 1, + lastdiag + (s1[y - 1] == s2[x - 1] ? 0 : 1)); + lastdiag = olddiag; + } + } + + return (column[len]); } -int main(int argc, char ** argv) +int +main(int argc, char **argv) { - char ** pattern; - char * filename; - int approx_factor = 0; - int nb_patterns = 0; - int i, j; - char * buf; - struct timeval t1, t2; - double duration; - int n_bytes; - int * n_matches; - - /* Check number of arguments */ - if (argc < 4) - { - printf("Usage: %s approximation_factor " - "dna_database pattern1 pattern2 ...\n", - argv[0]); - return 1; - } - - approx_factor = atoi(argv[1]);/* Get the distance factor */ - filename = argv[2];/* Grab the filename containing the target text */ - nb_patterns = argc - 3;/* Get the number of patterns to search for */ - - pattern = (char **)malloc(nb_patterns * sizeof(char*)); - if (pattern == NULL)/*Fill the pattern*/ - { - fprintf(stderr, - "Unable to allocate array of pattern of size %d\n", - nb_patterns); - return 1; - } - - for (i=0; i < nb_patterns; i++) /* Grab the patterns */ - { - int l; - l = strlen(argv[i+3]); - - if (l <= 0) - { - fprintf(stderr, "Error while parsing argument %d\n", i+3); - return 1; - } - - pattern[i] = (char *)malloc((l+1) * sizeof(char)); - if (pattern[i] == NULL) - { - fprintf(stderr, "Unable to allocate string of size %d\n", l); - return 1; - } - - strncpy(pattern[i], argv[i+3], (l+1)); - } - - - printf("Approximate Pattern Mathing: " - "looking for %d pattern(s) in file %s w/ distance of %d\n", - nb_patterns, filename, approx_factor); - - buf = read_input_file(filename, &n_bytes); - if (buf == NULL) - { - fprintf(stderr, "Error: NULL pointer from reading input file."); - return 1; - } - - n_matches = (int *)malloc(nb_patterns * sizeof(int));/*Alloc the matches*/ - if (n_matches == NULL) - { - fprintf(stderr, "Error: unable to allocate memory for %ldB\n", - nb_patterns * sizeof(int)); - return 1; - } - - /***** - * BEGIN MAIN LOOP - ******/ - - /* Timer start */ - gettimeofday(&t1, NULL); - - for (i = 0; i < nb_patterns; i++) - { - int size_pattern = strlen(pattern[i]); - int * column; - - n_matches[i] = 0; - - column = (int *)malloc((size_pattern+1) * sizeof(int)); - if (column == NULL) - { - fprintf(stderr, - "Error: unable to allocate memory for column (%ldB)\n", - (size_pattern+1) * sizeof(int)); - return 1; - } - - for (j = 0; j < n_bytes; j++) - { - int distance = 0; - int size; - + char **pattern; + char *filename; + int approx_factor = 0; + int nb_patterns = 0; + int i, j; + char *buf; + struct timeval t1, t2; + double duration; + int n_bytes; + int *n_matches; + + /* Check number of arguments */ + if (argc < 4) + { + printf("Usage: %s approximation_factor " + "dna_database pattern1 pattern2 ...\n", + argv[0]); + return 1; + } + + approx_factor = atoi(argv[1]);/* Get the distance factor */ + filename = argv[2];/* Grab the filename containing the target text */ + nb_patterns = argc - 3;/* Get the number of patterns to search for */ + pattern = (char **)malloc(nb_patterns * sizeof(char *)); + + if (pattern == NULL)/*Fill the pattern*/ + { + fprintf(stderr, + "Unable to allocate array of pattern of size %d\n", + nb_patterns); + return 1; + } + + for (i = 0; i < nb_patterns; i++) /* Grab the patterns */ + { + int l; + l = strlen(argv[i + 3]); + + if (l <= 0) + { + fprintf(stderr, "Error while parsing argument %d\n", i + 3); + return 1; + } + + pattern[i] = (char *)malloc((l + 1) * sizeof(char)); + + if (pattern[i] == NULL) + { + fprintf(stderr, "Unable to allocate string of size %d\n", l); + return 1; + } + + strncpy(pattern[i], argv[i + 3], (l + 1)); + } + + printf("Approximate Pattern Mathing: " + "looking for %d pattern(s) in file %s w/ distance of %d\n", + nb_patterns, filename, approx_factor); + buf = read_input_file(filename, &n_bytes); + + if (buf == NULL) + { + fprintf(stderr, "Error: NULL pointer from reading input file."); + return 1; + } + + n_matches = (int *)malloc(nb_patterns * sizeof(int));/*Alloc the matches*/ + + if (n_matches == NULL) + { + fprintf(stderr, "Error: unable to allocate memory for %ldB\n", + nb_patterns * sizeof(int)); + return 1; + } + + /***** + * BEGIN MAIN LOOP + ******/ + /* Timer start */ + gettimeofday(&t1, NULL); + + for (i = 0; i < nb_patterns; i++) + { + int size_pattern = strlen(pattern[i]); + int *column; + n_matches[i] = 0; + column = (int *)malloc((size_pattern + 1) * sizeof(int)); + + if (column == NULL) + { + fprintf(stderr, + "Error: unable to allocate memory for column (%ldB)\n", + (size_pattern + 1) * sizeof(int)); + return 1; + } + + for (j = 0; j < n_bytes; j++) + { + int distance = 0; + int size; #if APM_DEBUG - if (j % 100 == 0) - { - printf("Procesing byte %d (out of %d)\n", j, n_bytes); - } -#endif - - size = size_pattern; - if (n_bytes - j < size_pattern) - { - //size = n_bytes - j; - //NO ! we do not want to match substring of our input, wth - break; - } - - distance = levenshtein(pattern[i], &buf[j], size, column); - if (distance <= approx_factor) - { - n_matches[i]++; - } - } + if (j % 100 == 0) + { + printf("Procesing byte %d (out of %d)\n", j, n_bytes); + } - free(column); - } - - /* Timer stop */ - gettimeofday(&t2, NULL); - - duration = (t2.tv_sec -t1.tv_sec)+((t2.tv_usec-t1.tv_usec)/1e6); - - printf("APM done in %lf s\n", duration); - - /***** - * END MAIN LOOP - ******/ - - for (i = 0; i < nb_patterns; i++) - { - printf("Number of matches for pattern <%s>: %d\n", - pattern[i], n_matches[i]); - } - - return 0; +#endif + size = size_pattern; + + if (n_bytes - j < size_pattern) + { + //size = n_bytes - j; + //NO ! we do not want to match substring of our input, wth + break; + } + + distance = levenshtein(pattern[i], &buf[j], size, column); + + if (distance <= approx_factor) + { + n_matches[i]++; + } + } + + free(column); + } + + /* Timer stop */ + gettimeofday(&t2, NULL); + duration = (t2.tv_sec - t1.tv_sec) + ((t2.tv_usec - t1.tv_usec) / 1e6); + printf("APM done in %lf s\n", duration); + + /***** + * END MAIN LOOP + ******/ + + for (i = 0; i < nb_patterns; i++) + { + printf("Number of matches for pattern <%s>: %d\n", + pattern[i], n_matches[i]); + } + + return 0; } diff --git a/Projet/CODE/apm/src/apm_gpu.cu b/Projet/CODE/apm/src/apm_gpu.cu index ab42d36..efbdb48 100644 --- a/Projet/CODE/apm/src/apm_gpu.cu +++ b/Projet/CODE/apm/src/apm_gpu.cu @@ -18,491 +18,511 @@ //the amount of RAM used by the programm is approx~Â 30*MAX_BUFFER_SIZE. //If you get out of memory errors, you should reduce this value -char * read_input_file(char * filename, int * size) +char * +read_input_file(char *filename, int *size) { - char * buf; - off_t fsize; - int fd = 0; - int n_bytes = 1; - - /* Open the text file */ - fd = open(filename, O_RDONLY); - if (fd == -1) - { - fprintf(stderr, "Unable to open the text file <%s>\n", filename); - return NULL; - } - - /* Get the number of characters in the textfile */ - fsize = lseek(fd, 0, SEEK_END); - lseek(fd, 0, SEEK_SET); - /* TODO check return of lseek */ - - #if APM_DEBUG - printf("File length: %lld\n", fsize); - #endif - - /* Allocate data to copy the target text */ - buf = (char *)malloc(fsize * sizeof (char)); - if (buf == NULL) - { - fprintf(stderr, "Unable to allocate %ld byte(s) for main array\n", - fsize); - return NULL; - } - - n_bytes = read(fd, buf, fsize); - if (n_bytes != fsize) - { - fprintf(stderr, - "Unable to copy %ld byte(s) from text file (%d byte(s) copied)\n", - fsize, n_bytes); - return NULL; - } - - #if APM_DEBUG - printf("Number of read bytes: %d\n", n_bytes); - #endif - - *size = n_bytes; - close(fd); - return buf; + char *buf; + off_t fsize; + int fd = 0; + int n_bytes = 1; + /* Open the text file */ + fd = open(filename, O_RDONLY); + + if (fd == -1) + { + fprintf(stderr, "Unable to open the text file <%s>\n", filename); + return NULL; + } + + /* Get the number of characters in the textfile */ + fsize = lseek(fd, 0, SEEK_END); + lseek(fd, 0, SEEK_SET); + /* TODO check return of lseek */ +#if APM_DEBUG + printf("File length: %lld\n", fsize); +#endif + /* Allocate data to copy the target text */ + buf = (char *)malloc(fsize * sizeof(char)); + + if (buf == NULL) + { + fprintf(stderr, "Unable to allocate %ld byte(s) for main array\n", + fsize); + return NULL; + } + + n_bytes = read(fd, buf, fsize); + + if (n_bytes != fsize) + { + fprintf(stderr, + "Unable to copy %ld byte(s) from text file " + "(%d byte(s) copied)\n", + fsize, n_bytes); + return NULL; + } + +#if APM_DEBUG + printf("Number of read bytes: %d\n", n_bytes); +#endif + *size = n_bytes; + close(fd); + return buf; } -off_t get_file_size(int fd) +off_t +get_file_size(int fd) { off_t size; size = lseek(fd, 0, SEEK_END); lseek(fd, 0, SEEK_SET); return size; -} -char * read_input_file_max(int fd, int * size - , int pattern_len, off_t offset) +} +char * +read_input_file_max(int fd, int *size + , int pattern_len, off_t offset) { - char * buf; - off_t fsize; - int n_bytes = 1; - int to_read; - - fsize = lseek(fd, 0, SEEK_END); - to_read = - ((fsize - offset) > MAX_BUFFER_SIZE) ? MAX_BUFFER_SIZE : (fsize-offset); - lseek(fd, offset, SEEK_SET); - - #if APM_DEBUG - printf("File length: %lld\n", fsize); - printf("diff: %i\n", to_read); - #endif - - /* Allocate data to copy the target text */ - buf = (char *)malloc(fsize * sizeof (char)); - if (buf == NULL) - { - fprintf(stderr, "Unable to allocate %ld byte(s) for main array\n", - fsize); - return NULL; - } - - n_bytes = read(fd, buf, to_read); - if (n_bytes != to_read) - { - fprintf(stderr, - "Unable to copy %ld byte(s) from text file (%d byte(s) copied)\n", - fsize, n_bytes); - return NULL; - } - - #if APM_DEBUG - printf("Number of read bytes: %d\n", n_bytes); - #endif - - *size = n_bytes; - return buf; + char *buf; + off_t fsize; + int n_bytes = 1; + int to_read; + fsize = lseek(fd, 0, SEEK_END); + to_read = + ((fsize - offset) > MAX_BUFFER_SIZE) + ? MAX_BUFFER_SIZE : (fsize - offset); + lseek(fd, offset, SEEK_SET); +#if APM_DEBUG + printf("File length: %lld\n", fsize); + printf("diff: %i\n", to_read); +#endif + /* Allocate data to copy the target text */ + buf = (char *)malloc(fsize * sizeof(char)); + + if (buf == NULL) + { + fprintf(stderr, "Unable to allocate %ld byte(s) for main array\n", + fsize); + return NULL; + } + + n_bytes = read(fd, buf, to_read); + + if (n_bytes != to_read) + { + fprintf(stderr, + "Unable to copy %ld byte(s) from text file " + "(%d byte(s) copied)\n", + fsize, n_bytes); + return NULL; + } + +#if APM_DEBUG + printf("Number of read bytes: %d\n", n_bytes); +#endif + *size = n_bytes; + return buf; } #define MIN3(a, b, c) ((a)<(b) ? ((a)<(c) ? (a) : (c)) : ((b)<(c) ? (b) : (c))) -int levenshtein(char *s1, char *s2, int len, int * column, int approx_factor) +int +levenshtein(char *s1, char *s2, int len, int *column, int approx_factor) { - int x, y, lastdiag, olddiag; - - for (y = 1; y <= len; y++) - { - column[y] = y; - } - for (x = 1; x <= len; x++) - { - column[0] = x; - lastdiag = x-1; - for (y = 1; y <= len; y++) - { - olddiag = column[y]; - column[y] = MIN3(column[y] + 1, - column[y-1] + 1, - lastdiag + (s1[y-1] == s2[x-1] ? 0 : 1)); - lastdiag = olddiag; - } - } - return (column[len] <= approx_factor) ? 1 : 0; + int x, y, lastdiag, olddiag; + + for (y = 1; y <= len; y++) + { + column[y] = y; + } + + for (x = 1; x <= len; x++) + { + column[0] = x; + lastdiag = x - 1; + + for (y = 1; y <= len; y++) + { + olddiag = column[y]; + column[y] = MIN3(column[y] + 1, + column[y - 1] + 1, + lastdiag + (s1[y - 1] == s2[x - 1] ? 0 : 1)); + lastdiag = olddiag; + } + } + + return (column[len] <= approx_factor) ? 1 : 0; } -__global__ void levenshtein_cu(char *find, char *buf, int len, int n_bytes - ,int approx_factor, int* g_column, int* result) -{ - int tId = blockIdx.x * blockDim.x + threadIdx.x;//global thread id - if (tId > n_bytes) - {return;}//we are past the buffer length - do not process - - //position s2 and column to the right position in the pre-allocated - //arrays - char* s2 = buf+tId; - int* column = g_column+tId*(len+1); - - //i do not understand this algorithm and god do i not want to. - int x, y, lastdiag, olddiag; - - for (y = 1; y <= len; y++) - { - column[y] = y; - } - for (x = 1; x <= len; x++) - { - column[0] = x; - lastdiag = x-1; - for (y = 1; y <= len; y++) - { - olddiag = column[y]; - column[y] = MIN3(column[y] + 1, - column[y-1] + 1, - lastdiag + (find[y-1] == s2[x-1] ? 0 : 1)); - lastdiag = olddiag; - } - } - - int res = 0; - if (column[len] <= approx_factor) - res = 1; - //{result_vec[tId] = 1;}//its a match - - atomicAdd(result, res); -} - -int main(int argc, char ** argv) +__global__ void +levenshtein_cu(char *find, char *buf, int len, int n_bytes + , int approx_factor, int *g_column, int *result) { - char ** pattern; - char * filename; - int fdesc; - off_t filesize; - int approx_factor = 0; - int nb_patterns = 0; - - char * buf; - struct timeval t1, t2; - double duration; - int n_bytes; - int * n_matches; - - //cuda-related vars - char *buf_dev; - int NTBB = NUMBER_THREADS_BY_BLOCK; //Number of threads by blocks - int NB = 0;//Number of blocks - cudaError_t cu_err; - - /* Check number of arguments */ - if (argc < 4) - { - printf("Usage: %s approximation_factor " - "dna_database pattern1 pattern2 ...\n", - argv[0]); - return 1; - } - - approx_factor = atoi(argv[1]);/* Get the distance factor */ - filename = argv[2];/* Grab the filename containing the target text */ - - /* Open the text file */ - fdesc = open(filename, O_RDONLY); - if (fdesc == -1) - { - fprintf(stderr, "Unable to open the text file <%s>\n", filename); - return 1; - } - - filesize = get_file_size(fdesc); - if (filesize == 0) + int tId = blockIdx.x * blockDim.x + threadIdx.x;//global thread id + + if (tId > n_bytes) + { + return; //we are past the buffer length - do not process + } + + //position s2 and column to the right position in the pre-allocated + //arrays + char *s2 = buf + tId; + int *column = g_column + tId * (len + 1); + //i do not understand this algorithm and god do i not want to. + int x, y, lastdiag, olddiag; + + for (y = 1; y <= len; y++) + { + column[y] = y; + } + + for (x = 1; x <= len; x++) + { + column[0] = x; + lastdiag = x - 1; + + for (y = 1; y <= len; y++) { - fprintf(stderr, "File <%s> is empty !\n", filename); - return 1; - } - - nb_patterns = argc - 3;/* Get the number of patterns to search for */ - - pattern = (char **)malloc(nb_patterns * sizeof(char*)); - if (pattern == NULL)/*Fill the pattern*/ - { - fprintf(stderr, - "Unable to allocate array of pattern of size %d\n", - nb_patterns); - return 1; - } - - for (int i=0; i < nb_patterns; i++) /* Grab the patterns */ - { - int l; - l = strlen(argv[i+3]); - - if (l <= 0) - { - fprintf(stderr, "Error while parsing argument %d\n", i+3); - return 1; - } - - pattern[i] = (char *)malloc((l+1) * sizeof(char)); - if (pattern[i] == NULL) - { - fprintf(stderr, "Unable to allocate string of size %d\n", l); - return 1; - } - - strncpy(pattern[i], argv[i+3], (l+1)); - } - - - printf("Approximate Pattern Mathing: " - "looking for %d pattern(s) in file %s w/ distance of %d\n", - nb_patterns, filename, approx_factor); - - - - n_matches = (int *)malloc(nb_patterns * sizeof(int));/*Alloc the matches*/ - if (n_matches == NULL) - { - fprintf(stderr, "Error: unable to allocate memory for %ldB\n", - nb_patterns * sizeof(int)); - return 1; - } - - /***** - * BEGIN MAIN LOOP - ******/ - - /* Timer start */ - //TODO MAYBE count time with cudaevents (see older tp) - gettimeofday(&t1, NULL); - - for (int i = 0; i < nb_patterns; i++) - { - n_matches[i] = 0; - - int size_pattern = strlen(pattern[i]); - char* pattern_dev; - - cudaMalloc((void**)&pattern_dev, size_pattern); - if ((cu_err = cudaGetLastError()) != cudaSuccess) + olddiag = column[y]; + column[y] = MIN3(column[y] + 1, + column[y - 1] + 1, + lastdiag + (find[y - 1] == s2[x - 1] ? 0 : 1)); + lastdiag = olddiag; + } + } + + int res = 0; + + if (column[len] <= approx_factor) + { + res = 1; + } + + //{result_vec[tId] = 1;}//its a match + atomicAdd(result, res); +} + +int +main(int argc, char **argv) +{ + char **pattern; + char *filename; + int fdesc; + off_t filesize; + int approx_factor = 0; + int nb_patterns = 0; + char *buf; + struct timeval t1, t2; + double duration; + int n_bytes; + int *n_matches; + //cuda-related vars + char *buf_dev; + int NTBB = NUMBER_THREADS_BY_BLOCK; //Number of threads by blocks + int NB = 0;//Number of blocks + cudaError_t cu_err; + + /* Check number of arguments */ + if (argc < 4) + { + printf("Usage: %s approximation_factor " + "dna_database pattern1 pattern2 ...\n", + argv[0]); + return 1; + } + + approx_factor = atoi(argv[1]);/* Get the distance factor */ + filename = argv[2];/* Grab the filename containing the target text */ + /* Open the text file */ + fdesc = open(filename, O_RDONLY); + + if (fdesc == -1) + { + fprintf(stderr, "Unable to open the text file <%s>\n", filename); + return 1; + } + + filesize = get_file_size(fdesc); + + if (filesize == 0) + { + fprintf(stderr, "File <%s> is empty !\n", filename); + return 1; + } + + nb_patterns = argc - 3;/* Get the number of patterns to search for */ + pattern = (char **)malloc(nb_patterns * sizeof(char *)); + + if (pattern == NULL)/*Fill the pattern*/ + { + fprintf(stderr, + "Unable to allocate array of pattern of size %d\n", + nb_patterns); + return 1; + } + + for (int i = 0; i < nb_patterns; i++) /* Grab the patterns */ + { + int l; + l = strlen(argv[i + 3]); + + if (l <= 0) + { + fprintf(stderr, "Error while parsing argument %d\n", i + 3); + return 1; + } + + pattern[i] = (char *)malloc((l + 1) * sizeof(char)); + + if (pattern[i] == NULL) + { + fprintf(stderr, "Unable to allocate string of size %d\n", l); + return 1; + } + + strncpy(pattern[i], argv[i + 3], (l + 1)); + } + + printf("Approximate Pattern Mathing: " + "looking for %d pattern(s) in file %s w/ distance of %d\n", + nb_patterns, filename, approx_factor); + n_matches = (int *)malloc(nb_patterns * sizeof(int));/*Alloc the matches*/ + + if (n_matches == NULL) + { + fprintf(stderr, "Error: unable to allocate memory for %ldB\n", + nb_patterns * sizeof(int)); + return 1; + } + + /***** + * BEGIN MAIN LOOP + ******/ + /* Timer start */ + //TODO MAYBE count time with cudaevents (see older tp) + gettimeofday(&t1, NULL); + + for (int i = 0; i < nb_patterns; i++) + { + n_matches[i] = 0; + int size_pattern = strlen(pattern[i]); + char *pattern_dev; + cudaMalloc((void **)&pattern_dev, size_pattern); + + if ((cu_err = cudaGetLastError()) != cudaSuccess) + { + fprintf(stderr, "Unable to allocate pattern on device: %s.\n", + cudaGetErrorString(cu_err)); + return 1; + } + + cudaMemcpy(pattern_dev, pattern[i], + size_pattern, cudaMemcpyHostToDevice); + + if ((cu_err = cudaGetLastError()) != cudaSuccess) + { + fprintf(stderr, "Unable to copy pattern onto device: %s.\n", + cudaGetErrorString(cu_err)); + return 1; + } + + int result = 0; + int *result_dev; + cudaMalloc((void **)&result_dev, sizeof(int)); + + if ((cu_err = cudaGetLastError()) != cudaSuccess) + { + fprintf(stderr, "Unable to allocate result on device: %s.\n", + cudaGetErrorString(cu_err)); + return 1; + } + + off_t offset = 0; + + while (offset < filesize) + { +#if APM_DEBUG + printf("offset: %i, filesize: %i\n", offset, filesize); +#endif + buf = read_input_file_max(fdesc, &n_bytes, size_pattern, offset); + + if (buf == NULL) { - fprintf(stderr, "Unable to allocate pattern on device: %s.\n" - , cudaGetErrorString(cu_err)); + fprintf(stderr, "Error: NULL pointer from reading input file."); return 1; } - - cudaMemcpy(pattern_dev, pattern[i] - , size_pattern, cudaMemcpyHostToDevice); + + cudaMalloc((void **)&buf_dev, n_bytes * sizeof(char)); + if ((cu_err = cudaGetLastError()) != cudaSuccess) { - fprintf(stderr, "Unable to copy pattern onto device: %s.\n" - , cudaGetErrorString(cu_err)); + fprintf(stderr, "Unable to allocate buffer on device: %s.\n", + cudaGetErrorString(cu_err)); return 1; } - - int result = 0; - int* result_dev; - cudaMalloc((void**)&result_dev, sizeof(int)); + + cudaMemcpy(buf_dev, buf, n_bytes, cudaMemcpyHostToDevice); + if ((cu_err = cudaGetLastError()) != cudaSuccess) { - fprintf(stderr, "Unable to allocate result on device: %s.\n" - , cudaGetErrorString(cu_err)); + fprintf(stderr, "Unable to copy buffer onto device: %s.\n", + cudaGetErrorString(cu_err)); return 1; } + NB = (n_bytes / NTBB) + (((n_bytes % NTBB) > 0) ? 1 : 0); + int *column_dev; + cudaMalloc((void **)&column_dev, + (size_pattern + 1)*NTBB * NB * sizeof(int)); - off_t offset = 0; - while (offset < filesize) - { - #if APM_DEBUG - printf("offset: %i, filesize: %i\n",offset,filesize); - #endif + if ((cu_err = cudaGetLastError()) != cudaSuccess) + { + fprintf(stderr, + "Unable to allocate column vector on device: %s.\n", + cudaGetErrorString(cu_err)); + return 1; + } - buf = read_input_file_max(fdesc, &n_bytes, size_pattern, offset); - if (buf == NULL) - { - fprintf(stderr, "Error: NULL pointer from reading input file."); - return 1; - } + char *result_vec_dev; //result vectors. + cudaMalloc((void **)&result_vec_dev, NTBB * NB * sizeof(char)); - cudaMalloc((void**)&buf_dev, n_bytes * sizeof(char)); - if ((cu_err = cudaGetLastError()) != cudaSuccess) - { - fprintf(stderr, "Unable to allocate buffer on device: %s.\n" - , cudaGetErrorString(cu_err)); - return 1; - } + if ((cu_err = cudaGetLastError()) != cudaSuccess) + { + fprintf(stderr, + "Unable to allocate result vector on device: %s.\n", + cudaGetErrorString(cu_err)); + return 1; + } - cudaMemcpy(buf_dev, buf, n_bytes, cudaMemcpyHostToDevice); - if ((cu_err = cudaGetLastError()) != cudaSuccess) - { - fprintf(stderr, "Unable to copy buffer onto device: %s.\n" - , cudaGetErrorString(cu_err)); - return 1; - } + char *result_vec = (char *) malloc(NTBB * NB * sizeof(char)); + if (result_vec == NULL) + { + fprintf(stderr, "Unable to allocate result vec on host."); + return 1; + } - NB = (n_bytes / NTBB) + (((n_bytes % NTBB) > 0) ? 1 : 0); - + /* + cudaMemset(result_vec_dev, 0, NTBB*NB*sizeof(char)); + if ((cu_err = cudaGetLastError()) != cudaSuccess) + { + fprintf(stderr, "Unable to init result vector to 0 on device: %s.\n" + , cudaGetErrorString(cu_err)); + return 1; + } - int * column_dev; - cudaMalloc((void**)&column_dev - , (size_pattern+1)*NTBB*NB*sizeof(int)); - if ((cu_err = cudaGetLastError()) != cudaSuccess) - { - fprintf(stderr, "Unable to allocate column vector on device: %s.\n" + cudaMemset(result_dev, 0, sizeof(int)); + if ((cu_err = cudaGetLastError()) != cudaSuccess) + { + fprintf(stderr, "Unable to init result to 0 on device: %s.\n" , cudaGetErrorString(cu_err)); - return 1; - } - - char * result_vec_dev; //result vectors. - cudaMalloc((void**)&result_vec_dev, NTBB*NB*sizeof(char)); - if ((cu_err = cudaGetLastError()) != cudaSuccess) - { - fprintf(stderr, "Unable to allocate result vector on device: %s.\n" - , cudaGetErrorString(cu_err)); - return 1; - } - - char* result_vec =(char*) malloc(NTBB*NB*sizeof(char)); - if (result_vec == NULL) - { - fprintf(stderr, "Unable to allocate result vec on host."); - return 1; - } - - /* - cudaMemset(result_vec_dev, 0, NTBB*NB*sizeof(char)); - if ((cu_err = cudaGetLastError()) != cudaSuccess) - { - fprintf(stderr, "Unable to init result vector to 0 on device: %s.\n" - , cudaGetErrorString(cu_err)); - return 1; - } - - cudaMemset(result_dev, 0, sizeof(int)); - if ((cu_err = cudaGetLastError()) != cudaSuccess) - { - fprintf(stderr, "Unable to init result to 0 on device: %s.\n" - , cudaGetErrorString(cu_err)); - return 1; - } - */ + return 1; + } + */ + levenshtein_cu <<< NB, NTBB>>>(pattern_dev, buf_dev, size_pattern, + n_bytes, approx_factor, column_dev, result_dev); - levenshtein_cu<<<NB,NTBB>>>(pattern_dev, buf_dev, size_pattern - , n_bytes, approx_factor, column_dev, result_dev); - if ((cu_err = cudaGetLastError()) != cudaSuccess) - { - fprintf(stderr, "Kernel execution of levenshtein_cu failed: %s.\n" - , cudaGetErrorString(cu_err)); - return 1; - } - - //get result - cudaMemcpy(&result, result_dev - , sizeof(int), cudaMemcpyDeviceToHost); - if ((cu_err = cudaGetLastError()) != cudaSuccess) - { - fprintf(stderr, "Unable to retrieve result on host: %s.\n" - , cudaGetErrorString(cu_err)); - return 1; - } - - n_matches[i] += result; + if ((cu_err = cudaGetLastError()) != cudaSuccess) + { + fprintf(stderr, + "Kernel execution of levenshtein_cu failed: %s.\n", + cudaGetErrorString(cu_err)); + return 1; + } - /* - for (int j = 0 ; j<n_bytes ; j++) - { - // Highly advanced debbugging (printfs) - int column[size_pattern+1]; - int d = - levenshtein(pattern[i], buf+j, size_pattern, column - , approx_factor); - //printf("%d",d); - if (d != result_vec[j]) - { - printf("MISMATCH FOUND %s should have match at %i :" - ,pattern[i], j); - printf("%.*s\n",size_pattern,&buf[j]); - } - - n_matches[i] += result_vec[j]; - } - */ - - offset += (MAX_BUFFER_SIZE - size_pattern + 1); + //get result + cudaMemcpy(&result, result_dev, + sizeof(int), cudaMemcpyDeviceToHost); - cudaFree(buf_dev); - if ((cu_err = cudaGetLastError()) != cudaSuccess) - { - fprintf(stderr, "Unable to free memory for dev on device: %s.\n" - , cudaGetErrorString(cu_err)); - return 1; - } - free(buf); - - cudaFree(column_dev); - if ((cu_err = cudaGetLastError()) != cudaSuccess) - { - fprintf(stderr, "Unable to free memory for column on device: %s.\n" - , cudaGetErrorString(cu_err)); - return 1; - } - - /* - cudaFree(result_vec_dev); - if ((cu_err = cudaGetLastError()) != cudaSuccess) + if ((cu_err = cudaGetLastError()) != cudaSuccess) + { + fprintf(stderr, "Unable to retrieve result on host: %s.\n", + cudaGetErrorString(cu_err)); + return 1; + } + + n_matches[i] += result; + /* + for (int j = 0 ; j<n_bytes ; j++) + { + // Highly advanced debbugging (printfs) + int column[size_pattern+1]; + int d = + levenshtein(pattern[i], buf+j, size_pattern, column + , approx_factor); + //printf("%d",d); + if (d != result_vec[j]) { - fprintf(stderr, "Unable to free memory for result on device: %s.\n" - , cudaGetErrorString(cu_err)); - return 1; + printf("MISMATCH FOUND %s should have match at %i :" + ,pattern[i], j); + printf("%.*s\n",size_pattern,&buf[j]); } - free(result_vec); - */ + n_matches[i] += result_vec[j]; } + */ + offset += (MAX_BUFFER_SIZE - size_pattern + 1); + cudaFree(buf_dev); - //free memory - and then get onto the next pattern. - cudaFree(pattern_dev); if ((cu_err = cudaGetLastError()) != cudaSuccess) { - fprintf(stderr, "Unable to free memory for pattern on device: %s.\n" - , cudaGetErrorString(cu_err)); + fprintf(stderr, + "Unable to free memory for dev on device: %s.\n", + cudaGetErrorString(cu_err)); return 1; } - } - /* Timer stop */ - gettimeofday(&t2, NULL); + free(buf); + cudaFree(column_dev); - duration = (t2.tv_sec -t1.tv_sec)+((t2.tv_usec-t1.tv_usec)/1e6); + if ((cu_err = cudaGetLastError()) != cudaSuccess) + { + fprintf(stderr, + "Unable to free memory for column on device: %s.\n", + cudaGetErrorString(cu_err)); + return 1; + } - printf("APM done in %lf s\n", duration); + /* + cudaFree(result_vec_dev); + if ((cu_err = cudaGetLastError()) != cudaSuccess) + { + fprintf(stderr, "Unable to free memory for result on device: %s.\n" + , cudaGetErrorString(cu_err)); + return 1; + } - /***** - * END MAIN LOOP - ******/ + free(result_vec); + */ + } - for (int i=0; i < nb_patterns; i++) - { - printf("Number of matches for pattern <%s>: %d\n", - pattern[i], n_matches[i]); - } + //free memory - and then get onto the next pattern. + cudaFree(pattern_dev); - return 0; + if ((cu_err = cudaGetLastError()) != cudaSuccess) + { + fprintf(stderr, + "Unable to free memory for pattern on device: %s.\n", + cudaGetErrorString(cu_err)); + return 1; + } + } + + /* Timer stop */ + gettimeofday(&t2, NULL); + duration = (t2.tv_sec - t1.tv_sec) + ((t2.tv_usec - t1.tv_usec) / 1e6); + printf("APM done in %lf s\n", duration); + + /***** + * END MAIN LOOP + ******/ + + for (int i = 0; i < nb_patterns; i++) + { + printf("Number of matches for pattern <%s>: %d\n", + pattern[i], n_matches[i]); + } + + return 0; } diff --git a/Projet/CODE/apm/src/apm_omp.c b/Projet/CODE/apm/src/apm_omp.c index 853c628..c0d595c 100644 --- a/Projet/CODE/apm/src/apm_omp.c +++ b/Projet/CODE/apm/src/apm_omp.c @@ -14,238 +14,243 @@ #define APM_DEBUG 0 -char * read_input_file(char * filename, int * size) +char * +read_input_file(char *filename, int *size) { - char * buf; - off_t fsize; - int fd = 0; - int n_bytes = 1; - - /* Open the text file */ - fd = open(filename, O_RDONLY); - if (fd == -1) - { - fprintf(stderr, "Unable to open the text file <%s>\n", filename); - return NULL; - } - - /* Get the number of characters in the textfile */ - fsize = lseek(fd, 0, SEEK_END); - lseek(fd, 0, SEEK_SET); - /* TODO check return of lseek */ - + char *buf; + off_t fsize; + int fd = 0; + int n_bytes = 1; + /* Open the text file */ + fd = open(filename, O_RDONLY); + + if (fd == -1) + { + fprintf(stderr, "Unable to open the text file <%s>\n", filename); + return NULL; + } + + /* Get the number of characters in the textfile */ + fsize = lseek(fd, 0, SEEK_END); + lseek(fd, 0, SEEK_SET); + /* TODO check return of lseek */ #if APM_DEBUG - printf("File length: %lld\n", fsize); + printf("File length: %lld\n", fsize); #endif - - /* Allocate data to copy the target text */ - buf = (char *)malloc(fsize * sizeof (char)); - if (buf == NULL) - { - fprintf(stderr, "Unable to allocate %ld byte(s) for main array\n", - fsize); - return NULL; - } - - n_bytes = read(fd, buf, fsize); - if (n_bytes != fsize) - { - fprintf(stderr, - "Unable to copy %ld byte(s) from text file (%d byte(s) copied)\n", - fsize, n_bytes); - return NULL; - } + /* Allocate data to copy the target text */ + buf = (char *)malloc(fsize * sizeof(char)); + + if (buf == NULL) + { + fprintf(stderr, "Unable to allocate %ld byte(s) for main array\n", + fsize); + return NULL; + } + + n_bytes = read(fd, buf, fsize); + + if (n_bytes != fsize) + { + fprintf(stderr, + "Unable to copy %ld byte(s) from text file " + "(%d byte(s) copied)\n", + fsize, n_bytes); + return NULL; + } #if APM_DEBUG - printf("Number of read bytes: %d\n", n_bytes); + printf("Number of read bytes: %d\n", n_bytes); #endif - - *size = n_bytes; - close(fd); - return buf; + *size = n_bytes; + close(fd); + return buf; } #define MIN3(a, b, c) ((a)<(b) ? ((a)<(c) ? (a) : (c)) : ((b)<(c) ? (b) : (c))) -int levenshtein(char *s1, char *s2, int len, int * column) +int +levenshtein(char *s1, char *s2, int len, int *column) { - unsigned int x, y, lastdiag, olddiag; - - for (y = 1; y <= len; y++) - { - column[y] = y; - } - for (x = 1; x <= len; x++) - { - column[0] = x; - lastdiag = x-1; - for (y = 1; y <= len; y++) - { - olddiag = column[y]; - column[y] = MIN3(column[y] + 1, - column[y-1] + 1, - lastdiag + (s1[y-1] == s2[x-1] ? 0 : 1)); - lastdiag = olddiag; - } - } - return(column[len]); -} + unsigned int x, y, lastdiag, olddiag; + for (y = 1; y <= len; y++) + { + column[y] = y; + } -int main(int argc, char ** argv) -{ - char ** pattern; - char * filename; - int approx_factor = 0; - int nb_patterns = 0; - int i, j; - char * buf; - struct timeval t1, t2; - double duration; - int n_bytes; - int * n_matches; - int num_threads; - - /* Check number of arguments */ - if (argc < 4) - { - printf("Usage: %s approximation_factor " - "dna_database pattern1 pattern2 ...\n", - argv[0]); - return 1; - } - - approx_factor = atoi(argv[1]);/* Get the distance factor */ - filename = argv[2];/* Grab the filename containing the target text */ - nb_patterns = argc - 3;/* Get the number of patterns to search for */ - - pattern = (char **)malloc(nb_patterns * sizeof(char*)); - if (pattern == NULL)/*Fill the pattern*/ - { - fprintf(stderr, - "Unable to allocate array of pattern of size %d\n", - nb_patterns); - return 1; - } - - for (i=0; i < nb_patterns; i++) /* Grab the patterns */ - { - int l; - l = strlen(argv[i+3]); - - if (l <= 0) - { - fprintf(stderr, "Error while parsing argument %d\n", i+3); - return 1; - } - - pattern[i] = (char *)malloc((l+1) * sizeof(char)); - if (pattern[i] == NULL) - { - fprintf(stderr, "Unable to allocate string of size %d\n", l); - return 1; - } - - strncpy(pattern[i], argv[i+3], (l+1)); - } - - - printf("Approximate Pattern Mathing: " - "looking for %d pattern(s) in file %s w/ distance of %d\n", - nb_patterns, filename, approx_factor); - - buf = read_input_file(filename, &n_bytes); - if (buf == NULL) - { - fprintf(stderr, "Error: NULL pointer from reading input file."); - return 1; - } - - n_matches = (int *)malloc(nb_patterns * sizeof(int));/*Alloc the matches*/ - if (n_matches == NULL) - { - fprintf(stderr, "Error: unable to allocate memory for %ldB\n", - nb_patterns * sizeof(int)); - return 1; - } - - #pragma omp parallel - { - num_threads = omp_get_num_threads(); - } - - /***** - * BEGIN MAIN LOOP - ******/ - - /* Timer start */ - gettimeofday(&t1, NULL); - - for (i = 0; i < nb_patterns; i++) - { - int size_pattern = strlen(pattern[i]); - int * column; - int distance = 0; - - n_matches[i] = 0; - - column = (int *)malloc((size_pattern+1) * num_threads * sizeof(int)); - if (column == NULL) - { - fprintf(stderr, - "Error: unable to allocate memory for column (%ldB)\n", - (size_pattern+1) * sizeof(int) * n_bytes); - return 1; - } - - int matches = 0; - #pragma omp parallel for reduction(+:matches) private(distance) - for (j = 0; j < n_bytes; j++) - { - -#if APM_DEBUG - if (j % 100 == 0) - { - printf("Procesing byte %d (out of %d)\n", j, n_bytes); - } -#endif + for (x = 1; x <= len; x++) + { + column[0] = x; + lastdiag = x - 1; - if (n_bytes - j < size_pattern) - { - //size = n_bytes - j; - //NO ! we do not want to match substring of our input, wth - continue; - } + for (y = 1; y <= len; y++) + { + olddiag = column[y]; + column[y] = MIN3(column[y] + 1, + column[y - 1] + 1, + lastdiag + (s1[y - 1] == s2[x - 1] ? 0 : 1)); + lastdiag = olddiag; + } + } + + return (column[len]); +} - distance = levenshtein(pattern[i], &buf[j], size_pattern, - column+(omp_get_thread_num()*(size_pattern+1))); - if (distance <= approx_factor) - { - matches++; - } - } +int +main(int argc, char **argv) +{ + char **pattern; + char *filename; + int approx_factor = 0; + int nb_patterns = 0; + int i, j; + char *buf; + struct timeval t1, t2; + double duration; + int n_bytes; + int *n_matches; + int num_threads; + + /* Check number of arguments */ + if (argc < 4) + { + printf("Usage: %s approximation_factor " + "dna_database pattern1 pattern2 ...\n", + argv[0]); + return 1; + } + + approx_factor = atoi(argv[1]);/* Get the distance factor */ + filename = argv[2];/* Grab the filename containing the target text */ + nb_patterns = argc - 3;/* Get the number of patterns to search for */ + pattern = (char **)malloc(nb_patterns * sizeof(char *)); + + if (pattern == NULL)/*Fill the pattern*/ + { + fprintf(stderr, + "Unable to allocate array of pattern of size %d\n", + nb_patterns); + return 1; + } + + for (i = 0; i < nb_patterns; i++) /* Grab the patterns */ + { + int l; + l = strlen(argv[i + 3]); + + if (l <= 0) + { + fprintf(stderr, "Error while parsing argument %d\n", i + 3); + return 1; + } - n_matches[i] = matches; - free(column); - } + pattern[i] = (char *)malloc((l + 1) * sizeof(char)); - /* Timer stop */ - gettimeofday(&t2, NULL); + if (pattern[i] == NULL) + { + fprintf(stderr, "Unable to allocate string of size %d\n", l); + return 1; + } + + strncpy(pattern[i], argv[i + 3], (l + 1)); + } + + printf("Approximate Pattern Mathing: " + "looking for %d pattern(s) in file %s w/ distance of %d\n", + nb_patterns, filename, approx_factor); + buf = read_input_file(filename, &n_bytes); + + if (buf == NULL) + { + fprintf(stderr, "Error: NULL pointer from reading input file."); + return 1; + } + + n_matches = (int *)malloc(nb_patterns * sizeof(int));/*Alloc the matches*/ + + if (n_matches == NULL) + { + fprintf(stderr, "Error: unable to allocate memory for %ldB\n", + nb_patterns * sizeof(int)); + return 1; + } + + #pragma omp parallel + { + num_threads = omp_get_num_threads(); + } + /***** + * BEGIN MAIN LOOP + ******/ + /* Timer start */ + gettimeofday(&t1, NULL); + + for (i = 0; i < nb_patterns; i++) + { + int size_pattern = strlen(pattern[i]); + int *column; + int distance = 0; + n_matches[i] = 0; + column = (int *)malloc((size_pattern + 1) * num_threads * sizeof(int)); + + if (column == NULL) + { + fprintf(stderr, + "Error: unable to allocate memory for column (%ldB)\n", + (size_pattern + 1) * sizeof(int) * n_bytes); + return 1; + } - duration = (t2.tv_sec -t1.tv_sec)+((t2.tv_usec-t1.tv_usec)/1e6); + int matches = 0; + #pragma omp parallel for reduction(+:matches) private(distance) - printf("APM done in %lf s\n", duration); + for (j = 0; j < n_bytes; j++) + { +#if APM_DEBUG - /***** - * END MAIN LOOP - ******/ + if (j % 100 == 0) + { + printf("Procesing byte %d (out of %d)\n", j, n_bytes); + } - for (i = 0; i < nb_patterns; i++) - { - printf("Number of matches for pattern <%s>: %d\n", - pattern[i], n_matches[i]); - } +#endif - return 0; + if (n_bytes - j < size_pattern) + { + //size = n_bytes - j; + //NO ! we do not want to match substring of our input, wth + continue; + } + + distance = levenshtein(pattern[i], &buf[j], size_pattern, + column + (omp_get_thread_num() * (size_pattern + 1)) + ); + + if (distance <= approx_factor) + { + matches++; + } + } + + n_matches[i] = matches; + free(column); + } + + /* Timer stop */ + gettimeofday(&t2, NULL); + duration = (t2.tv_sec - t1.tv_sec) + ((t2.tv_usec - t1.tv_usec) / 1e6); + printf("APM done in %lf s\n", duration); + + /***** + * END MAIN LOOP + ******/ + + for (i = 0; i < nb_patterns; i++) + { + printf("Number of matches for pattern <%s>: %d\n", + pattern[i], n_matches[i]); + } + + return 0; } -- GitLab