2014-01-16 64 views
-2

我想總結一個變量與openmp與下面給出的代碼。在openmp fortran總結錯誤

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的結果對於並行和後綴代碼是不同的。在其中的一篇文章中,我看到內部循環變量應該在並行構造內部定義(爲什麼我不知道)。我也改變了指向本地分配變量的指針,但結果沒有改變。規範是一個保存的實際變量。

任何建議和幫助,將不勝感激。

此致

Gokmen

+0

嘗試將代碼減少到[短,自包含的,編譯的示例](http://sscce.org/)。這會迫使你更好地分析問題並允許其他人重現問題。 – Massimiliano

+2

如果我對http://stackoverflow.com/questions/20993327/using-openmp-critical-and-ordered/20996615的回答不能解釋您的錯誤,請告訴我們並行和順序結果的不同之處。 –

+1

考慮到規範是非負數的積累和減少的方式,在使用和不使用OpenMP的最終結果中應該沒有太大差異。這兩種結果究竟有多少不同? –

回答

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)