Трансляция в гиперкубе с MPI - PullRequest
0 голосов
/ 04 октября 2018

Я пытаюсь передать вектор, полный 1 из процесса 0 в гиперкубе

int main(int argc, char **argv) {
  int myRank, nProc;

  MPI_Init(&argc, &argv);
  MPI_Comm_rank(MPI_COMM_WORLD, &myRank);
  MPI_Comm_size(MPI_COMM_WORLD, &nProc);
  MPI_Request request;
  MPI_Status status; 

  MPI_Barrier(MPI_COMM_WORLD);
  double start = MPI_Wtime();

  std::vector<int> vector(100, 0);
  if (myRank == 0) {vector = std::vector<int>(100, 1);}

  //Broadcast in a hypercube
  int dimension = log2(nProc);

  for (int step = 0 ; step < dimension ; step++) {
    std::bitset<6> tmpRank(myRank);
    if (tmpRank >> step == 0) { //source
      int neighbor = static_cast<int>(tmpRank.flip(step).to_ulong()); //The neighbor of a source at the step i is the i_th bit flipped, re-converted to int in order to send
      MPI_Send(vector.data(), vector.size(), MPI_INT, neighbor, 0, MPI_COMM_WORLD);
    }
    else { //destination ( if(rank >> step == 1) )
      //MPI_Status status;
      MPI_Irecv(vector.data(), vector.size(), MPI_INT, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &request);
    }
  }
  //

  MPI_Barrier(MPI_COMM_WORLD);
  double end = MPI_Wtime();

  std::cout << "I am process " << myRank << " last element of my vector after broadcast is " << vector.back() << std::endl;

  if (myRank==0) std::cout << " operation time : " << end-start << "[s]" << std::endl;

  MPI_Finalize();
}

У меня есть ввывод:

 I am process 0 last element of my vector after broadcast is 1
 operation time : 3.40939e-05[s]
 I am process 1 last element of my vector after broadcast is 1
 I am process 2 last element of my vector after broadcast is 1
 I am process 3 last element of my vector after broadcast is 0

Почему последний процесс не получил вектор?Ошибка должна исходить от send и receive , но я не знаю, какую функцию мне следует использовать (Isend, Irecv, Send, Recv).Спасибо

1 Ответ

0 голосов
/ 04 октября 2018

Вы должны явно завершить все неблокирующие коммуникации (в вашем случае MPI_Irecv), прежде чем получить доступ к любым участвующим данным.Это означает, что вы не можете ни переслать данные, ни распечатать их из-за завершения.Используйте MPI_Wait, MPI_Test или любой из его any / some / all вариантов в зависимости от ситуации.

Если вам не нужна неблокирующая связь, как показывает ваш пример, используйтевместо этого блокируя один (т. е. MPI_Recv).

Практически, используйте коллективные группы вместо двухточечных, когда это возможно, в вашем случае MPI_Bcast.Реализация собственной трансляции не является хорошей идеей, если вы не хотите учиться или действительно знать, что делаете.

...