【问题标题】:iterating 2D array using parallel processing MPI使用并行处理 MPI 迭代二维数组
【发布时间】:2017-06-12 20:02:47
【问题描述】:

我对并行处理很陌生。我有一个以顺序方式计算和存储二维数组元素的示例。我想使用 MPI 将其转换为并行程序。

以下是顺序程序的代码。

#include <stdio.h>
int x,y,xMax=10,yMax=10;
int main ()
{
  int arr[yMax][xMax];
  for(y =0; y<yMax;x++)
  {
      for (x=0;x<xMax;x++)
      {
         arr[y][x]=x+y;
         printf("%d",arr[y][x]);
      }
      printf("\n");
  }
}

我尝试通过并行化外部 for 循环将其转换为等效的 MPI 程序,如下所示: 在这里,我希望每个进程计算每个数组行的值并将输出数组发送到根进程,该进程最后将收集所有数组并将它们组合成单个二维数组。

#include <stdio.h>
#include <mpi.h>
int x,y,xMax=10,yMax=10,size,rank;
int main()
{
   int arr[xMax];
   int arrall[yMax][xMax];  
   MPI_Init(NULL,NULL);
   MPI_Comm_size(MPI_COMM_WORLD, &size);
   MPI_Comm_rank(MPI_COMM_WORLD, &rank);
   for(y =0+rank; y<yMax;y=y+size)
   {
      for (x=0;y<xMax;x++)
      {
         arr[y][x]=x+y;

      }
      MPI_Send(arr,xMax,MPI_INT,0,0,MPI_COMM_WORLD);
   }
  if(rank==0)
  {
  MPI_Gather(arr,xMax,MPI_INT,&arrall,xMax*yMax,MPI_INT,0,MPI_COMM_WORLD);
  }  
  MPI_Finalize();
}

但是当我编译程序并等待很长时间时,它仍然没有给出任何结果。它没有显示错误。 我尝试了很长一段时间,并搜索了任何解决方案但无法找到。任何帮助都感激不尽。谢谢

【问题讨论】:

    标签: c arrays parallel-processing mpi


    【解决方案1】:

    其实你想的太复杂了。 MPI 中的集体操作负责发送和接收部分。正如标记所写,MPI_Send 等点对点消息将仅与点对点消息(例如 MPI_Recv)匹配,而集合仅与同一个集合匹配。

    所有进程只需一次调用MPI_Gather即可完成整个通信:

    MPI_Gather(arr,xMax,MPI_INT,arrall,xMax,MPI_INT,0,MPI_COMM_WORLD);
    

    注意,recvcountxMax,因为它指定了每次接收中的元素数。

    补充几点:

    • 您必须确保size == yMax
    • 这仅适用于二维数组在内存中按行连续布局。这不适用于指针“二维”数组。
    • 在真正的 MPI 程序中,您希望避免将整个工作数据收集在单个等级上,因为它会限制可伸缩性。相反,您应该做所有分布式的事情。

    编辑:每个等级多于一行的一种特定方式:

    int rows_per_rank = yMax / size;
    assert(rows_per_rank * size == yMax);
    MPI_Gather(arr,xMax * rows_per_rank,MPI_INT,arrall,xMax * rows_per_rank,MPI_INT,0,MPI_COMM_WORLD);
    

    【讨论】:

    • 谢谢!输出的大小是多少?会是二维数组吗?
    • arrall 将被size * xMax 元素填充。 “输出”将匹配二维数组的数据布局。
    • "你必须确保 size == yMax" 你能帮我解决这个问题吗?如果 yMax = 1000,我无法将任务分配给 1000 个进程。谢谢
    • 如果你想每个等级多于一行,比如rows_per_rank * rank == size,只需将MPI_Gather 的发送/接收大小参数从xMax 替换为xMax * rows_per_rank
    • 只是为了尝试,我将 10 行数据划分为 5 个进程。并将发送/接收乘以 2。但我无法正确收集数据。我得到一些带有负号而不是原始数据的大数字。虽然我注意到每个进程的最后一行我得到了正确的。
    猜你喜欢
    • 2019-08-12
    • 2018-12-01
    • 2017-05-20
    • 2022-11-27
    • 2014-07-13
    • 2011-12-28
    • 2015-04-04
    • 2014-05-30
    相关资源
    最近更新 更多