【发布时间】:2019-10-27 08:00:33
【问题描述】:
我想使用 MPI 函数MPI_GATHERV,其中每个 MPI 等级都有一个大小不同的缓冲区,需要在根进程中收集。
像往常一样,我的根进程只会收集缓冲区,但本身没有发送缓冲区。
例如
排名1
buf_sz =3
buf(1) = 1
buf(2) = 2
buf(3) = 3
排名 2
buf_sz =3
buf(1) = 4
buf(2) = 5
buf(3) = 6
在 MPI_GATHERV 之后,我的 Root 应该有
buf(1) = 1
buf(2) = 2
buf(3) = 3
buf(4) = 4
buf(5) = 5
buf(6) = 6
就目前而言,这意味着我必须在 Root 应用一个分配有零元素和零计数的 sendbuf。我不确定这通常有多明确和安全?
示例代码
if(myrankid == root)then
allocate(displ(3))
allocate(counts(3))
displ(1) = 0
displ(2) = 0
displ(3) = 3
counts(1) = 0
counts(2) = 3
counts(3) = 3
allocate(buf_send(0))
sendcount = 0
allocate(recvbuf(6))
else
allocate(displ(1))
allocate(counts(1))
allocate(buf_send(3))
allocate(recvbuf(1))
sendcount = 3
endif
MPI_Gatherv(buf_send, sendcount, mpi_integer,&
recvbuf, counts, displs,&
mpi_integer, root, mpi_comm_world)
【问题讨论】:
-
向我们展示您的代码。
-
@GillesGouaillardet - 100% 不同意。如果相应的虚拟参数没有可分配属性,则传递未分配的可分配数组始终是不标准的。这完全与被调用的例程是否访问参数无关。由于 MPI 没有具有可分配属性的参数,因此对于 MPI 调用来说总是非法的,并且在上述情况下,调用例程应该分配,可能大小为零。
-
@A2LBK 是的,分配为零大小并传递它是合法的。这正是我所做的
-
@VictorEijkhout 不,不访问数组无关紧要。在标准 Fortran 中,如果接口不在范围内,则传递未分配的可分配数组是总是非法的。 总是。程序对它的作用是无关紧要的。如果接口在要传递的未分配可分配数组的范围内(除了与此处无关的小例外),则相应的虚拟参数也必须是可分配的。 MPI 没有可分配的虚拟参数。因此,将未分配的可分配数组传递给 MPI 例程是总是错误的。
-
@VictorEijkhout 请参阅stackoverflow.com/questions/13496510/… 以获得更多讨论,尤其是 francescalus 的(更新得多的)版本,它提供了对 Fortran 标准相关部分的参考