OpenMPI MPI_Send 与英特尔 MPI MPI_Send

Posted

技术标签:

【中文标题】OpenMPI MPI_Send 与英特尔 MPI MPI_Send【英文标题】:OpenMPI MPI_Send vs Intel MPI MPI_Send 【发布时间】:2019-07-08 00:16:55 【问题描述】:

我有一个使用 openmpi 编译和运行的代码。最近,我想使用英特尔 MPI 运行相同的代码。但是我的代码没有按预期工作。 我深入研究了代码,发现 MPI_Send 在两种实现中的行为不同。

我从不同的论坛获得了使用 MPI_Isend 而不是来自不同论坛的 MPI_Send 的建议。但这需要大量的工作来修改代码。英特尔 MPI 中是否有任何解决方法可以使其像在 OpenMPI 中一样工作。可能是一些标志或增加缓冲区或其他东西。提前感谢您的回答。

int main(int argc, char **argv) 
    int numRanks;
    int rank;
    char cmd[] = "Hello world";
    MPI_Status status;

    MPI_Init (&argc, &argv);
    MPI_Comm_size (MPI_COMM_WORLD, &numRanks);
    MPI_Comm_rank (MPI_COMM_WORLD, &rank);
    if(rank == 0) 
            for (int i=0; i< numRanks; i++) 
                    printf("Calling MPI_Send() from rank %d to %d\n", rank, i);
                  MPI_Send(&cmd,sizeof(cmd),MPI_CHAR,i,MPI_TAG,MPI_COMM_WORLD);
                    printf("Returned from MPI_Send()\n");
            
    
    MPI_Recv(&cmd,sizeof(cmd),MPI_CHAR,0,MPI_TAG,MPI_COMM_WORLD,&status);
    printf("%d receieved from 0 %s\n", rank, cmd);

    MPI_Finalize();

OpenMPI 结果

# mpirun --allow-run-as-root  -n 2  helloworld_openmpi
Calling MPI_Send() from rank 0 to 0
Returned from MPI_Send()
Calling MPI_Send() from rank 0 to 1
Returned from MPI_Send()
0 receieved from 0 Hello world
1 receieved from 0 Hello world

英特尔 MPI 结果

# mpiexec.hydra -n 2 /root/helloworld_intel

Calling MPI_Send() from rank 0 to 0

卡在 MPI_Send。

【问题讨论】:

我想你希望MPI_Send() 在你的接收者和你的发送者等级相同的情况下立即返回,但是英特尔和 OpenMPI 处理这个不同。这是正确的吗? 是正确的。我想要和提到的完全一样的东西 好的。我认为您的问题本可以在您的问题中更清楚地说明(我必须真正查看代码和输出才能弄清楚发生了什么),但我想我现在已经进入了。 【参考方案1】:

假设MPI_Send() 将在匹配的接收发布之前返回是不正确的,因此您的代码在 MPI 标准方面不正确,您很幸运它没有与 Open MPI 挂起。

MPI 实现通常急切发送 small 消息,因此MPI_Send() 可以立即返回,但这是标准未强制要求的实现选择,“small”消息取决于库版本,您正在使用的互连和其他因素。

这里唯一安全且可移植的选择是编写正确的代码。

FWIW,MPI_Bcast(cmd, ...) 更适合这里,假设所有等级都已经知道字符串长度加上 NUL 终止符。

最后但同样重要的是,缓冲区参数是 cmd 而不是 &amp;cmd

【讨论】:

以上是关于OpenMPI MPI_Send 与英特尔 MPI MPI_Send的主要内容,如果未能解决你的问题,请参考以下文章

关于MPI_Send与MPI_Recv语义

MPI_Comm_split 与 MPI_Send / MPI_Recv 的关系

MPI_Send() 和 MPI_Ssend() 之间的区别?

MPI_SEND 在 MPI_BARRIER 之后停止工作

openmpi 中的即时通信与同步通信

使用 MPI_Send 和 MPI_Recv 实现 MPI_Scatter 的问题