2 个静态进程的问题,它使用 open mpi 创建 2 个动态进程
Problem with 2 static process which creates 2 dynamic process with open mpi
程序必须创建两个静态进程,我们可以调用它们 m0 和 m1。
每个主进程(m0 和 m1)必须使用 mpi_spawn 动态创建 2 个 child 进程。 m0 master 必须通过一次 bcast 调用对所有进程进行 bcast。
我不知道该如何解决。
下面的代码将是有效的,例如,如果每个 master 都对自己的 children 进行 bcast,但不能将它们发送到另一个 master 的 children。
我想我应该创建一个 intracom,但我不知道该怎么做
#include "mpi.h"
#include "stdio.h"
#define PROCESOS 2
int main(int argc, char *argv[])
{
int rank, size, n = 1234, size_intercom, size_remote;
MPI_Comm intercom, iguales;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_get_parent(&intercom); // Para conocer si tiene padre o no
if (intercom == MPI_COMM_NULL)
{
MPI_Comm_spawn(argv[0], MPI_ARGV_NULL, PROCESOS, MPI_INFO_NULL, 0, MPI_COMM_SELF, &intercom, MPI_ERRCODES_IGNORE);
printf("soy maestro %d\n", rank);
MPI_Comm_size(intercom, &size_intercom);
MPI_Comm_remote_size(MPI_COMM_WORLD, &size_remote);
printf("procesos en intercom %d, en remoto %d \n", size_intercom, size_remote);
MPI_Bcast(&n, 1, MPI_INT, MPI_ROOT, intercom);
}
else
{
// MPI_Intercomm_merge(intercom, 1, &iguales);
MPI_Bcast(&n, 1, MPI_INT, 0, intercom);
printf("soy hijo %d, recibo %d\n", rank, n);
}
MPI_Finalize();
return 0;
}
版本 2.0:
我想知道这是否是一种方法,但我无法得到预期的结果:
if (intercom == MPI_COMM_NULL)
{
if (rank == 0)
{
n = 1234;
}
MPI_Comm_spawn(argv[0], MPI_ARGV_NULL, PROCESOS, MPI_INFO_NULL, 0, MPI_COMM_SELF, &intercom, MPI_ERRCODES_IGNORE);
MPI_Intercomm_merge(intercom, 0, &iguales);
MPI_Intercomm_create(MPI_COMM_SELF, 0, iguales, 1, 1, &todos);
MPI_Bcast(&n, 1, MPI_INT, MPI_ROOT, todos);
printf("I'M MASTER rank: %d, i get: %d\n", rank, n);
}
else
{
MPI_Intercomm_merge(intercom, 1, &iguales);
MPI_Intercomm_create(MPI_COMM_WORLD, 0, iguales, 0, 1, &todos);
MPI_Bcast(&n, 1, MPI_INT, 0, todos);
printf("I'm a child %d, i get: %d\n", rank, n);
}
通过之前的修改,我得到的结果与通过 de intercom comnunicator intercom 进行 bcast 相同。我不明白为什么:
I'M MASTER rank: 1, i get: 0
I'm a child 0, i get: 0
I'm a child 1, i get: 0
I'M MASTER rank: 0, i get: 1234
I'm a child 1, i get: 1234
I'm a child 0, i get: 1234
如果您无法改造您的应用程序以便两个主节点一起生成四个从节点,或者您无法使用两步广播,那么您可以通过以下方法获得所需的结果。
#include "mpi.h"
#include "stdio.h"
#define PROCESSES 2
int main(int argc, char *argv[])
{
int rank, size, n = -1, remote_leader = -1;
int master;
MPI_Comm intercomm, mergedcomm, universe_inter, universe;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_get_parent(&intercomm);
if (MPI_COMM_NULL == intercomm)
{
printf("I am master %d\n", rank);
MPI_Comm_spawn(argv[0], MPI_ARGV_NULL, PROCESSES, MPI_INFO_NULL, 0, MPI_COMM_SELF, &intercomm, MPI_ERRCODES_IGNORE);
MPI_Bcast(&rank, 1, MPI_INT, MPI_ROOT, intercomm);
master = rank;
remote_leader = master^1;
if (0 == rank) {
n = 1234;
}
}
else
{
MPI_Bcast(&master, 1, MPI_INT, 0, intercomm);
printf("I am slave %d from master %d\n", rank, master);
}
/* make sure the master rank has rank 0 in the merged communicator */
MPI_Intercomm_merge(intercomm, (NULL==MPI_COMM_NULL)?0:1, &mergedcomm);
MPI_Intercomm_create(mergedcomm, 0, MPI_COMM_WORLD, remote_leader, 0, &universe_inter);
/* make sure master 0 has rank 0 in the universe */
MPI_Intercomm_merge(universe_inter, master, &universe);
MPI_Comm_free(&mergedcomm);
MPI_Bcast(&n, 1, MPI_INT, 0, universe);
printf ("n = %d\n", n);
MPI_Comm_free(&universe);
MPI_Comm_disconnect(&intercomm);
MPI_Finalize();
return 0;
}
程序必须创建两个静态进程,我们可以调用它们 m0 和 m1。
每个主进程(m0 和 m1)必须使用 mpi_spawn 动态创建 2 个 child 进程。 m0 master 必须通过一次 bcast 调用对所有进程进行 bcast。 我不知道该如何解决。 下面的代码将是有效的,例如,如果每个 master 都对自己的 children 进行 bcast,但不能将它们发送到另一个 master 的 children。 我想我应该创建一个 intracom,但我不知道该怎么做
#include "mpi.h"
#include "stdio.h"
#define PROCESOS 2
int main(int argc, char *argv[])
{
int rank, size, n = 1234, size_intercom, size_remote;
MPI_Comm intercom, iguales;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_get_parent(&intercom); // Para conocer si tiene padre o no
if (intercom == MPI_COMM_NULL)
{
MPI_Comm_spawn(argv[0], MPI_ARGV_NULL, PROCESOS, MPI_INFO_NULL, 0, MPI_COMM_SELF, &intercom, MPI_ERRCODES_IGNORE);
printf("soy maestro %d\n", rank);
MPI_Comm_size(intercom, &size_intercom);
MPI_Comm_remote_size(MPI_COMM_WORLD, &size_remote);
printf("procesos en intercom %d, en remoto %d \n", size_intercom, size_remote);
MPI_Bcast(&n, 1, MPI_INT, MPI_ROOT, intercom);
}
else
{
// MPI_Intercomm_merge(intercom, 1, &iguales);
MPI_Bcast(&n, 1, MPI_INT, 0, intercom);
printf("soy hijo %d, recibo %d\n", rank, n);
}
MPI_Finalize();
return 0;
}
版本 2.0: 我想知道这是否是一种方法,但我无法得到预期的结果:
if (intercom == MPI_COMM_NULL)
{
if (rank == 0)
{
n = 1234;
}
MPI_Comm_spawn(argv[0], MPI_ARGV_NULL, PROCESOS, MPI_INFO_NULL, 0, MPI_COMM_SELF, &intercom, MPI_ERRCODES_IGNORE);
MPI_Intercomm_merge(intercom, 0, &iguales);
MPI_Intercomm_create(MPI_COMM_SELF, 0, iguales, 1, 1, &todos);
MPI_Bcast(&n, 1, MPI_INT, MPI_ROOT, todos);
printf("I'M MASTER rank: %d, i get: %d\n", rank, n);
}
else
{
MPI_Intercomm_merge(intercom, 1, &iguales);
MPI_Intercomm_create(MPI_COMM_WORLD, 0, iguales, 0, 1, &todos);
MPI_Bcast(&n, 1, MPI_INT, 0, todos);
printf("I'm a child %d, i get: %d\n", rank, n);
}
通过之前的修改,我得到的结果与通过 de intercom comnunicator intercom 进行 bcast 相同。我不明白为什么:
I'M MASTER rank: 1, i get: 0
I'm a child 0, i get: 0
I'm a child 1, i get: 0
I'M MASTER rank: 0, i get: 1234
I'm a child 1, i get: 1234
I'm a child 0, i get: 1234
如果您无法改造您的应用程序以便两个主节点一起生成四个从节点,或者您无法使用两步广播,那么您可以通过以下方法获得所需的结果。
#include "mpi.h"
#include "stdio.h"
#define PROCESSES 2
int main(int argc, char *argv[])
{
int rank, size, n = -1, remote_leader = -1;
int master;
MPI_Comm intercomm, mergedcomm, universe_inter, universe;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_get_parent(&intercomm);
if (MPI_COMM_NULL == intercomm)
{
printf("I am master %d\n", rank);
MPI_Comm_spawn(argv[0], MPI_ARGV_NULL, PROCESSES, MPI_INFO_NULL, 0, MPI_COMM_SELF, &intercomm, MPI_ERRCODES_IGNORE);
MPI_Bcast(&rank, 1, MPI_INT, MPI_ROOT, intercomm);
master = rank;
remote_leader = master^1;
if (0 == rank) {
n = 1234;
}
}
else
{
MPI_Bcast(&master, 1, MPI_INT, 0, intercomm);
printf("I am slave %d from master %d\n", rank, master);
}
/* make sure the master rank has rank 0 in the merged communicator */
MPI_Intercomm_merge(intercomm, (NULL==MPI_COMM_NULL)?0:1, &mergedcomm);
MPI_Intercomm_create(mergedcomm, 0, MPI_COMM_WORLD, remote_leader, 0, &universe_inter);
/* make sure master 0 has rank 0 in the universe */
MPI_Intercomm_merge(universe_inter, master, &universe);
MPI_Comm_free(&mergedcomm);
MPI_Bcast(&n, 1, MPI_INT, 0, universe);
printf ("n = %d\n", n);
MPI_Comm_free(&universe);
MPI_Comm_disconnect(&intercomm);
MPI_Finalize();
return 0;
}