Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Fortran 使用MPI_Bcast传递三维阵列_Fortran_Mpi_Fortran Common Block - Fatal编程技术网

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
的参数必须是向量。不知道你通过了什么,我无法告诉你问题可能是什么。请看我对我问题的回答