MPICH:如何publish_name 以便客户端应用程序可以lookup_name 呢?

Posted

技术标签:

【中文标题】MPICH:如何publish_name 以便客户端应用程序可以lookup_name 呢?【英文标题】:MPICH: How to publish_name such that a client application can lookup_name it? 【发布时间】:2012-12-22 01:04:14 【问题描述】:

在 windows (1.4.1p1) 中使用 MPICH 学习 MPI 时,我发现了一些示例代码 here。最初,当我运行服务器时,我必须复制生成的port_name 并使用它启动客户端。这样,客户端可以连接到服务器。我将其修改为在服务器中包含MPI_Publish_name()。启动名称为aaaa 的服务器后,我启动失败的客户端MPI_Lookup_name()

Invalid service name (see MPI_Publish_name), error stack:
MPID_NS_Lookup(87): Lookup failed for service name aaaa

以下是代码片段:

服务器.c

MPI_Comm client; 
MPI_Status status; 
char port_name[MPI_MAX_PORT_NAME];
char serv_name[256];
double buf[MAX_DATA]; 
int size, again; 
int res = 0;

MPI_Init( &argc, &argv ); 
MPI_Comm_size(MPI_COMM_WORLD, &size); 
MPI_Open_port(MPI_INFO_NULL, port_name);
sprintf(serv_name, "aaaa");
MPI_Publish_name(serv_name, MPI_INFO_NULL, port_name);

while (1) 
 
    MPI_Comm_accept( port_name, MPI_INFO_NULL, 0, MPI_COMM_WORLD, &client );
    /*...snip...*/

client.c

MPI_Comm server; 
double buf[MAX_DATA]; 
char port_name[MPI_MAX_PORT_NAME]; 
memset(port_name,'\0',MPI_MAX_PORT_NAME);
char serv_name[256];
memset(serv_name,'\0',256);

strcpy(serv_name, argv[1] )
MPI_Lookup_name(serv_name, MPI_INFO_NULL, port_name);
MPI_Comm_connect( port_name, MPI_INFO_NULL, 0, MPI_COMM_WORLD, &server ); 
MPI_Send( buf, 0, MPI_DOUBLE, 0, tag, server ); 
MPI_Comm_disconnect( &server ); 
MPI_Finalize(); 
return 0; 

我找不到有关更改已发布名称的可见性的任何信息,如果这甚至是问题的话。 MPICH 似乎没有用 MPI_INFO 实现任何东西。我会尝试 openMPI,但我在构建它时遇到了麻烦。有什么建议吗?

【问题讨论】:

我也有同样的问题。我认为只有在使用 mpirun 在多台计算机上启动程序时才能进行通信。我会发布一个新问题,也许我们很幸运。 您能描述一下您要完成的工作吗?如果您只是学习 MPI,我会注意到这是一个非常 晦涩难懂的功能集,我确实从未 看到或听说过在应用程序中使用它。换句话说,这可能不是您应该花时间和精力做的事情。 @Novelocrat 我想让客户端可靠地找到服务器,而无需用户在启动时读取服务器发布的名称。已经有一段时间了,我忘记了很多事情。 (对于任何未来的读者)我正在对 MPI 进行初步探索,以了解它可以做什么,但我没有太多运气并转向其他事情(最终使用 boost asio 来满足我的工作分配需求)。 重点是在启动 MPI 作业时,正常模式是 mpirun 一次性启动所有进程,然后它们是 MPI_COMM_WORLD 的一部分。他们可以在彼此之间发送和接收消息,而无需应用程序方面的进一步设置。除非您正在做一些奇怪的事情,否则只需启动并运行具有一些工作分配的并行程序应该是微不足道的。 @Novelocrat 如果我错了,请纠正我,但是工作分配是否意味着其他计算机的网络?确定mpirun 不能在其他计算机上启动进程?我的理解是,要让其他计算机加入WORLD,他们需要知道服务器的端口,即PUBLISHED。但是,当我在客户端上调用 MPI_Lookup_name 时,他们仍然无法找到服务器所在的位置。 (也许我应该只是复制端口号并将其提供给客户端,完全避免publish_name/lookup_name?) 【参考方案1】:

我在 Ubuntu 上使用 OpenMPI 1.6.5 上传了一个使用 C 语言的客户端和服务器的工作版本,这里使用 ompi-server 名称服务器:

OpenMPI nameserver client server example in C

【讨论】:

【参考方案2】:

(挖掘旧东西) 对于 MPICH,@daemondave 的代码实际上也应该可以工作。 但是,它仍然需要运行名称服务器。 对于 MPICH,可以使用 hydra_nameserver 来代替使用 ompi-server。 然后必须使用 -nameserver HOSTNAME 为所有 mpirun/mpiexec 调用指定主机。

我在 github 创建了一个工作示例,它还提供了一个 shell 脚本来构建和运行该示例。

P.S:ompi-server 变体似乎有些过时(并且包含一些错误)。 有关更新但仍然有些未记录的替代方案,请参阅this comment。

【讨论】:

【参考方案3】:

相对于正常的 MPI 使用而言,这种发布名称、查找名称并连接到名称的方法很奇怪。

标准模式是使用mpirun 指定一组节点,在这些节点上启动给定数量的进程。 mpirun实现的常用实现的操作在another question中解释

一旦所有进程都作为单个并行作业的一部分启动,MPI 库会读取启动器在MPI_Init 期间提供的任何信息,以设置MPI_COMM_WORLD,这是作业中所有进程组的通信器。

使用该通信器,并行应用程序可以分发工作、交换信息等。它将使用常见的MPI_SendMPI_Recv 例程、在它们的所有变体、集体操作等中执行此操作。

【讨论】:

您发现此功能集不常用(因为您从未使用过)这一事实并不意味着没有其他人使用它。该问题询问有关用于设置 MPI 客户端/服务器通信的名称发布的具体问题。事实上,这是一个非常普遍的特征,特别是对于广泛使用的代码耦合系统,例如,在科学计算中耦合两个(许多)独立(不同的可执行文件)求解器。例如,如果要模拟流体/结构相互作用,则流体求解器和结构求解器是耦合的。抱歉,-1 打扰您了。 这个场景怎么样:我在一个至少有两种不同处理器类型的集群上,我想使用这两种类型运行客户端/服务器或 MPDM。但是,集群管理员只允许我提交一种或另一种类型的作业。通过名称发布机制,我可以单独启动程序,然后将它们连接起来。 @victor:这将很好地利用原始问题中描述的功能。操作员显然是一个希望了解基本常见案例操作的新用户。

以上是关于MPICH:如何publish_name 以便客户端应用程序可以lookup_name 呢?的主要内容,如果未能解决你的问题,请参考以下文章

如何查看 MPICH 的版本?

我是用 OpenMPI 还是 MPICH 编译的?

如何在 MPICH 中使用 MPI_Info_set 和 MPI_Comm_spawn

MPICH配置安装与入门

MPICH2 gethostbyname 失败

MPICH安装