I am currently working on an assignment for my parallel programming class in which I need to write the same program sequentially, then parallelized using OpenMP then parallelized using MPI.
For context, the assignment is about searching for palindromes in a matrix of random characters. I already have most of the code working, my question is about how to structure, compile and run the project.
I could create three separate programs and run them independently, but I would like to combine them all in the same project so the three versions run one after the other and on the same initial matrix. This allows me to time each version to compare them.
I am using CMake as the build tool.
My CMakeLists.txt :
cmake_minimum_required(VERSION 3.21)
project(<project-name> C)
set(CMAKE_C_STANDARD 23)
find_package(MPI REQUIRED)
include_directories(SYSTEM ${MPI_INCLUDE_PATH})
find_package(OpenMP REQUIRED)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}")
add_executable(<project-name> <source-files>)
target_link_libraries(<project-name> ${MPI_C_LIBRARIES})
I build the project using the following commands
mkdir build && cd build && cmake .. && make
My main function :
// All the header inclusions
int main(int argc, char **argv) {
// Initialisation.
srand(time(NULL));
omp_set_num_threads(omp_get_num_procs());
double start_time;
ushort number_of_palindromes = 0;
ushort palindrome_length = 5;
ushort rows = 25000;
ushort cols = 25000;
char **matrix = create_matrix_of_chars(rows, cols);
printf("Matrix of size %dx%d, searching for palindromes of size %d.\n", rows, cols, palindrome_length);
// Run sequentially.
printf("%-45s", "Running sequentially ... ");
start_time = omp_get_wtime();
number_of_palindromes = find_palindromes_sequentially(matrix, rows, cols, palindrome_length);
printf("Found M palindromes in %7.4f seconds.\n", number_of_palindromes, omp_get_wtime() - start_time);
// Run using OpenMP.
printf("Running with OpenMP on %d %-20s", omp_get_num_procs(), "threads ... ");
start_time = omp_get_wtime();
number_of_palindromes = find_palindromes_using_openmp(matrix, rows, cols, palindrome_length);
printf("Found M palindromes in %7.4f seconds.\n", number_of_palindromes, omp_get_wtime() - start_time);
// Run using MPI.
int num_procs, rank;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &num_procs);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
printf("%d: hello (p=%d)\n", rank, num_procs);
MPI_Finalize();
// Cleanup and exit.
free_matrix(matrix, rows);
return 0;
}
When running ./<project-name>
the sequential and OpenMP versions run one after the other correctly. However, when running mpirun --use-hwthread-cpus ./<project-name>
the program starts 8 instances of the entire project (the line "Matrix of size ..." gets printed 8 times).
My understanding was that the MPI region is delimited by MPI_Init(...)
and MPI_Finalize()
but that does not seem to be the case. How would I go about solving this ?
Thanking you in advance for your answers.
CodePudding user response:
There is no such thing as an "MPI region". MPI uses independent process that only communicate/synchronize through the network. Meaning: the whole of your executable run in as many instances as you start it. Each and every statement, even before MPI_Init
is executed by each and every instance.