我有一个等级为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对其进行并行化,但到目前为止还没有运气。
是的,您可以这样做。这是一个完整的玩具程序,应演示此功能:
#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
返回主进程需要广播的信息,然后在条件分支之外广播。