关于MPI_Isend,MPI标准说“非阻塞发送调用表明系统可能开始从发送缓冲区中复制数据。发送缓冲区发送操作后,发送方不应访问发送缓冲区的任何部分,直到发送完成。“ (http://www.mpi-forum.org/docs/mpi-11-html/node46.html)
在另一个发送调用中引用发送缓冲区是否正常,或者是否包含在“访问发送缓冲区的任何部分”中?
换句话说,发件人的以下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);
答案 0 :(得分:3)
MPI标准确实允许这种用法。
如果有更多的“少数”排名需要相同的缓冲区,或者这种通信模式将重复超过“少数”次...然后创建一个具有相关排名的comm,并使用MPI_Bcast会更好。
编辑:
澄清我自己的答案。 MPI 2.0标准明确禁止这种用法。限制是为了容纳Fortran。 MPI 2.1或2.2标准包括“澄清”,即允许在多个ISend中重复使用发送缓冲区。有关更多信息,请参见MPI 2.2标准的第16.2.2节。
答案 1 :(得分:2)
我刚刚咨询了MPI 3.0 Standard并找到了以下信息:
非阻塞发送呼叫表示系统可能开始从中复制数据 发送缓冲区。在非阻塞之后,发送方不应修改发送缓冲区的任何部分 调用发送操作,直到发送完成。
但是,我最近参加了该标准的一些开发人员提供的关于MPI 3.0的教程,并且提到了,根据MPI实现(MPICH,LAM等),访问a可能是不安全的。在非阻塞通信调用中使用的缓冲区可以在发送完成之前从Isend过程修改缓冲区。换句话说,可能无法保证第二个MPI_Isend中的缓冲区与第一个发送中的缓冲区相同。为了确定这一点,我会参考您的实现源代码。