代码之家  ›  专栏  ›  技术社区  ›  Rom

用MPI在超立方体中广播

  •  1
  • Rom  · 技术社区  · 7 年前

    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
    

    为什么最后一个进程没有收到向量?错误一定来自 接收 但是我不知道应该使用哪个函数(Isend、Irecv、Send、Recv)。 谢谢

    1 回复  |  直到 7 年前
        1
  •  3
  •   Zulan    7 年前

    你呢 必须显式完成 MPI_Irecv )在访问任何参与数据之前。这意味着你既不能转发数据,也不能打印出来,因为完成。使用 MPI_Wait MPI_Test any / some / all 视情况而定。

    如果您不需要非阻塞通信,如您的示例所示,请使用阻塞通信(即。 MPI_Recv )相反。

    实际上,在可能的情况下,使用集体而不是点对点 MPI_Bcast