I know that this code is correct
#include <stdio.h>
#include "mpi.h"
int main(int argc, char * argv[]){
int my_rank, p, n;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &p);
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
if(my_rank == 0){
scanf("%d", &n);
}
MPI_Bcast(&n, 1, MPI_INT, 0, MPI_COMM_WORLD);
MPI_Finalize();
}
But what about this code. I asked someone and we got into a debate and he told me that this code is totally wrong.
#include <stdio.h>
#include "mpi.h"
int main(int argc, char * argv[]){
int my_rank, p, n;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &p);
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
if(my_rank == 0){
scanf("%d", &n);
MPI_Bcast(&n, 1, MPI_INT, 0, MPI_COMM_WORLD);
}
else {
MPI_Bcast(&n, 1, MPI_INT, 0, MPI_COMM_WORLD);
}
MPI_Finalize();
}
I know it's not efficient but I can't understand why is it wrong. I understand that every process will take a copy of the following program and work on it, so all of them will use MPI_Bcast as if it is outside the if statement, so can any one please explain to me what is really going on when I use MPI_Bcast inside if statements?
The first and the second code are semantically equivalent. Both are correct MPI programs. You can easily demonstrate that by compiling both - with optimization the compiler creates the exact same assembly code..
$ mpicc -S first.c -O3
$ mpicc -S second.c -O3
$ diff first.s second.s
1c1
< .file "first.c"
---
> .file "second.c"
That said, the first code is the better version. It is has a simpler control flow and it is easier to show that it is correct in a sense that all ranks enter the barrier. That is the important thing to ensure with MPI collectives - all processes (in the communicator) must call them in the same order.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With