diff --git a/main.c b/main.c index 398942f..b2e0abe 100644 --- a/main.c +++ b/main.c @@ -2,24 +2,159 @@ #include #include "kmp.h" #include "util.h" +#include +#include +#define MASTER 0 +#define DEFAULT_TAG 17 + +char *read_text(); + +char *read_pattern(); + +void find_end(int, char *, char *, int **, int *); + +void apply_shift(int, int *, int); + +int sum_array(int *, int); int main() { - char *patter = "acabacacd"; - char *text = "acfacabacabacacdac"; + int rank, size, private_text_len, text_len, pattern_len; + char *pattern, *text; - int pattern_len = strlen(patter); + MPI_Init(NULL, NULL); + + MPI_Comm_size(MPI_COMM_WORLD, &size); + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + + if (rank == MASTER) { + text = read_text(); + pattern = read_pattern(); + printf("text: %s\n", text); + printf("pattern: %s\n", pattern); + text_len = strlen(text); + pattern_len = strlen(pattern); + private_text_len = text_len / size; // TODO: size non divisibile + } + + MPI_Bcast(&private_text_len, 1, MPI_INT, MASTER, MPI_COMM_WORLD); + + char *private_text = (char *) malloc(sizeof(char) * (private_text_len + 1)); + + MPI_Scatter(text, private_text_len, MPI_CHAR, private_text, private_text_len, MPI_CHAR, MASTER, MPI_COMM_WORLD); + private_text[private_text_len] = '\0'; + + printf("%d -> input: %s\n", rank, private_text); + + MPI_Bcast(&pattern_len, 1, MPI_INT, MASTER, MPI_COMM_WORLD); + + if (rank != MASTER) { + pattern = (char *) malloc(sizeof(char) * (pattern_len + 1)); + } + + MPI_Bcast(pattern, pattern_len + 1, MPI_CHAR, MASTER, MPI_COMM_WORLD); - // long proper suffix array int lps[pattern_len]; - create_lps(patter, pattern_len, lps); + create_lps(pattern, pattern_len, lps); - int match_number = 0; - int residue; + int match_number = 0, residue; + int *matches = search_pattern(private_text, pattern, lps, &match_number, &residue); - int *matches = search_pattern(text, patter, lps, &match_number, &residue); - print_array(matches, match_number); - printf("%d\n", residue); + if (rank + 1 != size) { + MPI_Send(&residue, 1, MPI_INT, rank + 1, DEFAULT_TAG, MPI_COMM_WORLD); + } + + if (rank != 0) { + MPI_Recv(&residue, 1, MPI_INT, rank - 1, DEFAULT_TAG, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + if (residue != 0) + find_end(residue, pattern, private_text, &matches, &match_number); + } + + int shift = rank * private_text_len; + apply_shift(shift, matches, match_number); + + printf("%d -> result number: %d\n", rank, match_number); + + if (rank == MASTER) { + int match_numbers[size]; + match_numbers[MASTER] = match_number; + + for (int i = 0; i < size; ++i) { + if (i == MASTER) continue; + + MPI_Recv(match_numbers + i, 1, MPI_INT, i, DEFAULT_TAG, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + } + + match_number = sum_array(match_numbers, size); + matches = (int *) realloc(matches, sizeof(int) * match_number); + + int offset = 0; + for (int i = 0; i < size; ++i) { + if (i == MASTER) { + offset += match_numbers[i]; + continue; + } + + MPI_Recv(matches + offset, match_numbers[i], MPI_INT, i, DEFAULT_TAG, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + offset += match_numbers[i]; + } + } else { + MPI_Send(&match_number, 1, MPI_INT, MASTER, DEFAULT_TAG, MPI_COMM_WORLD); + MPI_Send(matches, match_number, MPI_INT, MASTER, DEFAULT_TAG, MPI_COMM_WORLD); + } + + MPI_Finalize(); + + if (rank == MASTER) { + printf("total matches: %d\n", match_number); + printf("matches index: "); + print_array(matches, match_number); + } +} + +char *read_text() { + // TODO + return "abc"; +} + +char *read_pattern() { + // TODO + return "mamma"; +} + +void find_end(int residue, char *pattern, char *text, int **matches, int *match_number) { + int pattern_index = residue; + int text_index = 0; + int text_len = strlen(text); + int pattern_len = strlen(pattern); + + if (pattern_len - residue > text_len) return; + + while (pattern_index < pattern_len && pattern[pattern_index] == text[text_index]) { + pattern_index++; + text_index++; + } + + if (pattern_index != pattern_len) return; + + *match_number = *match_number + 1; + *matches = (int *) realloc(*matches, *match_number * sizeof(int)); + (*matches)[*match_number - 1] = -residue; +} + +void apply_shift(int shift, int *array, int size) { + for (int i = 0; i < size; ++i) { + array[i] += shift; + } +} + +int sum_array(int *array, int size) { + int sum = 0; + for (int i = 0; i < size; ++i) { + sum += array[i]; + } + + return sum; }