Add basic parallel implementation
This commit is contained in:
parent
24535aff47
commit
f6cfc87ce1
153
main.c
153
main.c
@ -2,24 +2,159 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "kmp.h"
|
#include "kmp.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include <mpi.h>
|
||||||
|
#include <malloc.h>
|
||||||
|
|
||||||
|
#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 main() {
|
||||||
char *patter = "acabacacd";
|
int rank, size, private_text_len, text_len, pattern_len;
|
||||||
char *text = "acfacabacabacacdac";
|
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];
|
int lps[pattern_len];
|
||||||
|
|
||||||
create_lps(patter, pattern_len, lps);
|
create_lps(pattern, pattern_len, lps);
|
||||||
|
|
||||||
int match_number = 0;
|
int match_number = 0, residue;
|
||||||
int residue;
|
int *matches = search_pattern(private_text, pattern, lps, &match_number, &residue);
|
||||||
|
|
||||||
int *matches = search_pattern(text, patter, 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);
|
print_array(matches, match_number);
|
||||||
printf("%d\n", residue);
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user