使用MPI从不同进程收集小矩阵部分

时间:2013-11-01 19:52:41

标签: c mpi

我花了一些时间考虑计算矩阵的方案,一切都有意义,但最后一部分我不知道如何处理。

这是我打算做的事情(场景):

  1. 要求计算10(w)x5(h)矩阵。
  2. 我有10个处理器。
  3. 在每个处理器上声明1x5矩阵,包括等级为0的过程。
  4. 计算每个处理器上的每个子矩阵的偏移量。
  5. MPI_Barrier等待所有10个处理器完成计算。
  6. 显示完整矩阵。

    一直到第五步,我很高兴,但我不知道该怎么办。没有一个处理器具有完整的10x5矩阵。一开始我认为我不需要一个,我想要这样的东西:

      foreach(procX in proc(0-9))
          showColumn(procX)
    
  7. 但我不知道在MPI_Barrier之后将调用哪个处理器,我不知道如何以处理器的顺序打印事物(否则矩阵将无法正确打印)。

    有没有人知道如何处理这个问题?我已经阅读了很多关于让每个处理器在矩阵的某些部分上工作的内容,但是我找不到关于如何将这些不同部分组合起来的任何内容。

    我没有在我的代码中使用分散(即,不使用主从技术)

    由于

2 个答案:

答案 0 :(得分:1)

虽然可以让每个等级打印出自己的本地部分并按照suszterpatt给出的答案进行同步,但它依赖于不属于MPI标准的功能,因此无法保证始终有效并且仅推荐用于诊断用途。

首先,有些机器及其相应的MPI实现不允许除0级以外的任何等级发送到其标准输出。其次,即使所有等级的标准输出都被重定向到mpiexec进程,它通常也会被缓冲。因此,即使使用障碍强制执行打印顺序,也可能在排名i+1的输出之前显示排名i的标准输出。换句话说,MPI不提供显式刷新操作(例如fflush(stdout)之类的操作),可以强制将本地标准输出缓冲区发送到mpiexec并由后者显示。由实现决定如何处理它。

更多符合标准的方法是让每个等级将其矩阵的一部分发送到等级0,然后打印出来:

if (rank == 0)
{
   allocate temp_buffer;
   for (i = 1; i < num_procs; i++)
   {
       receive from rank i into temp_buffer
       print temp_buffer
   }
}
else
{
   send local matrix part to rank 0
}

这样就不会使用明确的屏障同步,并且因为只有一个过程输出所显示的行的顺序是有保证的。

另一个选择是让每个等级打印到本地字符串缓冲区 - 例如使用sprintf - 然后将缓冲区发送到0级并让后者显示接收到的字符串。

答案 1 :(得分:0)

如果您不想在单个进程上收集整个矩阵,可以使用如下循环:

for ( i = 0; i < 9; i++ )
{
    if ( i == myRank )
    {
        // print local matrix
    }
    MPI_Barrier(MPI_COMM_WORLD);
}