在一个缓冲区上多次调用 MPI_Isend 是否可行?

7
关于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);

我猜测这里,这就是为什么这不是一个完整的答案,你真正不想做的事情是在发送完成之前修改源缓冲区的内容或读取目标缓冲区的内容。所以对我来说,你正在做的看起来没问题。但请测试一下,不要听我的。 - bob.sacamento
@bob.sacamento 当然,没错。我知道我的代码对于我正在使用的MPI实现是正确的(查看了源代码),但我想知道这是否符合标准,即是否适用于每个正确的MPI实现。 - Posco Grubb
2个回答

3
MPI标准允许这种用法。如果有超过“一把手”的排名需要相同的缓冲区,或者如果此通信模式将重复超过“一把手”次数,则创建与相关排名的通信,并使用MPI_Bcast将更可取。
编辑:
为了澄清我的答案。MPI 2.0标准明确禁止这种用法。限制是为了适应Fortran。MPI 2.1或2.2标准包括一个“澄清”,即在多个ISends中重用发送缓冲区是允许的。有关更多信息,请参见MPI 2.2标准的第16.2.2节。

1
谢谢。MPI 2.2标准的那一部分很有启发性。 - Posco Grubb

3

我刚刚查询了MPI 3.0标准,发现以下信息:

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

然而,我最近参加了一次由标准的一些开发人员提供的MPI 3.0教程,并且提到,根据MPI实现(MPICH,LAM等),访问在非阻塞通信调用中使用的缓冲区可能是不安全的,因为缓冲区可能会在Isend过程中被修改,而发送尚未完成。 换句话说,无法保证第二个MPI_Isend中的缓冲区与第一个发送中的缓冲区相同。 为了确切地弄清楚这一点,建议您查阅您的实现源代码。


嗯,这正是我担心的。标准是否规定在发送完成时发送缓冲区必须“返回”未经修改的应用程序,还是可以进行修改?我只是无法想象一个合理的实现会如何从实际修改发送缓冲区中受益。 - Posco Grubb
1
并不是说实现一定会修改缓冲区,但它确实需要确保在复制/发送时缓冲区不被更改。 - Wesley Bland

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接