【问题标题】:Can MPI_Publish_name be used for two separately started applications?MPI_Publish_name 可以用于两个单独启动的应用程序吗?
【发布时间】:2013-02-07 01:35:44
【问题描述】:

我编写了一个 OpenMPI 应用程序,它由一个服务器和一个客户端部分组成,分别启动:

me@server1:~> mpirun server

me@server2:~> mpirun client

server 使用MPI_Open_port 创建一个端口。问题是:OpenMPI 是否有将端口与client 通信的机制?我想MPI_Publish_nameMPI_Lookup_name 在这里不起作用,因为server 不知道应该将信息发送到哪台其他计算机。

在我看来,似乎只有使用单个 mpirun 启动的进程才能与 MPI_Publish_name 通信。

我还找到了ompi-server,但文档过于简约,我无法理解这一点。有谁知道这是怎么用的吗?

相关:MPICH: How to publish_name such that a client application can lookup_name it?https://stackoverflow.com/questions/9263458/client-server-example-using-ompi-does-not-work

【问题讨论】:

    标签: mpi openmpi


    【解决方案1】:

    MPI_Publish_name 提供了一个 MPI 信息对象,它可能有一个 Open MPI 特定的布尔键 ompi_global_scope。如果此键设置为 true,则名称将发布到全局范围,即发布到已运行的 ompi-server 实例。如果提供了ompi-server 的URI,则MPI_Lookup_name 默认首先进行全局名称查找。

    使用专用的 Open MPI 服务器

    这个过程涉及几个步骤:

    1) 在集群中可以从所有节点访问的某个位置启动ompi-server。出于调试目的,您可以将--no-daemonize -r + 参数传递给它。它会启动并向标准输出打印一个类似于此的 URI:

    $ ompi-server --no-daemonize -r +
    1221656576.0;tcp://10.1.13.164:36351;tcp://192.168.221.41:36351
    

    2) 在服务器中,构建一个 MPI 信息对象并将 ompi_global_scope 键设置为 true:

    MPI_Info info;
    
    MPI_Info_create(&info);
    MPI_Info_set(info, "ompi_global_scope", "true");
    

    然后将 info 对象传递给MPI_Publish_name

    MPI_Publish_name("server", info, port_name);
    

    3) 在客户端中,对 MPI_Lookup_name 的调用将首先自动在全局上下文中进行查找(这可以通过在 MPI 信息对象中提供正确的键来更改,但在您的情况下,默认行为就足够了)。

    为了让客户端和服务器代码都知道ompi-server 的位置,您必须使用--ompi-server 1221656576.0;tcp://10.1.13.164:36351;tcp://192.168.221.41:36351 选项将其URI 提供给mpirun 命令。

    另一种选择是让ompi-server 将URI 写入文件,然后可以在要运行mpirun 的节点上读取该文件。例如,如果您在执行两个mpirun 命令的同一节点上启动服务器,那么您可以使用/tmp 中的文件。如果您在不同的节点上启动ompi-server,则可以使用共享文件系统(NFS、Lustre 等)。无论哪种方式,命令集都是:

    $ ompi-server [--no-daemonize] -r file:/path/to/urifile
    ...
    $ mpirun --ompi-server file:/path/to/urifile server
    ...
    $ mpirun --ompi-server file:/path/to/urifile client
    

    无服务器方法

    如果在同一节点上同时运行两个 mpirun--ompi-server 还可以指定已运行的 mpirun 实例的 PID,以用作名称服务器。它允许您在服务器中使用本地名称发布(即跳过“运行 ompi-server”和“制作信息对象”部分)。命令的顺序是:

    head-node$ mpirun --report-pid server
    [ note the PID of this mpirun instance ]
    ...
    head-node$ mpirun --ompi-server pid:12345 client
    

    其中12345 应替换为服务器mpirun 的真实PID。

    您还可以让服务器的 mpirun 打印其 URI 并将该 URI 传递给客户端的 mpirun

    $ mpirun --report-uri + server
    [ note the URI ]
    ...
    $ mpirun --ompi-server URI client
    

    如果您在--report-uri 选项后指定/path/to/file(注意:此处没有file: 前缀)而不是+,也可以将URI 写入文件:

    $ mpirun --report-uri /path/to/urifile server
    ...
    $ mpirun --ompi-server file:/path/to/urifile client
    

    注意mpirun返回的URI与ompi-server的格式相同,即包括主机IP地址,所以如果第二个mpirun在不同的节点上执行,它也可以工作,这能够通过 TCP/IP 与第一个节点通信(/path/to/urifile 位于共享文件系统上)。

    我使用 Open MPI 1.6.1 测试了以上所有内容。某些变体可能不适用于早期版本。

    【讨论】:

    • 感谢您的出色回答。您是否也知道 URI/port_name 开头的浮点数是如何产生的?我只找到了mpi-forum.org/docs/mpi22-report/node214.htm,但这又不是很有帮助。如果把数字转换成十六进制,前四位全为零……里面信息量不大。
    • 端口名称是特定于实现的,而 URI 是非常特定于 Open MPI 的。 OpenRTE 的rml MCA 组件的源代码中的注释表明URI 以“进程名称”开头。进一步挖掘 ORTE 的 name utility functions 表明,进程名称是两个无符号长整数的串联,形式为 <jobid>.<vpid>
    • 我也进行了一些挖掘,但没有你那么远。我将 "left" unsigned long 与进程 ID 进行了比较——它们不匹配,但它们很接近(例如 12551 和 13225)。这很奇怪。
    • 初始作业 ID 在 PLM(流程生命周期管理)框架的 base 组件中的 orte_plm_base_set_hnp_name() 中计算。显然,该值基于启动器的 PID 和散列主机名。
    • @Z0lenDer,DeinoMPI 基于 MPICH 而不是 Open MPI。您可能应该查阅 DeinoMPI 手册。
    猜你喜欢
    • 1970-01-01
    • 2012-07-05
    • 2016-06-08
    • 1970-01-01
    • 1970-01-01
    • 2013-10-21
    • 2014-04-18
    • 2011-03-27
    • 1970-01-01
    相关资源
    最近更新 更多