#include #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() { int rank, size, private_text_len, text_len, pattern_len; char *pattern, *text; 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); int lps[pattern_len]; create_lps(pattern, pattern_len, lps); int match_number = 0, residue; int *matches = search_pattern(private_text, pattern, lps, &match_number, &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; }