我有一个名为pot.f的旧版Fortran源文件,我需要将 OpenMP 应用于并行,如下所示,但我可以提供有关意外结束状态等的错误消息。但是$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 指令中开始第二个parallel
部分,该指令不会因end parallel
终止。所以 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
编译时,主线程完成了所有工作。更糟糕的是,通过"第一次接触原则",整个数组位于与第一个线程相关的内存中。在我们的 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
我不知道他们是否解决了这个问题,但从那时起,我对共享内存中的数组使用这种初始化方式。