MPI-向从其他功能运行的进程发送消息

问题描述 投票:0回答:1

我有一个等级为0(MASTER)的进程正在运行的函数(FUNCA)中执行:

...

get_moves_list(node,&moves_list,&moves_len,maximizing);
//for each rank in SLAVES
//MPI_Send a move to a SLAVE

我希望从属进程从MASTER接收消息,但是从属进程正在从另一个函数(FUNCB)中/内部运行

void run_slave(rank) {
    int move;
    //MPI_Recv a move from MASTER
    //Do some stuff with that move
    //Then return to caller 
}

主看起来像这样

int main(int argc,char **argv)
{
    int rank,size;
    MPI_Init(NULL,NULL);
    MPI_Comm_rank(MPI_COMM_WORLD,&rank);
    MPI_Comm_size(MPI_COMM_WORLD,&size);

    if (rank == MASTER) {
        ...

        //CALL FUNCA

        ...
    } else {
        run_slave(rank);
        MPI_Finalize();
    }
}

MPI是否可以通过向不同功能运行的进程发送/接收消息来实现这种功能?

如果有帮助,我试图并行化一个minimax函数(FUNCA),但是必须如上所述使用程序的结构。

程序启动时,MASTER进程启动游戏并调用minimax以使最大化玩家的最佳举动。

我有minimax的串行版本,并且目前正在尝试使用MPI对其进行并行化,但到目前为止还没有运气。

function mpi send minimax message-passing
1个回答
0
投票

是的,您可以这样做。这是一个完整的玩具程序,应演示此功能:

#include <iostream>
#include "mpi.h"
#include "unistd.h"
#define MASTER 0
int pid, pnum;

void func1(void)
{
    int bcastval = 1000;
    MPI_Bcast(&bcastval, 1, MPI_INT, 0, MPI_COMM_WORLD);
    std::cout << pid << " sent " << bcastval << std::endl;
}

void func2(void)
{
    int recv;
    MPI_Bcast(&recv, 1, MPI_INT, 0, MPI_COMM_WORLD);
    std::cout << pid << " received " << recv << std::endl;
}


int main(void)
{
    MPI_Init(NULL,NULL);
    MPI_Comm_rank(MPI_COMM_WORLD,&pid);
    MPI_Comm_size(MPI_COMM_WORLD,&pnum);
    if (pid == MASTER) func1();
    else func2();
    if (pid == MASTER) std::cout << "Done!" << std::endl;
    MPI_Finalize();
}

注意,以mpirun -np 2 ./a.out运行会产生结果

0 sent 1000
1 received 1000
Done!

但是,如果您在主进程和其他两个调用的函数中都具有复杂的逻辑,我强烈建议您避免这样做。这个例子很容易说明:

#include <iostream>
#include "mpi.h"
#include "unistd.h"
#define MASTER 0
int pid, pnum;

void func1(void)
{
    int bcastval = 1000;
    MPI_Bcast(&bcastval, 1, MPI_INT, 0, MPI_COMM_WORLD);
    std::cout << pid << " sent " << bcastval << std::endl;
    MPI_Barrier(MPI_COMM_WORLD); // any blocking call
}

void func2(void)
{
    int recv;
    MPI_Bcast(&recv, 1, MPI_INT, 0, MPI_COMM_WORLD);
    std::cout << pid << " received " << recv << std::endl;
}    

int main(void)
{
    MPI_Init(NULL,NULL);
    MPI_Comm_rank(MPI_COMM_WORLD,&pid);
    MPI_Comm_size(MPI_COMM_WORLD,&pnum);
    if (pid == MASTER) func1();
    else func2();
    if (pid == MASTER) std::cout << "Done!" << std::endl;
    MPI_Finalize();
}

每次在分支中进行阻塞的MPI调用,并且并非所有进程都跟随该分支,由于并非所有进程都可以“签入”该调用,因此MPI将永远停止程序。此外,如果这些功能中发生了很多事情,那么由于调试输出的表现可能会异常,因此很难进行故障排除。

有关此事:我正在编写一个具有MPI层的大型多物理场仿真代码。最近,发生了与上述情况完全相同的事情,它停止了所有17个开发人员的整个代码。每个开发人员都发现代码停止在不同的位置,有时会停在依赖MPI的外部库中。故障排除花费了很长时间。

[我建议FUNCA返回主进程需要广播的信息,然后在条件分支之外广播。

© www.soinside.com 2019 - 2024. All rights reserved.