2012-07-28 46 views
4

我想在一个函数中使用多进程,我该如何做到这一点。如你所知,MPI_Init需要两个参数:“int argc,char ** argv”。这是否意味着我必须在函数定义中添加这两个参数?如何初始化函数中的MPI?

我的要求是我想在功能上并行一步而不是主程序中的一步。

例如,

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

你似乎对MPI是什么有一个基本的误解。 MPI提供跨行列的通信和同步机制(即至少在所有有趣的实现中,rank *是一个进程......)。特别是,整个可执行文件需要在每个等级中重复 - “main”和“func”。您尝试的并行性可能更好地通过线程实现,可能使用OpenMP。 – 2012-07-29 20:03:49

回答

0

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

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

原则上功能不必知道关于argcargv,是吗?

6

你并不需要通过argcargv出现自MPI-2解禁MPI-1是compilant实现限制可能需要参数MPI_Init是相同参数main

在MPI-2实现中不允许强制执行此要求。需要遵循MPI的实施方案,以允许应用程序通过和argv参数main通过NULL

但是你还是要测试是否MPI已经初始化,因为MPI_Init()(或MPI_Init_thread())应该叫不超过一次。这是使用MPI_Initialized()完成的,所以你的代码应该是这样的:

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可以初始化,然后应用程序的整个生命周期中完成一次。如果要多次调用该函数,那么MPI_Init() ... MPI_Finalize()的函数代码块将不起作用,即MPI的功能与OpenMP并行地执行的功能不同。

顺便说一下,如果我可以初始化MPI int func,那么这个时候每个进程都存在吗?

一个正在运行的MPI程序由多个进程组成,并带有它们自己的专用地址空间。通常这些是相同程序代码(所谓的单一程序多个数据或SPMD范例)的多个副本,但也可以是被编写为一起工作的多个程序的多个副本(也称为多个程序多个数据或MPMD)。 SPMD是一种更简单和更常见的情况,即所有进程都执行完全相同的代码,直到其MPI级别用于将执行分支到多个方向。所以是的,A存在于每个进程中,并且如果在前面的计算中不涉及(伪)随机数/事件,则在MPI库的初始化之前,每个MPI进程中的A将具有相同的值。请注意0​​只是一个普通的库调用,就像任何其他库调用一样。它不会更改用户内存的内容 - 它只会让大量运行中的MPI进程相互了解并使它们能够相互通信,从而使它们能够共同工作以解决特定问题。