3

我有名为 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)
4

1 回答 1

6

parallel在第二个 OpenMP 指令中开始第二个部分,该部分不以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

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

于 2013-10-11T18:01:01.937 回答