2014-01-16 2 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 отличается для параллельного и секвенциального кода. В одном из сообщений я видел, что внутренняя переменная цикла должна быть определена внутри параллельной конструкции (почему я не знаю). Я также изменил указатели на локальные распределенные переменные, но результат не изменился. normr - сохраненная действительная переменная.

Любые предложения и помощь будут оценены.

С наилучшими пожеланиями,

Гокмен

+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) 
Смежные вопросы