2013-10-11 34 views
2

我有遗留的fortran源文件,名为pot.f, ,我需要将OpenMP应用到并行,如下所示,但我可以关于意外结束状态等错误消息。但是当我评论通过添加额外的$OMP行!在第一列中,没有错误。添加Openmp伪指令时奇怪gfortran编译错误

这对我来说真的很奇怪。有谁能告诉我哪里出了问题?

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) 
+0

我注意到你在数组中使用了'maxatoms'作为第一个索引。我的猜测是你描述了与每个原子相关的三维矢量。我认为将Fortran转换为[专业专栏](https://en.wikipedia.org/wiki/Row-major_order#Column-major_order)将会更好。这样,3D矢量在内存中将是连续的。 –

回答

4

你开始在第二OpenMP指令,这不被终止end parallel第二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 

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

+0

如果使用数组部分语法来替代'WORKSHARE'内的数组赋值,则由'gfortran'并行化。 'gtmp(:) = 0.d0; ftmp(:, :) = 0.d0'。否则,所有的工作都在'SINGLE'指令中完成。 –

+0

IIRC,至少在我的gfortran 4.8中,你也可以使用整个阵列。 –