0

After I broadcast my final array in rank 0 to all other nodes. It should then back to the loop and all of the nodes have the same array. But in fact, I got the original array instead of the array after broadcasting. I am using MPI to do it. I am sure how to use loop in MPI. I have a program similar to this one. First, I need to deal with some calculation with the array in each node. Then find one array among nodes that I need, then I repeat the step from the beginning and do it again and again. Can anyone help me with it or give me better ways to do it? Thank you to everyone.

int main(int argc, char** argv) {

    //set array of long double to send
    long double array[4][4]{0}, compenergy=0;
    int size, rank;
    int i, j;
    int rank_lowest_energy, lowrank;
    MPI_Status status;

    struct {
        long double val;
        int rank;
    } energy, lowenergy;

    lowenergy.val = 0;

    MPI_Init(NULL, NULL);
    // Get the number of processes
    size = MPI::COMM_WORLD.Get_size();
    // Get the rank of the process
    rank = MPI::COMM_WORLD.Get_rank();

    for (int m = 0; m < 3; ++m)
    {
        //MPI::COMM_WORLD.Bcast(&array, 4*4, MPI::LONG_DOUBLE, 0);
        if (rank == 0) 
        {
            energy.val = 10000;
            energy.rank = rank;
        }
        else
        {
            for (i = 0; i < rank; ++i)
                array[rank][i] += rank;

            energy.val = rank + 10 - array[rank][0]- lowenergy.val;
            energy.rank = rank;
        }

        MPI_Allreduce(&energy, &lowenergy, 1, MPI_LONG_DOUBLE_INT, MPI_MINLOC, MPI_COMM_WORLD);
        if (rank == lowenergy.rank)
            MPI::COMM_WORLD.Send(&array, 4 * 4, MPI::LONG_DOUBLE, 0, 0);

        if (rank == 0) 
        {
            MPI::COMM_WORLD.Recv(&array, 4 * 4, MPI::LONG_DOUBLE, MPI::ANY_SOURCE, MPI::ANY_TAG);
            cout << "Its rank is: " << lowenergy.rank << "\n";
            cout<< "Its value is: "<<lowenergy.val<<"\n";
            for (i = 0; i < 4; ++i) 
            {
                for (j = 0; j < 4; ++j)
                    cout << array[i][j] << "  ";
                cout << "\n";
            }
            MPI::COMM_WORLD.Bcast(&lowenergy, 1, MPI::LONG_DOUBLE_INT, 0);
        }
        MPI::COMM_WORLD.Bcast(&array, 4*4, MPI::LONG_DOUBLE, 0);
    }

    MPI::Finalize();
}
John Zwinck
  • 239,568
  • 38
  • 324
  • 436
ZHI
  • 1
  • 1
  • 2
    please format the code correctly. – ptb Jun 29 '18 at 21:17
  • You should not broadcast `lowenergy` – Gilles Gouaillardet Jun 30 '18 at 00:49
  • @ptb Sorry, I do not understand what you mean. Could you please explain it in details? – ZHI Jul 02 '18 at 12:17
  • @GillesGouaillardet, if I do not broadcast lowenergy, can I get the value when starts a new loop? – ZHI Jul 02 '18 at 12:19
  • The formatting has already been corrected. – ptb Jul 02 '18 at 15:28
  • Why would you broadcast lowenergy after an allreduce ? If you really want to broadcast , then do it on all ranks (e.g. not only on rank 0). Note lowenergy.rank could directly broadcast array (e.g. no send/recv). Last but not least, your program is incorrect w.r.t. the MPI standard since it might deadlock when lowenergy.rank is 0. – Gilles Gouaillardet Jul 02 '18 at 21:16
  • MPI_Bcast must be called by all processes. You can have a look here: https://stackoverflow.com/questions/7864075/using-mpi-bcast-for-mpi-communication – supercheval Jul 02 '18 at 21:17
  • @GillesGouaillardet What I want to do is that after I broadcast lowenergy, I need to reuse it to do some calculation in the new loop for each node. And it works. But when I broadcast array at the last line in the loop, it did not work. – ZHI Jul 03 '18 at 00:16
  • @lmontigny, I think I kind of know what you mean. But in my situation, I can broadcast lowenergy instead of array. According to your advice, I should succeed boradcast array at the last line in the loop rather than lowenergy which is not called by all processes. Is it right? – ZHI Jul 03 '18 at 00:20
  • @GillesGouaillarde, I want to braodcast both array and lowenergy. Do you have any way to do it? I want the update the array and lowenergy each time staring a new loop. – ZHI Jul 03 '18 at 00:22
  • @ptb, do you have any advice can give me to help me correct my codes? Thanks. – ZHI Jul 03 '18 at 00:23
  • `MPI_Allreduce()` has the same outcome than `MPI_Reduce()` followed by `MPI_Bcast()`, so what is the point of broadcasting again `lowenergy` ? Then you can simply `MPI_Bcast(buffer=array, ..., root=lowenergy.rank, ...)` – Gilles Gouaillardet Jul 03 '18 at 00:33
  • I'm not too sure what you are actually trying to do here. It would helpful if you edit your question to include sample inputs and the expected outcome – ptb Jul 03 '18 at 14:46

0 Answers0