【问题标题】:Sending messages with MPI with three threads with ISend and IRecv使用 ISend 和 IRecv 使用三个线程使用 MPI 发送消息
【发布时间】:2014-05-29 03:00:46
【问题描述】:

我正在尝试并行生成导数矩阵。我有整个热方程求解器使用两个线程,但现在我试图找出如何将底行发送到下一个级别的 rec2,将顶行发送到前一个级别的 rec1。我试着用请求矩阵中的数字鬼混,但没有任何效果。出于某种原因,有人告诉我,使用 iSend 时,两个不同的接收是相同的请求。

任何解决此问题或帮助我更好地理解此问题的建议都会很棒。

  double** change = alloc(sizeX,sizeY); 
  double*    rec1;
  double*    rec2;
  int rank,size;
  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
  MPI_Comm_size(MPI_COMM_WORLD, &size);
  MPI_Request req[4];


  if(rank != 0)
  {
    rec1 = calloc(sizeY,sizeof(double));
  }
  if(rank != size-1)
  {
    rec2 = calloc(sizeY,sizeof(double));
  }

  if ( rank == 0 )
  {
    MPI_Irecv(rec2, sizeY, MPI_DOUBLE, rank+1, 1244, MPI_COMM_WORLD, &req[1]);
    MPI_Isend(u[sizeX-1], sizeY, MPI_DOUBLE, rank+1, 1244, MPI_COMM_WORLD, &req[0]);
  }
  else if ( rank == size-1 )
  {
    MPI_Irecv(rec1, sizeY, MPI_DOUBLE, rank - 1, 1244, MPI_COMM_WORLD, &req[2]);
    MPI_Isend(u[0], sizeY, MPI_DOUBLE, rank - 1, 1244, MPI_COMM_WORLD, &req[3]);
  }
  else if ( rank != 0 && rank != size -1)
  {
    MPI_Irecv(rec1, sizeY, MPI_DOUBLE, rank-1, 1234, MPI_COMM_WORLD, &req[1]);
    MPI_Isend(u[0], sizeY, MPI_DOUBLE, rank-1, 1234, MPI_COMM_WORLD, &req[0]);

    MPI_Irecv(rec2, sizeY, MPI_DOUBLE, rank+1, 1234, MPI_COMM_WORLD, &req[2]);
    MPI_Isend(u[sizeX-1], sizeY, MPI_DOUBLE, rank+1, 1234, MPI_COMM_WORLD, &req[3]);

  }
  // setting elements of most of the points

  int xStart = 1;
  int xBound = sizeX-1;

  for(int x = xStart; x < xBound; x++)
  { 
    for(int y = 1; y < sizeY-1; y++)
    {
      change[x][y] = fpp(u[x-1][y],u[x][y],u[x+1][y],dx)
      + fpp(u[x][y-1],u[x][y],u[x][y+1],dx);
    }
  }

  MPI_Waitall(size+1,req,MPI_STATUSES_IGNORE );

【问题讨论】:

  • 观看请求数量及其开始! rank 0 和 rank size-1 处理 2 条消息,而其他处理 4。这可能会导致 MPI_Waitall() 出现问题。而rank size-1 没有初始化 req[0] 和 req[1] !
  • 线程是指进程?他们安静不同。
  • @francis 是非常正确的 - 您在请求数组中使用的索引和元素数量不一致,因此等待已注定。我最喜欢的方法是在每个发布的请求中通过,例如,&amp;req[reqcnt++],最后调用MPI_Waitall(reqcnt, req...
  • 您还可以通过定义来简化代码,例如left = (rank &gt; 0? rank - 1 : MPI_PROC_NULL);right = (rank &lt; size-1? rank + 1 : MPI_PROC_NULL),然后只使用最后一个elseif 正文并使用leftright 而不是@987654331 删除其余部分@。上面的 waitall 应该可以工作,但代码将被简化,以减少重复(未来错误的来源)。

标签: c mpi


【解决方案1】:

观看请求的数量及其开始! rank 0 和 rank size-1 处理 2 条消息,而其他处理 4。这可能会导致 MPI_Waital() 出现问题。并且rank size-1不会初始化req[0]和req[1]

使用@JonathanDursi 的reqcnt 技巧:

 int nbreq=0;
 if(rank!=0 && size>1){
   MPI_Irecv(rec1, sizeY, MPI_DOUBLE, rank - 1, 1244, MPI_COMM_WORLD, &req[nbreq]);
   nbreq++;
   MPI_Isend(u[0], sizeY, MPI_DOUBLE, rank - 1, 1244, MPI_COMM_WORLD, &req[nbreq]);
   nbreq++;
 }
 if(rank!=size-1){
   MPI_Irecv(rec2, sizeY, MPI_DOUBLE, rank+1, 1244, MPI_COMM_WORLD, &req[nbreq]);
   nbreq++;
   MPI_Isend(u[sizeX-1], sizeY, MPI_DOUBLE, rank+1, 1244, MPI_COMM_WORLD, &req[nbreq]);
   nbreq++;
 }
 ...
 MPI_Waitall(nbreq,req,MPI_STATUSES_IGNORE );

【讨论】:

    猜你喜欢
    • 2017-07-14
    • 2012-11-05
    • 2012-03-31
    • 2017-04-24
    • 2018-05-25
    • 1970-01-01
    • 1970-01-01
    • 2013-02-08
    • 1970-01-01
    相关资源
    最近更新 更多