Создание дочернего процесса с MPI_Comm_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.

2 ответа

Решение

Вы, кажется, неправильно поняли, что MPI_Comm_spawn делает. Это коллективный вызов, и он не порождает n дополнительные процессы на ранг, а скорее порождает дочернюю работу MPI с n процессы, поэтому добавление n к общему количеству процессов. Когда вызывается с n = 2это порождает дочернюю работу с 2 процессами, и это именно то, что вы наблюдаете в выводе.

Пока 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

Единственная проблема для этого подхода состоит в том, что дети другого родителя никогда не смогут общаться друг с другом.

Это зависит от параметра связи. Если вы используете MPI_COMM_SELF, тогда каждый мастер создаст n процессов, но если вы используете MPI_COMM_WORLD среди всех мастеров, создаст n процессов. Итак, если у вас есть 2 мастера, в первом случае вы собираетесь создать 2 * n процессов. Во втором случае вы собираетесь создать n процессов.

Другие вопросы по тегам