等到奴隶调用MPI_finalize

时间:2016-03-14 20:25:43

标签: c mpi openmpi

我在使用以下代码时遇到问题:

站长:

#include <iostream> 
using namespace std;

#include "mpi.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#define PB1 1
#define PB2 1

int main (int argc, char *argv[])
{
  int np[2] = { 2, 1 }, errcodes[2];
  MPI_Comm parentcomm, intercomm;
  char *cmds[2] = { "./slave", "./slave" };
  MPI_Info infos[2] = { MPI_INFO_NULL, MPI_INFO_NULL };  
  MPI_Init(NULL, NULL);

#if PB1
  for(int i = 0 ; i<2 ; i++)
    {
      MPI_Info_create(&infos[i]);      
      char hostname[] = "localhost";
      MPI_Info_set(infos[i], "host", hostname);
    }
#endif

  MPI_Comm_spawn_multiple(2, cmds, MPI_ARGVS_NULL, np, infos, 0, MPI_COMM_WORLD, &intercomm, errcodes);  
  printf("c Creation of the workers finished\n");

#if PB2
  sleep(1);
#endif

  MPI_Comm_spawn_multiple(2, cmds, MPI_ARGVS_NULL, np, infos, 0, MPI_COMM_WORLD, &intercomm, errcodes);
  printf("c Creation of the workers finished\n");

  MPI_Finalize();
  return 0;
}

从站:

#include "mpi.h"
#include <stdio.h>

using namespace std;

int main( int argc, char *argv[])
{
  int rank;
  MPI_Init(0, NULL);

  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
  printf("rank =  %d\n", rank);

  MPI_Finalize();  
  return 0;
}

我不知道为什么当我运行 mpirun -np 1 ./master 时,当我将PB1和PB2设置为1时,我的程序会停止以下消息(当我设置的时,它运行良好他们到0):

  

系统中没有足够的插槽可满足2   应用程序请求的插槽:./ slave Either   为您的应用程序请求更少的插槽,或提供更多的插槽   使用。

例如,当我将PB2设置为0时,程序运行良好。因此,我认为这是因为MPI_finalize没有完成它的工作......

我用谷歌搜索,但我没有找到任何答案。我尝试了各种各样的事情:调用MPI_comm_disconnect,添加障碍,......但没有任何效果。

我在Ubuntu(15.10)上工作并使用OpenMPI版本1.10.2。

1 个答案:

答案 0 :(得分:1)

第一组药膏上的MPI_Finalize将无法完成,直到主人调用MPI_Finalize为止。 MPI_Finalize是所有相关流程的集体。您可以通过在调用MPI_Finalize之前手动断开第一批salves与intercommunicator的连接来解决这个问题。这样,奴隶实际上将完成并退出 - 释放新一批奴隶的“槽”。遗憾的是,我没有看到一种标准化的方法来真正确保从属设备在其插槽被释放的意义上完成,因为这将是实现定义的。 OpenMPI在MPI_Comm_spawn_multiple中冻结而不是返回错误的事实是不幸的,人们可能会认为这是一个错误。无论如何,这是你可以做的草案:

在主人内部,每次都完成了奴隶:

MPI_Barrier(&intercomm); // Make sure master and slaves are somewhat synchronized
MPI_Comm_disconnect(&intercomm);
sleep(1); // This is the ugly unreliable way to give the slaves some time to shut down

奴隶:

MPI_Comm parent;
MPI_Comm_get_parent(&parent); // you should have that already
MPI_Comm_disconnect(&parent);
MPI_Finalize();  

但是,您仍然需要确保OpenMPI知道应该为整个应用程序保留多少个插槽(universe_size)。例如,您可以使用hostfile

执行此操作
localhost slots=4

然后mpirun -np 1 ./master

现在这并不漂亮,我认为你动态生成MPI工作者的方法并不是MPI的意思。它可能受标准支持,但如果实施正在挣扎,这对您没有帮助。但是,没有足够的信息表明您打算如何与外部流程进行通信,以提供更清晰,更具思想性的解决方案。

最后一句话:检查MPI功能的返回码。特别是MPI_Comm_spawn_multiple