可以在一个缓冲区上多次调用MPI_Isend吗?

可以在一个缓冲区上多次调用MPI_Isend吗?,mpi,message-passing,Mpi,Message Passing,关于MPI Isend,MPI标准规定“非阻塞发送调用表示系统可能开始从发送缓冲区复制数据。在调用非阻塞发送操作后,发送方不应访问发送缓冲区的任何部分,直到发送完成。”() 在另一个发送调用中引用发送缓冲区是正常的,还是包括在“访问发送缓冲区的任何部分”中 换句话说,发送方的以下C代码正确吗 MPI_Request req[2]; MPI_Status statuses[2]; ... MPI_Isend(buf, type, count, dest0, tag, comm, &req[

关于MPI Isend,MPI标准规定“非阻塞发送调用表示系统可能开始从发送缓冲区复制数据。在调用非阻塞发送操作后,发送方不应访问发送缓冲区的任何部分,直到发送完成。”()

在另一个发送调用中引用发送缓冲区是正常的,还是包括在“访问发送缓冲区的任何部分”中

换句话说,发送方的以下C代码正确吗

MPI_Request req[2];
MPI_Status statuses[2];
...
MPI_Isend(buf, type, count, dest0, tag, comm, &req[0]);
MPI_Isend(buf, type, count, dest1, tag, comm, &req[1]);
MPI_Waitall(2, req, statuses);

MPI标准允许这种使用

如果有更多的“少数”列组需要相同的缓冲区,或者如果此通信模式将重复超过“少数”次…则最好与相关列组创建通信,并使用MPI_Bcast

编辑:

澄清我自己的答案。MPI 2.0标准明确禁止此类使用。限制是为了适应Fortran。MPI 2.1或2.2标准包括一个“澄清”,即允许在多个iSend中重复使用发送缓冲区。更多信息,请参见MPI 2.2标准第16.2.2节

我刚刚查阅了,发现了以下信息:

非阻塞发送调用表示系统可能开始从中复制数据 发送缓冲区。在非阻塞后,发送方不应修改发送缓冲区的任何部分 调用发送操作,直到发送完成


但是,我最近参加了一个由该标准的一些开发人员提供的关于MPI 3.0的教程,其中提到,根据MPI实现(MPICH、LAM等),访问非阻塞通信调用中使用的缓冲区可能不安全,因为在发送完成之前,可能会从Isend过程修改缓冲区。换句话说,可能无法保证第二次MPI发送中的缓冲区与第一次发送中的缓冲区相同。为了确定这一点,我将参考您的实现源代码。

我在这里猜测,这就是为什么这不是一个完整的答案,您真正不想做的是在发送完成之前修改源缓冲区的内容或读取目标缓冲区的内容。所以对我来说,你所做的看起来很好。但是请测试一下。别相信我的话。@bob.sacamento当然,这是真的。我知道我的代码对于我正在使用的MPI实现是正确的(查看了源代码),但我想知道根据标准,这是否正确,也就是说,可以在每个正确的MPI实现上工作。嗯,这是我害怕的。标准是否规定发送完成时的发送缓冲区必须未经修改“返回”给应用程序,或者可以修改它们?我只是看不出一个合理的实现通过实际修改发送缓冲区会有什么好处。这并不是说该实现一定会修改缓冲区,但它确实需要确保在复制/发送缓冲区时不会更改缓冲区。谢谢。MPI 2.2标准的这一部分很有启发性。