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

添加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'

我有一个名为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'
   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不兼容。