openMP嵌套do循环的并行化

时间:2016-02-03 00:14:54

标签: parallel-processing fortran openmp nested-loops fortran77

我在openmp fortran 77代码中有一个嵌套的do循环,我无法并行化(代码在运行时会出现分段错误错误)。我在相同代码的不同子例程中有一个非常相似的嵌套do循环,并行运行并没有问题。 这是我遇到问题的嵌套do循环:

      do n=1,num_p
C$OMP  PARALLEL DO DEFAULT(SHARED), PRIVATE(l,i1,i2,j1,j2,k1,k2
C$OMP& ,i,j,k,i_t,j_t,i_ddf,j_ddf,ddf_dum)
        do l=1,n_l(n)
          call del_fn(l,n)
          i1=p_iw(l,n)
          i2=p_ie(l,n)
          j1=p_js(l,n)
          j2=p_jn(l,n)
          k1=p_kb(l,n)
          k2=p_kt(l,n)
          do i=i1,i2
            i_ddf=i-i1+1
            if(i .lt. 1) then
              i_t=nx+i
            elseif (i .gt. nx) then
              i_t=i-nx
            else
              i_t=i
            endif
            do j=j1,j2
                j_ddf=j-j1+1
              if(j .lt.1) then
                j_t=ny+j
              elseif(j .gt. ny) then
                j_t=j-ny
              else
                j_t=j
              endif
              do k=k1,k2
                ddf(l,n,i_ddf,j_ddf,k-k1+1) = ddf_dum(i_t,j_t,k)
              enddo
            enddo
          enddo
        enddo
C$OMP END PARALLEL DO
      enddo

我已将问题缩小到 ddf_dum(i_t,j_t,k)。当这个术语关闭时(假设我用0.d0替换它),代码运行正常。

另一方面,我有一个非常相似的嵌套do循环,并行运行并没有问题。下面是嵌套的do循环,并行运行并没有问题。有谁能请确定我在这里缺少什么?

      do n=1,1
C$OMP  PARALLEL DO DEFAULT(SHARED), PRIVATE(l,i1,i2,j1,j2,k1,k2
C$OMP& ,i,j,k,i_f,j_f,i_ddf,j_ddf)
        do l=1,n_l(n)
          i1=p_iw(l,n)
          i2=p_ie(l,n)
          j1=p_js(l,n)
          j2=p_jn(l,n)
          k1=p_kb(l,n)
          k2=p_kt(l,n)
          u_forcing(l,n)= (u_p(l,n)-up_tilde(l,n))/dt
          v_forcing(l,n)= (v_p(l,n)-vp_tilde(l,n))/dt
          w_forcing(l,n)= (w_p(l,n)-wp_tilde(l,n))/dt
          do i=i1,i2
            i_ddf=i-i1+1
            if(i .lt. 1) then
              i_f=nx+i
            elseif (i .gt. nx) then
              i_f=i-nx
            else
              i_f=i
            endif
            do j=j1,j2
              j_ddf=j-j1+1
              if(j .lt.1) then
                j_f=ny+j
              elseif(j .gt. ny) then
                j_f=j-ny
              else
                j_f=j
              endif
              do k=k1,k2
                forcing_x(i_f,j_f,k)=forcing_x(i_f,j_f,k)+u_forcing(l,n)
 &                            *ddf_n(l,n,i_ddf,j_ddf,k-k1+1)*dv_l(l,n)
                forcing_y(i_f,j_f,k)=forcing_y(i_f,j_f,k)+v_forcing(l,n)
 &                            *ddf_n(l,n,i_ddf,j_ddf,k-k1+1)*dv_l(l,n)
                forcing_z(i_f,j_f,k)=forcing_z(i_f,j_f,k)+w_forcing(l,n)
 &                            *ddf_n(l,n,i_ddf,j_ddf,k-k1+1)*dv_l(l,n)
              enddo
            enddo
          enddo
        enddo
C$OMP END PARALLEL DO
      enddo

1 个答案:

答案 0 :(得分:2)

如您所述,您的问题是ddf_dum。它应该是一个共享变量,而不是私有变量,因为它只是从中读取而从不写入。您正在获取段错误,因为您尝试在不是主线程的所有线程上访问未初始化的内存。

一个很好的经验法则,您可能已经习惯于自己发现这个错误:所有仅在您的并行区域中等号的RHS上找到的变量应始终为shared