如何在函数中初始化MPI?

时间:2012-07-28 12:03:36

标签: c++ c parallel-processing mpi

我想在一个函数中使用多个进程,我该怎么做。

如您所知,MPI_Init需要两个参数:“int argc,char ** argv”。这是否意味着我必须在函数定义中添加这两个参数?

我的要求是我希望并行化一个功能步骤而不是主程序中的步骤。

例如,

func(mat &A, vec &x) {
  some computation on A;
  auto B = sub_mat(A, 0, 10);
  B*x; // I want to parallelize this computation
}
main(){
  mat A;
  vec x;
  func(A, x);
}

我只想在B * x中使用MPI,但我不知道如何初始化MPI?顺便说一句,如果我可以初始化MPI int func,那么此时每个进程中是否都存在A?

帮助我&谢谢!

2 个答案:

答案 0 :(得分:9)

你不需要传递argcargv,因为MPI-2解除了MPI-1中的限制,编译实现可能需要{{1}的参数}与MPI_Init的参数相同:

  

在MPI-2中,不允许实施此要求。需要符合MPI的实现,以允许应用程序为main的{​​{1}}和NULL参数传递argc

但是你仍然必须测试MPI是否已经初始化,因为argv(或main)应该被调用不超过一次。这是使用MPI_Init()完成的,因此您的代码应如下所示:

MPI_Init_thread()

请注意,MPI可以初始化,然后在应用程序的整个生命周期内只完成一次。如果要多次调用函数,那么使用MPI_Initialized()的函数代码块将无法工作,即MPI的功能与OpenMP及其并行区域的功能相同。

  

顺便说一下,如果我可以初始化MPI int func,那么此时每个进程中是否都存在A?

正在运行的MPI程序由多个进程组成,并带有自己的私有地址空间。通常这些是相同程序代码的多个副本(所谓的单程序多数据或SPMD范例),但也可以是多个程序的多个副本,一起编写(也称为多程序多数据或MPMD)。 SPMD是更简单和更常见的情况,其中所有进程执行完全相同的代码,直到使用其MPI等级将执行分支到多个方向的点。所以是的,int initialized, finalized; MPI_Initialized(&initialized); if (!initialized) MPI_Init(NULL, NULL); // Perform work in parallel ... // You also need this when your program is about to exit MPI_Finalized(&finalized); if (!finalized) MPI_Finalize(); 存在于每个进程中,如果前面的计算中没有(伪)随机数/事件,那么MPI_Init() ... MPI_Finalize()在初始化之前的每个MPI进程中将具有相同的值。 MPI库。请注意,A只是与任何其他库调用一样的常规库调用。它不会改变用户内存的内容 - 它只会使大量运行MPI进程相互了解并使它们能够相互通信,从而使它们能够集体工作以解决特定问题。

答案 1 :(得分:0)

如果您想在子功能中使用MPI_Init,则必须将int argc, char **argv传递给该功能,以便将其传递。

但是,即使您只想并行化子功能的一部分,您也可以(并且应该为了更透明的代码)在程序的早期使用MPI_Init。例如。在完成其他初始化之后,或者如果您想在调用函数之前将其用于接近并行化函数之后。

原则上,该功能不必了解argcargv,是吗?