添加Openmp指令时出现奇怪的gfortran编译错误
我有一个名为pot.f的传统fortran源文件, 我需要将OpenMP应用于parallel,如下所示,但我可以在注释掉添加Openmp指令时出现奇怪的gfortran编译错误,fortran,openmp,Fortran,Openmp,我有一个名为pot.f的传统fortran源文件, 我需要将OpenMP应用于parallel,如下所示,但我可以在注释掉$OMP行时添加额外的错误消息,例如意外的结束状态等!在第一列中,没有错误 这对我来说真的很奇怪。谁能告诉我出了什么问题吗 subroutine pot_osc(rvp,R_pot,e_pot,pe_pot,ftmp,gtmp,vtmp,natoms) implicit none include 'sizes.h' include 'constants.h'
$OMP
行时添加额外的错误消息,例如意外的结束状态等!在第一列中,没有错误
这对我来说真的很奇怪。谁能告诉我出了什么问题吗
subroutine pot_osc(rvp,R_pot,e_pot,pe_pot,ftmp,gtmp,vtmp,natoms)
implicit none
include 'sizes.h'
include 'constants.h'
include 'omp_lib.h'
double precision ftmp(maxatoms,3),gtmp(3),R_pot(maxatoms,3)
!$OMP PARALLEL WORKSHARE SHARED(gtmp,ftmp)
!$OMP PARALLEL NUM_THREADS(16)
gtmp = 0d0
ftmp = 0d0
!$OMP END PARALLEL WORKSHARE
return
end
subroutine pot_asym(rvp,vtmp)
implicit none
include 'constants.h'
return
end
错误消息:
end
1
Error: Unexpected END statement at (1)
subroutine pot_asym(rvp,vtmp)
1
Error: Unclassifiable statement at (1)
您在第二个OpenMP指令中启动第二个
并行
部分,该部分不会被结束并行
终止。因此,OpenMP指令应为
!$OMP PARALLEL WORKSHARE SHARED(gtmp,ftmp) NUM_THREADS(16)
gtmp = 0d0
ftmp = 0d0
!$OMP END PARALLEL WORKSHARE
或者,如果你想保持线路中断,请使用
!$OMP PARALLEL WORKSHARE SHARED(gtmp,ftmp) &
!$OMP NUM_THREADS(16)
gtmp = 0d0
ftmp = 0d0
!$OMP END PARALLEL WORKSHARE
在过去,我遇到过一些与这种初始化完全相关的问题。似乎在使用gfortran
编译时,主线程完成了所有工作。更糟糕的是,通过“第一个stouch原理”,整个数组位于与第一个线程相关联的内存中。在我们的CCNUMA机器上,这导致了巨大的减速
为了解决这个问题,我使用显式循环来初始化:
!$OMP PARALLEL DO SHARED(gtmp,ftmp) NUM_THREADS(16)
do i=1,maxatoms
ftmp(i,:) = 0d0
enddo
!$OMP END PARALLEL DO
! No need to do three elements in parallel
gtmp = 0d0
我不知道他们是否解决了这个问题,但从那时起,我对共享内存中的数组使用了这种初始化方法 我注意到您使用了
maxantoms
作为数组中的第一个索引。我猜你描述了与每个原子相关的三维向量。我认为最好像Fortran那样转换这些数组。这样,3D向量在内存中是连续的。如果使用数组节语法,则WORKSHARE
中的数组分配由gfortran
并行,例如gtmp(:)=0.d0;ftmp(:,:)=0.d0
。否则,所有的工作都是在一个指令中完成的。IIRC,至少在我的gfortran 4.8中,您还可以使用整个数组。谢谢您的回答!“英特尔语法”在换行时与mpif90不兼容。