Add version 2
This commit is contained in:
parent
3e9ea923b6
commit
0a0b2f89ae
12
makefile
12
makefile
@ -7,14 +7,26 @@ sequential-time: src/sequential.c src/util.c src/kmp.c build
|
|||||||
parallel: src/parallel.c src/util.c src/kmp.c build
|
parallel: src/parallel.c src/util.c src/kmp.c build
|
||||||
mpicc -std=c99 src/parallel.c src/util.c src/kmp.c -lm -o build/kmp-p.out
|
mpicc -std=c99 src/parallel.c src/util.c src/kmp.c -lm -o build/kmp-p.out
|
||||||
|
|
||||||
|
parallel-2: src/parallel-v2.c src/util.c src/kmp.c build
|
||||||
|
mpicc -std=c99 src/parallel-v2.c src/util.c src/kmp.c -lm -o build/kmp-p-2.out
|
||||||
|
|
||||||
parallel-time: src/parallel.c src/util.c src/kmp.c build
|
parallel-time: src/parallel.c src/util.c src/kmp.c build
|
||||||
mpicc -std=c99 -D TIME src/parallel.c src/util.c src/kmp.c /usr/local/lib/libpapi.a -lm -o build/kmp-pt.out
|
mpicc -std=c99 -D TIME src/parallel.c src/util.c src/kmp.c /usr/local/lib/libpapi.a -lm -o build/kmp-pt.out
|
||||||
|
|
||||||
|
parallel-time-2: src/parallel-v2.c src/util.c src/kmp.c build
|
||||||
|
mpicc -std=c99 -D TIME src/parallel-v2.c src/util.c src/kmp.c /usr/local/lib/libpapi.a -lm -o build/kmp-pt-2.out
|
||||||
|
|
||||||
parallel-log: src/parallel.c src/util.c src/kmp.c build
|
parallel-log: src/parallel.c src/util.c src/kmp.c build
|
||||||
mpicc -std=c99 -D LOG src/parallel.c src/util.c src/kmp.c -lm -o build/kmp-pl.out
|
mpicc -std=c99 -D LOG src/parallel.c src/util.c src/kmp.c -lm -o build/kmp-pl.out
|
||||||
|
|
||||||
|
parallel-log-2: src/parallel-v2.c src/util.c src/kmp.c build
|
||||||
|
mpicc -std=c99 -D LOG src/parallel-v2.c src/util.c src/kmp.c -lm -o build/kmp-pl-2.out
|
||||||
|
|
||||||
parallel-mpe: src/parallel.c src/util.c src/kmp.c build
|
parallel-mpe: src/parallel.c src/util.c src/kmp.c build
|
||||||
mpecc -std=c99 -mpilog -lpthread src/parallel.c src/util.c src/kmp.c -lm -o build/kmp-mpe.out
|
mpecc -std=c99 -mpilog -lpthread src/parallel.c src/util.c src/kmp.c -lm -o build/kmp-mpe.out
|
||||||
|
|
||||||
|
parallel-mpe-2: src/parallel-v2.c src/util.c src/kmp.c build
|
||||||
|
mpecc -std=c99 -mpilog -lpthread src/parallel-v2.c src/util.c src/kmp.c -lm -o build/kmp-mpe-2.out
|
||||||
|
|
||||||
build:
|
build:
|
||||||
mkdir build
|
mkdir build
|
||||||
|
176
src/parallel-v2.c
Normal file
176
src/parallel-v2.c
Normal file
@ -0,0 +1,176 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "kmp.h"
|
||||||
|
#include "util.h"
|
||||||
|
#include <mpi.h>
|
||||||
|
#include <malloc.h>
|
||||||
|
|
||||||
|
#ifdef TIME
|
||||||
|
#include <papi.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define MASTER 0
|
||||||
|
#define DEFAULT_TAG 17
|
||||||
|
|
||||||
|
int find_end(int residue, char *pattern, char *text, int shift);
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
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;
|
||||||
|
char *private_text;
|
||||||
|
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);
|
||||||
|
|
||||||
|
MPI_Barrier(MPI_COMM_WORLD);
|
||||||
|
|
||||||
|
#ifdef TIME
|
||||||
|
long_long start_time = PAPI_get_real_usec();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
char *text_file_path = get_text_file(argc, argv);
|
||||||
|
private_text = read_file_portion(text_file_path, size, rank, &private_text_len, &remain);
|
||||||
|
pattern = read_file("data/pattern.txt", &pattern_len);
|
||||||
|
|
||||||
|
#ifdef LOG
|
||||||
|
printf("%d -> input: %s\n", rank, private_text);
|
||||||
|
printf("%d -> text len: %d\n", rank, private_text_len);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// create and build lps array
|
||||||
|
int lps[pattern_len];
|
||||||
|
create_lps(pattern, pattern_len, lps);
|
||||||
|
|
||||||
|
// search for matches
|
||||||
|
int match_number = 0;
|
||||||
|
int residue;
|
||||||
|
#ifdef TIME
|
||||||
|
long_long start_search = PAPI_get_real_usec();
|
||||||
|
#endif
|
||||||
|
int *matches = search_pattern(private_text, pattern, lps, &match_number, &residue);
|
||||||
|
|
||||||
|
// send the residue to the next process
|
||||||
|
if (rank + 1 != size) {
|
||||||
|
MPI_Request request;
|
||||||
|
MPI_Isend(&residue, 1, MPI_INT, rank + 1, DEFAULT_TAG, MPI_COMM_WORLD, &request);
|
||||||
|
}
|
||||||
|
|
||||||
|
// receiving the residue from the previous process
|
||||||
|
int other_residue = 0;
|
||||||
|
MPI_Request rec_rq;
|
||||||
|
if (rank != 0) {
|
||||||
|
MPI_Irecv(&other_residue, 1, MPI_INT, rank - 1, DEFAULT_TAG, MPI_COMM_WORLD, &rec_rq);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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
|
||||||
|
apply_shift(shift, matches, match_number);
|
||||||
|
|
||||||
|
if (rank == MASTER) {
|
||||||
|
// allocation for the array containing the number of matches of each process
|
||||||
|
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);
|
||||||
|
|
||||||
|
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_matches = (int *) malloc(sizeof(int) * (total_match_number + size));
|
||||||
|
|
||||||
|
displacements = (int *) malloc(sizeof(int) * size);
|
||||||
|
displacements[0] = 0;
|
||||||
|
for (int i = 0; i < size - 1; ++i) {
|
||||||
|
displacements[i + 1] = displacements[i] + match_numbers[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// collection of match indices from each process
|
||||||
|
// 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
|
||||||
|
);
|
||||||
|
|
||||||
|
if (rank == MASTER) {
|
||||||
|
free(match_numbers);
|
||||||
|
free(displacements);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rank != 0) {
|
||||||
|
MPI_Status myStatus;
|
||||||
|
MPI_Wait(&rec_rq, &myStatus);
|
||||||
|
if (residue != 0) {
|
||||||
|
int splitted_match = find_end(other_residue, pattern, private_text, shift);
|
||||||
|
MPI_Send(&splitted_match, 1, MPI_INT, MASTER, DEFAULT_TAG, MPI_COMM_WORLD);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rank == MASTER) {
|
||||||
|
int splitted_match;
|
||||||
|
for (int i = 0; i < size - 1; i++) {
|
||||||
|
MPI_Recv(&splitted_match, 1, MPI_INT, MPI_ANY_SOURCE, DEFAULT_TAG, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
|
||||||
|
if (splitted_match > 0) {
|
||||||
|
total_matches[total_match_number] = splitted_match;
|
||||||
|
total_match_number++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef TIME
|
||||||
|
long_long end_time = PAPI_get_real_usec();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
MPI_Finalize();
|
||||||
|
|
||||||
|
if (rank == MASTER) {
|
||||||
|
printf("total matches: %d\n", total_match_number);
|
||||||
|
#ifdef LOG
|
||||||
|
printf("matches index: ");
|
||||||
|
print_array(total_matches, total_match_number);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TIME
|
||||||
|
printf("total elapsed: %d\n", end_time - start_time);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int find_end(int residue, char *pattern, char *text, int shift) {
|
||||||
|
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 -1;
|
||||||
|
|
||||||
|
while (pattern_index < pattern_len && pattern[pattern_index] == text[text_index]) {
|
||||||
|
pattern_index++;
|
||||||
|
text_index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pattern_index != pattern_len) return -1;
|
||||||
|
|
||||||
|
return shift - residue;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user