86

I'm trying to broadcast a message from the root node to all other nodes using MPI_Bcast. However, whenever I run this program it always hangs at the beginning. Does anybody know what's wrong with it?

#include <mpi.h>
#include <stdio.h>

int main(int argc, char** argv) {
        int rank;
        int buf;
        MPI_Status status;
        MPI_Init(&argc, &argv);
        MPI_Comm_rank(MPI_COMM_WORLD, &rank);

        if(rank == 0) {
                buf = 777;
                MPI_Bcast(&buf, 1, MPI_INT, 0, MPI_COMM_WORLD);
        }
        else {
                MPI_Recv(&buf, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, &status);
                printf("rank %d receiving received %d\n", rank, buf);
        }

        MPI_Finalize();
        return 0;
}
techenthu
  • 158
  • 11
David
  • 2,080
  • 5
  • 29
  • 44

2 Answers2

164

This is a common source of confusion for people new to MPI. You don't use MPI_Recv() to receive data sent by a broadcast; you use MPI_Bcast().

Eg, what you want is this:

#include <mpi.h>
#include <stdio.h>

int main(int argc, char** argv) {
        int rank;
        int buf;
        const int root=0;

        MPI_Init(&argc, &argv);
        MPI_Comm_rank(MPI_COMM_WORLD, &rank);

        if(rank == root) {
           buf = 777;
        }

        printf("[%d]: Before Bcast, buf is %d\n", rank, buf);

        /* everyone calls bcast, data is taken from root and ends up in everyone's buf */
        MPI_Bcast(&buf, 1, MPI_INT, root, MPI_COMM_WORLD);

        printf("[%d]: After Bcast, buf is %d\n", rank, buf);

        MPI_Finalize();
        return 0;
}

For MPI collective communications, everyone has to particpate; everyone has to call the Bcast, or the Allreduce, or what have you. (That's why the Bcast routine has a parameter that specifies the "root", or who is doing the sending; if only the sender called bcast, you wouldn't need this.) Everyone calls the broadcast, including the receivers; the receviers don't just post a receive.

The reason for this is that the collective operations can involve everyone in the communication, so that you state what you want to happen (everyone gets one processes' data) rather than how it happens (eg, root processor loops over all other ranks and does a send), so that there is scope for optimizing the communication patterns (eg, a tree-based hierarchical communication that takes log(P) steps rather than P steps for P processes).

Jonathan Dursi
  • 50,107
  • 9
  • 127
  • 158
  • Thanks for explaining it like that. However, I'm still confused as to how to have each node receive the message using MPI_Recv. I tried wrapping a MPI_Recv call in an if(rank != 0) block and without one but my program still doesn't print anything. Do you know how to also receive the message on each node? – David Oct 23 '11 at 20:34
  • 3
    You don't. MPI_Bcast isn't like a send; it's a collective operation that *everyone* takes part in, sender and receiver, and at the end of the call, the receiver has the value the sender had. The same function call does (something like) a send if the rank == root (here, 0), and (something like) a receive otherwise. I've updated the code above so you can see that everyone ends up with the same result. – Jonathan Dursi Oct 23 '11 at 21:01
  • 6
    @David: If you think of `MPI_Bcast` as meaning 'participate in a broadcast event', it maybe makes more sense. – Hugh Perkins Jun 22 '13 at 02:41
  • 1
    This comment was a godsend... I swear so much of MPI is unintuitive or ambiguous in its design intentions... – Shane Sepac May 01 '21 at 02:15
3

MPI_Bcast is a collective operation and it must be called by all processes in order to complete.

And there is no need to call MPI_Recv when using MPI_Bcast. There is a post that may be helpful for you, click here

Gilles Gouaillardet
  • 8,193
  • 11
  • 24
  • 30
GoingMyWay
  • 16,802
  • 32
  • 96
  • 149