openmp fortran中的求和错误

时间:2014-01-16 03:10:33

标签: fortran openmp fortran90

我试图用openmp总结一个带有下面代码的变量。

    normr=0.0
 !$omp parallel default(private) shared(nelem,normr,cell_data,alphar,betar,k)
   !$omp do REDUCTION(+:normr)
     do ii=1,nelem
        nnodese=cell_data(ii)%num_vertex
        pe=cell_data(ii)%porder
        ndofe=cell_data(ii)%ndof             
        num_neighboure=cell_data(ii)%num_neighbour

        be=>cell_data(ii)%Force
        Ke=>cell_data(ii)%K
        Me=>cell_data(ii)%M
        pressuree=>cell_data(ii)%p
        Rese=>cell_data(ii)%Res
        neighbour_indexe=>cell_data(ii)%neighbour_index(:)

        Rese(:)=be(:)
        Rese(:)=Rese(:)-cmplx(-1.0,1.0*alphar/k)*matmul(Me(:,:),pressuree(:))
        Rese(:)=Rese(:)-cmplx(1.0,1.0*k*betar)*matmul(Ke(:,:),pressuree(:))

        do jj=1,num_neighboure  
           nbeindex=neighbour_indexe(jj)
           Knbe=>cell_data(ii)%neighbour(jj)%Knb
           pressurenb=>cell_data(nbeindex)%p
           ndofnb=cell_data(nbeindex)%ndof



           Rese(:)=Rese(:)-cmplx(1.0,1.0*k*betar)*matmul(Knbe(:,:),pressurenb(:))


           nullify(pressurenb)
           nullify(Knbe)
        end do   


        normr=normr+dot_product(Rese(:),Rese(:))

        nullify(pressuree)
        nullify(Ke)
        nullify(Me)
        nullify(Rese)
        nullify(neighbour_indexe)
        nullify(be)

     end do
  !$omp end do
!$omp end parallel 

求和变量normr的结果对于并行和sequantial代码是不同的。在其中一篇文章中,我看到内部循环变量应该在并行构造中定义(为什么我不知道)。我还将指针更改为locall分配的变量,但结果没有改变。 normr是一个保存的实变量。

任何建议和帮助都将不胜感激。

最诚挚的问候,

Gokmen

1 个答案:

答案 0 :(得分:0)

对于并行和顺序代码,

normr可以不同,因为求和不会以相同的顺序发生。因此,差异不一定是错误,可以从减少操作中得到预期。

不是错误并不意味着不是问题。解决这个问题的一种方法是将求和移出并行循环:

!$omp parallel default(private) shared(... keep_dot_product)
!$OMP do
do ii=1,nelem
   ! ...
   keep_dot_product(ii) = dot_product(Rese(:),Rese(:))
   ! ...
end do
!$omp end do
!$omp end parallel
normr = sum(keep_dot_product)