Add comments
This commit is contained in:
parent
954556f28a
commit
06a6ded2e7
58
main.c
58
main.c
@ -39,74 +39,106 @@ int main() {
|
|||||||
if (rank == MASTER)
|
if (rank == MASTER)
|
||||||
initialize();
|
initialize();
|
||||||
|
|
||||||
|
// distribution of the length of the text portion to each process
|
||||||
MPI_Scatter(text_piece, 1, MPI_INT, &private_text_len, 1, MPI_INT, MASTER, MPI_COMM_WORLD);
|
MPI_Scatter(text_piece, 1, MPI_INT, &private_text_len, 1, MPI_INT, MASTER, MPI_COMM_WORLD);
|
||||||
|
|
||||||
|
// allocation of space for text
|
||||||
char *private_text = (char *) malloc(sizeof(char) * (private_text_len + 1));
|
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,
|
// distribution of the text portion to each process
|
||||||
MPI_COMM_WORLD);
|
// scatterv is necessary because the last process receives a larger portion of text in case it is not perfectly divisible.
|
||||||
|
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';
|
private_text[private_text_len] = '\0';
|
||||||
|
|
||||||
|
// sending the remain to the last trial
|
||||||
|
// this is necessary for the calculation of the offset
|
||||||
if (rank == MASTER)
|
if (rank == MASTER)
|
||||||
MPI_Send(&remain, 1, MPI_INT, size - 1, DEFAULT_TAG, MPI_COMM_WORLD);
|
MPI_Send(&remain, 1, MPI_INT, size - 1, DEFAULT_TAG, MPI_COMM_WORLD);
|
||||||
else if (rank == size -1)
|
else if (rank == size - 1)
|
||||||
MPI_Recv(&remain, 1, MPI_INT, MASTER, DEFAULT_TAG, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
|
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 -> input: %s\n", rank, private_text);
|
||||||
printf("%d -> text len: %d\n", rank, private_text_len);
|
printf("%d -> text len: %d\n", rank, private_text_len);
|
||||||
printf("%d -> text len_: %d\n", rank, strlen(private_text));
|
|
||||||
|
|
||||||
|
// distribution of the length of the pattern to each process
|
||||||
MPI_Bcast(&pattern_len, 1, MPI_INT, MASTER, MPI_COMM_WORLD);
|
MPI_Bcast(&pattern_len, 1, MPI_INT, MASTER, MPI_COMM_WORLD);
|
||||||
|
|
||||||
|
// allocation of space for the pattern
|
||||||
|
// the master has already done so previously
|
||||||
if (rank != MASTER) {
|
if (rank != MASTER) {
|
||||||
pattern = (char *) malloc(sizeof(char) * (pattern_len + 1));
|
pattern = (char *) malloc(sizeof(char) * (pattern_len + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// distribution of the pattern to each process
|
||||||
MPI_Bcast(pattern, pattern_len + 1, MPI_CHAR, MASTER, MPI_COMM_WORLD);
|
MPI_Bcast(pattern, pattern_len + 1, MPI_CHAR, MASTER, MPI_COMM_WORLD);
|
||||||
|
|
||||||
|
// create and build lps array
|
||||||
int lps[pattern_len];
|
int lps[pattern_len];
|
||||||
|
|
||||||
create_lps(pattern, pattern_len, lps);
|
create_lps(pattern, pattern_len, lps);
|
||||||
|
|
||||||
int match_number = 0, residue;
|
int match_number = 0, residue;
|
||||||
|
// search for matches
|
||||||
int *matches = search_pattern(private_text, pattern, lps, &match_number, &residue);
|
int *matches = search_pattern(private_text, pattern, lps, &match_number, &residue);
|
||||||
|
|
||||||
|
// send the residue to the next process
|
||||||
if (rank + 1 != size) {
|
if (rank + 1 != size) {
|
||||||
MPI_Send(&residue, 1, MPI_INT, rank + 1, DEFAULT_TAG, MPI_COMM_WORLD);
|
MPI_Send(&residue, 1, MPI_INT, rank + 1, DEFAULT_TAG, MPI_COMM_WORLD);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// receiving the residue from the previous process
|
||||||
if (rank != 0) {
|
if (rank != 0) {
|
||||||
MPI_Recv(&residue, 1, MPI_INT, rank - 1, DEFAULT_TAG, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
|
MPI_Recv(&residue, 1, MPI_INT, rank - 1, DEFAULT_TAG, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
|
||||||
if (residue != 0)
|
if (residue != 0)
|
||||||
|
// search for a split match
|
||||||
find_end(residue, pattern, private_text, &matches, &match_number);
|
find_end(residue, pattern, private_text, &matches, &match_number);
|
||||||
}
|
}
|
||||||
|
|
||||||
//print_array(matches, match_number);
|
// transformation of match indices from relative to absolute position.
|
||||||
|
int shift = rank * (private_text_len - remain); // the rest is zero for all but the last process
|
||||||
int shift = rank * (private_text_len - remain);
|
|
||||||
apply_shift(shift, matches, match_number);
|
apply_shift(shift, matches, match_number);
|
||||||
|
|
||||||
printf("%d -> result number: %d\n", rank, match_number);
|
printf("%d -> result number: %d\n", rank, match_number);
|
||||||
|
|
||||||
if (rank == MASTER) {
|
if (rank == MASTER) {
|
||||||
|
// allocation for the array containing the number of matches of each process
|
||||||
match_numbers = (int *) malloc(sizeof(int) * size);
|
match_numbers = (int *) malloc(sizeof(int) * size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// collection of the number of matches from each process
|
||||||
MPI_Gather(&match_number, 1, MPI_INT, match_numbers, 1, MPI_INT, MASTER, MPI_COMM_WORLD);
|
MPI_Gather(&match_number, 1, MPI_INT, match_numbers, 1, MPI_INT, MASTER, MPI_COMM_WORLD);
|
||||||
|
|
||||||
if (rank == MASTER) {
|
if (rank == MASTER) {
|
||||||
|
// preparation of the data structures needed to receive match indices from all processes
|
||||||
total_match_number = sum_array(match_numbers, size);
|
total_match_number = sum_array(match_numbers, size);
|
||||||
|
|
||||||
total_matches = (int *) malloc(sizeof(int) * total_match_number);
|
total_matches = (int *) malloc(sizeof(int) * total_match_number);
|
||||||
|
|
||||||
displacements[0] = 0;
|
displacements[0] = 0;
|
||||||
for (int i = 0; i < size - 1; ++i) {
|
for (int i = 0; i < size - 1; ++i) {
|
||||||
displacements[i + 1] = displacements[i] + match_numbers[i];
|
displacements[i + 1] = displacements[i] + match_numbers[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MPI_Gatherv(matches, match_number, MPI_INT, total_matches, match_numbers, displacements, MPI_INT, MASTER,
|
// collection of match indices from each process
|
||||||
MPI_COMM_WORLD);
|
// gatherv is necessary because each process will have a different number of matches
|
||||||
|
MPI_Gatherv(
|
||||||
|
matches,
|
||||||
|
match_number,
|
||||||
|
MPI_INT,
|
||||||
|
total_matches,
|
||||||
|
match_numbers,
|
||||||
|
displacements,
|
||||||
|
MPI_INT, MASTER,
|
||||||
|
MPI_COMM_WORLD
|
||||||
|
);
|
||||||
|
|
||||||
MPI_Finalize();
|
MPI_Finalize();
|
||||||
|
|
||||||
@ -139,7 +171,7 @@ void find_end(int residue, char *pattern, char *text, int **matches, int *match_
|
|||||||
}
|
}
|
||||||
|
|
||||||
void initialize() {
|
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);
|
text = "testo di esempio mamma altra mamma esempio prova mammamma esempio mamma";//read_file("data/text.txt", &text_len);
|
||||||
pattern = "mamma";//read_file("data/pattern.txt", &pattern_len);
|
pattern = "mamma";//read_file("data/pattern.txt", &pattern_len);
|
||||||
|
|
||||||
text_len = strlen(text);
|
text_len = strlen(text);
|
||||||
|
Loading…
Reference in New Issue
Block a user