Using MPI_Bcast for MPI communication
Asked Answered
E

2

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;
}
Engineer answered 23/10, 2011 at 3:3 Comment(0)
W
167

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).

Washedup answered 23/10, 2011 at 17:22 Comment(4)
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?Engineer
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.Washedup
@David: If you think of MPI_Bcast as meaning 'participate in a broadcast event', it maybe makes more sense.Liqueur
This comment was a godsend... I swear so much of MPI is unintuitive or ambiguous in its design intentions...Bryonbryony
M
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

Mojave answered 19/8, 2016 at 15:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.