#include #include #include "kmp.h" #include "util.h" #include #include #define MASTER 0 #define DEFAULT_TAG 17 void find_end(int, char *, char *, int **, int *); void apply_shift(int, int *, int); int sum_array(int *, int); void initialize(); int rank, size; int text_len; // length of all text int private_text_len; // length of private text int pattern_len; //length of the pattern char *text; char *pattern; int remain = 0; int *text_piece; int *displacements; int main() { int *match_numbers; int *total_matches; int total_match_number; MPI_Init(NULL, NULL); MPI_Comm_size(MPI_COMM_WORLD, &size); MPI_Comm_rank(MPI_COMM_WORLD, &rank); if (rank == MASTER) initialize(); MPI_Scatter(text_piece, 1, MPI_INT, &private_text_len, 1, MPI_INT, MASTER, MPI_COMM_WORLD); char *private_text = (char *) malloc(sizeof(char) * (private_text_len + 1)); MPI_Scatterv(text, text_piece, displacements, MPI_CHAR, private_text, private_text_len, MPI_CHAR, MASTER, MPI_COMM_WORLD); private_text[private_text_len] = '\0'; if (rank == MASTER) MPI_Send(&remain, 1, MPI_INT, size - 1, DEFAULT_TAG, MPI_COMM_WORLD); else if (rank == size -1) MPI_Recv(&remain, 1, MPI_INT, MASTER, DEFAULT_TAG, MPI_COMM_WORLD, MPI_STATUS_IGNORE); printf("%d -> input: %s\n", rank, private_text); printf("%d -> text len: %d\n", rank, private_text_len); printf("%d -> text len_: %d\n", rank, strlen(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); } //print_array(matches, match_number); int shift = rank * (private_text_len - remain); apply_shift(shift, matches, match_number); printf("%d -> result number: %d\n", rank, match_number); if (rank == MASTER) { match_numbers = (int *) malloc(sizeof(int) * size); } MPI_Gather(&match_number, 1, MPI_INT, match_numbers, 1, MPI_INT, MASTER, MPI_COMM_WORLD); if (rank == MASTER) { total_match_number = sum_array(match_numbers, size); total_matches = (int *) malloc(sizeof(int) * total_match_number); displacements[0] = 0; for (int i = 0; i < size - 1; ++i) { displacements[i + 1] = displacements[i] + match_numbers[i]; } } MPI_Gatherv(matches, match_number, MPI_INT, total_matches, match_numbers, displacements, MPI_INT, MASTER, MPI_COMM_WORLD); MPI_Finalize(); if (rank == MASTER) { printf("total matches: %d\n", total_match_number); printf("matches index: "); print_array(total_matches, total_match_number); } } 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); // TODO: match splitted on 3+ node 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 initialize() { text = "questo è un test di esempio. Qui c'è la prima occorenza mamma e qui la seconda mamma";//read_file("data/text.txt", &text_len); pattern = "mamma";//read_file("data/pattern.txt", &pattern_len); text_len = strlen(text); pattern_len = strlen(pattern); printf("text: %s\n", text); printf("pattern: %s\n", pattern); private_text_len = text_len / size; remain = text_len % size; if (pattern_len > private_text_len) MPI_Abort(MPI_COMM_WORLD, 1); text_piece = (int *) malloc(sizeof(int) * size); displacements = (int *) malloc(sizeof(int) * size); displacements[0] = 0; for (int i = 0; i < size - 1; ++i) { text_piece[i] = private_text_len; displacements[i + 1] = displacements[i] + private_text_len; } text_piece[size - 1] = private_text_len + remain; } 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; }