使用MPI_Comm_spawn创建子进程

eri*_*ess 2 c mpi openmpi spawn

有人可以解释为什么即使我将进程数设置为1以上,也只在下面的代码中创建了两个进程子进程.每个MPI_Comm_spawn可以使用下面的代码创建两个子进程,在使用的代码中使用mpirun创建的每个进程将调用MPI_Comm_spawn一次并将创建2(#define NUM_SPAWNS 2)子进程,所以如果我调用N进程然后子进程2*N进程必须创造孩子.但这不会发生.

在下面的例子中,孩子的数量必须是4*2 = 8.但......

例如:

:〜$ mpirun -np 4 ./spawn_example

输出:

我是父母.

我是父母.

我是父母.

我是父母.

我是产卵的.

我是产卵的.

以下示例代码说明了MPI_Comm_spawn.

Hri*_*iev 8

你好像误解了什么MPI_Comm_spawn.这是一个集体调用,它不会n为每个级别生成额外的进程,而是它会生成具有n进程的子MPI作业,因此会增加进程n的总数.调用时n = 2,它会生成一个包含2个进程的子作业,这正是您在输出中观察到的内容.

  • 不,MPI没有按等级子进程的概念.更重要的是,使用`MPI_Comm_spawn`生成的进程可能最终会出现一组完全不同的CPU(或集群节点),而不是最初属于MPI作业的进程.您可以使用`fork()`来启动每个级别的子进程,但这是非标准的,并且不受所有MPI实现的支持(例如,在Blue Gene/Q上). (3认同)

小智 5

只要 MPI_Comm_spawn 是集体调用,您就可以使用 MPI_COMM_SELF 为该特定父级创建子级:

家长:

// Child communicator
MPI_Comm child;
// spawn errors
int spawnError[N];
// Spawn 2 child process for each process
MPI_Comm_spawn("./child", MPI_ARGV_NULL, 2, MPI_INFO_NULL, 0, MPI_COMM_SELF, &child, spawnError);
// Broadcast world id for current parent process to children
int myid;
MPI_Comm_rank(MPI_COMM_WORLD, &myid);
MPI_Bcast(&myid,1,MPI_INT,MPI_ROOT,child);
Run Code Online (Sandbox Code Playgroud)

孩子:

// Obtain an intercommunicator to the parent MPI job
MPI_Comm parent;
MPI_Comm_get_parent(&parent);
// Get child rank
int myid;
MPI_Comm_rank(MPI_COMM_WORLD, &myid);
// Check if this process is a spawned one and if so get parent CPU rank
if (parent != MPI_COMM_NULL) {
  int parent_id;
  MPI_Bcast(&parent_id, 1, MPI_INT,0, parent);
  std::cout<<"Child "<<myid<<" of Parent "<<parent_id<<std::endl;
}
Run Code Online (Sandbox Code Playgroud)

结果将是:

> mpirun -np 4 parent
Child 0 of Parent 2
Child 0 of Parent 1
Child 0 of Parent 0
Child 0 of Parent 3
Child 1 of Parent 0
Child 1 of Parent 2
Child 1 of Parent 1
Child 1 of Parent 3
Run Code Online (Sandbox Code Playgroud)

这种方法的唯一问题是不同父母的孩子永远无法相互交流。