添加 Openmp 指令时出现奇怪的 gfortran 编译错误



我有一个名为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

我不知道他们是否解决了这个问题,但从那时起,我对共享内存中的数组使用这种初始化方式。

最新更新