【问题标题】:the error of MPI initializationMPI初始化错误
【发布时间】:2015-03-18 13:16:25
【问题描述】:

我有一个关于并行性的问题。我有一部分代码应用了并行化的概念,这部分代码必须在循环中重复 N 次,但我无法在循环中初始化 MPI,因为显示“MPI_Init(89): 无法调用 MPI_INIT 或MPI_INIT_THREAD 不止一次”,如果我在循环之前启动每个进程,它将处理所有循环,这不是目标。

for (int i = 0; i <N; i ++)
{
the parallel area
}

我希望对于循环中的每个 i,K 个进程执行并行区域。

【问题讨论】:

  • 发布所有相关代码。在我看来,您将 MPI 与 OpenMP 混淆了。在 MPI 中,内存不共享(在最简单的情况下),所有进程都通过MPI_Init 生成一次(在最简单的情况下)。
  • 我的程序的想法是我有 N 个数据,在给定的第 n 个计算结果取决于对第 (n-1) 个数据的计算结果,因此对每个数据进行计算数据必须是顺序的,对于每个数据 n 我可以将其划分为子独立数据,我可以应用并行化。
  • 你了解 MPI hello world 示例吗?
  • 第n个值是数组吗?
  • yes 是一个数组,它依赖于第 (n-1) 个数组的计算结果,我将根据数据 n 进行并行计算。

标签: c parallel-processing mpi


【解决方案1】:

在您的情况下分配计算的规范方法是在所有 MPI 进程中运行循环,并使除 0 级以外的每个等级跳过串行部分:

// Obtain the rank
int rank;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);

for (i = 0; i < N; i++)
{
   if (rank == 0)
   {
      // Some serial calculations
   }

   //
   // Parallel part
   //

   if (rank == 0)
   {
      // More serial calculations within the loop
   }
}

如果您需要在串行计算中传递 rank 0 中产生的数据,您可以在并行部分的开头使用点对点操作或 MPI_BcastMPI_Scatter 等集合。然后,您可以在并行块末尾使用MPI_GatherMPI_Reduce 将分布式数据带回等级 0 以在第二个串行部分中进行进一步处理。

另一种规范的方法是使用主从模式,其中一个进程(主进程)将工作项分配给一组工作进程,这些进程只是在接收工作的循环中旋转 -> 处理工作 -> 返回结果


关于 MPI 的多次初始化,可以检查是否已经完成:

int done_already;

MPI_Initialized(&done_already);
if (!done_already)
   MPI_Init(NULL, NULL);

请注意,一旦您通过调用 MPI_Finalize 完成 MPI,它无法在程序当前执行期间重新初始化。

【讨论】:

  • 我在网上搜索,发现 MPI_Initialized 是可以用来判断 MPI_INIT 是否被调用的例程,那么在我的情况下 MPI_Initialized 有什么用处
  • 我真的误读了您的问题 - 标题非常混乱。请参阅更新的答案。此外,您可能会更好地使用 OpenMP。
  • 在您引用的示例中,循环和并行部分将由进程之一执行,因此不是目标。
  • 不,循环将在所有等级中执行。执行冗余操作在 MPI 中很常见。只有if (rank == 0) { ... } 中包含的部分才会在单个进程中执行。
  • 我想要的是只有所有进程执行的并行部分而不是循环,如果进程从不执行循环,那么当我恢复使用结果时会给我一个延迟在接下来的数据中
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-08
  • 2017-04-05
  • 2019-08-05
  • 2013-04-12
  • 2018-08-27
  • 2015-04-06
相关资源
最近更新 更多