2

I'm writing a an MPI C-code but I found a problem with MPI_Bcast, in particular I'm trying to send in an array of size elements the element in position rank from the process denoted by rank. I write that code but it doesn't work.

#include<mpi.h>
#include<vector>
#include<iostream>

int main (int argc,char* argv[]) {
  MPI_Init(&argc,&argv);
  int rank,size,dimensions;
  MPI_Comm_rank(MPI_COMM_WORLD,&rank);
  MPI_Comm_size(MPI_COMM_WORLD,&size);

  if (rank == 0 ){
    int value;
    std::vector<int> v;
    std::cout<<"Dimension" <<std::endl;
    std::cin>>dimensions;
    std::cout<<"Values"<<std::endl;
    for (int i=0;i<dimensions;++i){
      std::cin>>value;
      v.push_back(value);
    }
  }

  int sizes[size]={0};
  MPI_Bcast (&dimensions,1,MPI_INT, 0, MPI_COMM_WORLD);
  int n_short = dimensions/size;
  int n_long = n_short+1;
  sizes[rank] = (rank<dimensions%size)?n_long:n_short;
  MPI_Bcast (sizes+rank,1,MPI_INT,rank,MPI_COMM_WORLD);
  MPI_Finalize();
  return 0;
}

I can't explain why the line

MPI_Bcast (sizes+rank,1,MPI_INT,rank,MPI_COMM_WORLD);

doesn't change anything and values in all processes remain the same.

1 Answers1

1

When you invoke MPI_Bcast with the root parameter equal to rank, you send data to all other processes from this process. Other processes should use MPI_Bcast with the same value of root parameter to receive it (like in your first MPI_Bcast call). There is no such call in your code, that's why you don't receive anything.

I guess you want MPI_Allgather function here, which will gather all elements of sizes to all the processes:

MPI_Allgather

int dimensions = 20;
std::vector<int> sizes(size);

const int n_short   = dimensions / size;
const int n_long    = n_short + 1;
const int this_size = (rank < dimensions % size) ? n_long : n_short;

MPI_Allgather(&this_size, 1, MPI_INT, sizes.data(), 1, MPI_INT, MPI_COMM_WORLD);

if (rank == 0)
    for (auto s : sizes)
        std::cout << s << ' ';

// Output for 3 processes: 7 7 6

or with MPI_IN_PLACE:

int dimensions = 20;
std::vector<int> sizes(size);

const int n_short = dimensions / size;
const int n_long  = n_short + 1;
sizes[rank] = (rank < dimensions % size) ? n_long : n_short;

MPI_Allgather(MPI_IN_PLACE, 0, MPI_DATATYPE_NULL, sizes.data(), 1, MPI_INT, MPI_COMM_WORLD);

Also note, that variable-length arrays are not standard C++. Prefer std::vectors.

(Picture source)

Evg
  • 25,259
  • 5
  • 41
  • 83