有人可以解释为什么即使我将进程数设置为1以上,也只会在下面的代码中创建两个进程子进程。每个MPI_Comm_spawn可以使用下面的代码创建两个子进程,在使用的代码中使用mpirun创建的每个进程将调用MPI_Comm_spawn一次并将创建2(#define NUM_SPAWNS 2)子进程,所以如果我调用N进程然后子进程2 * N进程必须创造孩子。但这不会发生。
在下面的例子中,孩子的数量必须是4 * 2 = 8.但是......
例如:
:〜$ mpirun -np 4 ./spawn_example
输出:
我是父母。
我是父母。
我是父母。
我是父母。
我是产卵的。
我是产卵的。
答案 0 :(得分:7)
您似乎误解了MPI_Comm_spawn
的作用。这是一个集体调用,它不会为每个级别生成n
个额外进程,而是生成具有n
进程的子MPI作业,因此将n
添加到进程总数中。使用n = 2
调用时,它会生成一个包含2个进程的子作业,这正是您在输出中观察到的内容。
答案 1 :(得分:1)
只要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);
子:
// 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;
}
结果将是:
> 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
这种方法的唯一问题是不同父母的孩子永远不能相互沟通。
答案 2 :(得分:0)
这取决于comm参数。如果使用MPI_COMM_SELF,则每个主节点将创建n个进程,但是如果在所有主节点中使用MPI_COMM_WORLD,则将创建n个进程。 因此,如果在第一种情况下您有2个主服务器,则您将要创建2 * n个进程。在第二种情况下,您将创建n个进程。