Fortran 使用MPI_Bcast传递三维阵列
我试图使用Fortran 使用MPI_Bcast传递三维阵列,fortran,mpi,fortran-common-block,Fortran,Mpi,Fortran Common Block,我试图使用MPI\u Bcast将3D数组传递给所有其他进程(在FORTRAN 77中)v1是一个公共块数组。我也不确定是否需要将公共数组的计算值v1广播给所有其他进程,或者它们在每个进程中都会因为是公共的而改变。以下是相关代码: parameter (nprocz=48,nzro=1) do i=i101,i102 dist = 0.015*float(i-iv0) adamp = exp(-dist*dist) do j = je0, je
MPI\u Bcast
将3D数组传递给所有其他进程(在FORTRAN 77中)v1
是一个公共块数组。我也不确定是否需要将公共数组的计算值v1
广播给所有其他进程,或者它们在每个进程中都会因为是公共的而改变。以下是相关代码:
parameter (nprocz=48,nzro=1)
do i=i101,i102
dist = 0.015*float(i-iv0)
adamp = exp(-dist*dist)
do j = je0, je1-1
do k = ke0, ke1
v1(k,j,i) = v1(k,j,i)*adamp
end do
end do
end do
nmpi01=floor((iv0-ie0-nzro)/(nprocz-1))
if (mpirank .le. nprocz-2) then
i101=ie0+(mpirank*nmpi01)
i102=ie0+(mpirank+1)*nmpi01-1
else
i101=ie0+(mpirank*nmpi01)
i102=iv0-1
endif
MPI_Bcast(v1(:,:,i101:i102),(ke1-ke0+1)*(je1-je0)*(i102-i101+1)
& ,MPI_FLOAT,mpirank,MPI_COMM_WORLD,ierr01)
我收到错误消息:
PGFTN-S-0081-Matrix/vector v1 illegal as subprogram argument
传入的数组的大小是正确的。有什么评论吗
我更正了代码,并在列组上循环,计算每个列组中rcount和DISPRESS的所有元素:
integer :: myscount, myi101
do rank = 0, nprocz-1
nmpi01=floor((iv0-ie0-nzro)/(nprocz-1))
if (rank .le. nprocz-2) then
i101=ie0+(rank*nmpi01)
i102=ie0+(rank+1)*nmpi01-1
else
i101=ie0+(rank*nmpi01)
i102=iv0-1
endif
scount=(i102-i101+1)*(je1-je0)*(ke1-ke0+1)
rcount(rank+1)=scount
displs(rank+1)=rank*scount+1
if (rank .eq. mpirank) then
myscount = scount
myi101 = i101
end if
end do
scount = myscount
i101 = myi101
call mpi_allgatherv(...)
但仍然是错误的结果。1-在我的例子中,每个部分的结果将用于下一部分,特别是在
mpi\u allgatherv
之后。那么我是否需要在每个mpi\u allgatherv
之后添加mpi\u屏障
?2-是否应使用就地mpi?考虑到我只有一个3D数组<代码> V1<代码>,每个子数组<代码> V1(1,1,i)< /代码>是通过某个过程计算的,并且我想把计算的子数组放在同一个数组的适当部分。3-考虑到fortran77中总是显示(1)=1,我想我应该为i=>2设置disfs(i)=sum(rcount(1:i-1))+1。所以我纠正了这一点:在循环disfs(1)=1
之前,在循环disfs(rank+2)=rank*scont+1
内部,在循环disfs(nprocz+1)=0
之后。我说得对吗?我记得,Fortran 77比Fortran 90对数组下标的限制更严格,pgftn是Fortran 77编译器。我会尝试将v1(1,1,i101)
传递到mpi\u bcast,而不是v1(:,:,i101:i102)
。(或使用带有“-Mfixed”标志的pgf95。)
如果每个进程都需要查看v1,那么您确实需要使用MPI进行通信。MPI任务之间不共享变量,即使是公共块中的任务也不共享。但是,如果每个进程都在计算v1的不同部分,那么每个进程都需要来自其他进程的一个片段,那么您不能使用mpi\u bcast
来实现这一点;改用mpi\u allgather
此外,如上所述,当您使用MPI过程时,您应该调用它们,因为它们是子例程。您能显示演示问题的最小完整代码示例吗?请注意,我没有说,复制并粘贴所有代码到问题中,因为这对我们来说太多了,无法解析。当你提供更好的信息时,你可能会找到问题的答案。感谢您的评论如果调用MPI\u Bcast(…)
?@IRO bot为什么要调用?这不是一个子程序。我正在尝试删除mpi_bcast,看看会发生什么。数组v1是一个公共块数组,对每个进程都是全局的。但仍然不确定是否在每个进程中计算该数组的某些部分,该部分的更改将在其他进程中进行。你认为呢?是的,在Fortran中,所有的MPI例程都是子程序。您使用什么MPI实现MPI_FLOAT
作为一种数据类型,看起来也很奇怪,请参阅。在您的情况下,对MPI\u Bcast
的调用将从根进程mpirank
向所有其他进程发送v1
片段<必须在所有进程上声明代码>v1
。请参阅如何使用MPI\u Bcast
@Sean patrick santos,因此首先我尝试了以下方法:Scont=(i102-i101+1)*(je1-je0)*(ke1-ke0+1)rcount(mpirank+1)=Scont displank(mpirank+1)=mpirank*Scont+1调用MPI\u allgatrov(v1(v1(1,1,101),Scont,MPI\u REAL,v1(1,1),rcount,dispus,MPI\u REAL,MPI\u commu WORLD,ierr004)但我得到了这个错误:PMPI中的致命错误\u Allgatherv:内部MPI错误!,错误堆栈:。。。MPI_Localcopy(378)…:memcpy参数彼此别名,dst=0x7ccddb44 src=0x7ccddb40 len=3642752@Sean patrick santos然后我将其更改为:call MPI_ALLGATHERV(MPI_IN_PlACE,Scont,MPI_REAL,v1(1,1,1),rcount,displats,MPI_REAL,MPI_COMM_WORLD,ierr004),但在程序崩溃之前内存一直在增量使用。每种情况下都有什么问题?对于第一个命令,问题只是您试图在同一个缓冲区中发送和接收;您需要在位置MPI_来实现。对于第二个参数,作为rcount
和dispuls
的参数必须是向量。不知道你通过了什么,我无法告诉你问题可能是什么。请看我对我问题的回答