首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在MPI中,如何在使用多个可执行文件时获得通信器?

在MPI中,如何在使用多个可执行文件时获得通信器?
EN

Stack Overflow用户
提问于 2019-07-17 14:52:35
回答 3查看 824关注 0票数 3

在MPI中,我们处理多个进程,它们不共享任何东西,只与recv/send操作通信。recv/send操作是针对通信器执行的,通信器可以是整个处理器集,也可以是它们的子集。基本命令如下:

代码语言:javascript
运行
复制
call MPI_Comm_size ( MPI_COMM_WORLD, nproc, ierr )
call MPI_Comm_rank ( MPI_COMM_WORLD, myrank, ierr )

使用MPI_COMM_WORLD,与所有处理器的集合相关联的通信器。MPI的一个有趣的特性是,我们可以与命令一起运行几个可执行文件:

代码语言:javascript
运行
复制
mpirun -n 3 prog1 : -n 2 prog2

将3个节点分配给第一个可执行文件,2个节点分配给第二个可执行文件。然而,对于实际工作,希望有一个与prog1或prog2相关联的通信器。是否有一种不使用MPI_COMM_SPLIT命令直接获取thi的方法

EN

回答 3

Stack Overflow用户

发布于 2019-07-18 00:22:17

没有标准指定的预定义通信器。

伟大的哲学家贾格尔曾经说过:“你不能总是得到你想要的东西”,你最好的选择就是使用MPI_Comm_split()MPI_COMM_WORLDMPI_APPNUM属性的值作为color参数。

来自MPI 3.1标准的第10.5.3章

10.5.3 MPI_APPNUM 有一个预定义的属性MPI_APPNUM of MPI_COMM_WORLD。在Fortran中,属性是一个整数值。在C中,属性是指向整数值的指针。如果进程是用MPI_COMM_SPAWN_MULTIPLE生成的,则MPI_APPNUM是生成当前进程的命令号。编号从零开始。如果一个进程是用MPI_COMM_SPAWN生成的,那么它的MPI_APPNUM将等于零。此外,如果进程不是通过派生调用启动的,而是通过能够处理多个流程规范的实现特定的启动机制启动的,则应该将MPI_APPNUM设置为相应流程规范的数量。特别是,如果它是从 spec0 : spec1 : spec2: 应该将MPI_APPNUM设置为相应规范的编号。 如果应用程序不是由MPI_COMM_SPAWN或MPI_COMM_SPAWN_MULTIPLE生成的,并且MPI_APPNUM在特定于实现的启动机制的上下文中没有意义,则不会设置MPI_APPNUM。 MPI实现还可以提供一种机制,通过info参数覆盖MPI_APPNUM的值。MPI为所有的子程序调用保留以下密钥。 appnum值包含一个整数,该整数覆盖子节点中MPI_APPNUM的默认值。 基本原理。 当一个应用程序启动时,它可以通过查看MPI_COMM_WORLD的大小来确定有多少进程。由多个SPMD子应用程序组成的应用程序无法确定有多少子应用程序以及进程属于哪个子应用程序。虽然有办法在特殊情况下解决这个问题,但却没有一般的机制。MPI_APPNUM提供了这样一种通用机制。(理由终止)

票数 3
EN

Stack Overflow用户

发布于 2019-11-16 14:03:41

对于任何对拆分MPI_COMM_WORLD感兴趣的人,我编写了一个小的实用程序库(一个头)。它将通信器分解成局部的通信器,并在它们之间建立交互器。它处理了许多技术问题:

您可以在:MPMD找到标题

它还为同时运行多个程序和生成程序提供了相同的语法。如果您有任何问题或想法来扩展这一点,请在github上打开一个问题。

例如,在您的第一个程序中:

代码语言:javascript
运行
复制
MPMDHelper MPMD;
MPI_Init(&argc, &argv);
MPMD.Init(MPI_COMM_WORLD, "programA");
MPMD.local //<-- this is your local Comm.

在另一个程序中:

代码语言:javascript
运行
复制
MPMDHelper MPMD;
MPI_Init(&argc, &argv);
MPMD.Init(MPI_COMM_WORLD, "programB");
MPMD.local //<-- this is your local Comm.
MPMD["programA"].local //<-- intercommunicator for communication with programA

希望能帮上忙。

票数 1
EN

Stack Overflow用户

发布于 2019-07-18 11:16:03

另一种选择是使用MPI标准所描述的客户机-服务器机制(有关这一机制的章节可以找到这里)。这里的想法是编译两个独立的MPI应用程序。其中一个最终成为服务器并打开一个连接端口。另一个是必须连接到该端口的客户端。代码将如下所示:

服务器:

代码语言:javascript
运行
复制
program server

    use mpi_f08
    implicit none

    integer :: error
    type(MPI_Comm) :: intercomm

    real, dimension(5) :: data = [1,2,3,4,5]
    character(len=MPI_MAX_PORT_NAME) :: port_name

    ! Normal MPI initialization
    call MPI_Init(error)

    ! Here we open a port for incoming connections
    call MPI_Open_port(MPI_INFO_NULL, port_name, error)
    ! Copy it in order to pass the address to a client
    print*, "PORT NAME:", port_name
    ! Accept the incoming connection creating the intercommunicator
    call MPI_Comm_accept(port_name, MPI_INFO_NULL, 0, MPI_COMM_WORLD, intercomm, error)
    ! Send test data
    call MPI_Send(data, 5, MPI_FLOAT, 0, 0, intercomm)
    print*, "DATA SENT"
    ! Close connection
    call MPI_Comm_disconnect(intercomm, error)

    call MPI_Finalize(error)

end program server

客户端:

代码语言:javascript
运行
复制
program client
    use mpi_f08
    implicit none

    integer :: error
    type(MPI_Comm) :: intercomm
    type(MPI_Status) :: status

    real, dimension(5) :: data = [0,0,0,0,0]
    character(len=MPI_MAX_PORT_NAME) :: port_name

    call MPI_Init(error)

    ! Here we copy the port name obtained from the server
    print*, "Type in port name"
    read(*,*) port_name

    ! Establish a connection creating the intercommunicator
    call MPI_Comm_connect(port_name, MPI_INFO_NULL, 0, MPI_COMM_WORLD, intercomm, error)
    ! Receive test data
    call MPI_Recv(data, 5, MPI_FLOAT, 0, 0, intercomm, status, error)
    print*, "DATA RECEIVED", data
    ! Close connection
    call MPI_Comm_disconnect(intercomm, error)

    call MPI_Finalize(error)

end program client

在一个真正的程序中,您可能会发现将有关端口地址的信息传输到客户端的其他方式(例如名称发布或文件系统传输)。然后您就可以像这样运行代码:

代码语言:javascript
运行
复制
mpirun -n <N1> server &
mpirun -n <N2> client

这种方法几乎没有什么值得注意的地方。如果您只创建一个交互器-您将只有一个MPI任务从每一方通信到合作伙伴代码。如果您需要发送大量数据--您可能需要考虑创建多个交互器。此外,MPI标准这一部分的实现可能有些挑剔(例如,在OpenMPI2.x中,有一个错误完全阻止了它的使用)。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57078723

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档