OpenMP代码在英特尔Fortran中没有给出任何结果

时间:2014-12-08 21:22:53

标签: fortran openmp intel-fortran

我为共轭梯度方法编写了一个串行代码,并尝试将其与OpenMP并行化(我的平台是Intel集群)

当我使用串行代码时,我得到如下输出: -

Test data (matrix and right hand side) :
  5.00000  0.00000 -1.00000 -1.00000  1.00000
  0.00000  5.00000 -1.00000 -1.00000  1.00000
 -1.00000 -1.00000  5.00000 -1.00000  1.00000
 -1.00000 -1.00000 -1.00000  5.00000  1.00000
  Solution for the linear system:
  0.37500  0.37500  0.43750  0.43750

但是当我使用Openmp进行特定的do循环时,我没有得到解决方案。输出只有这个:

Test data (matrix and right hand side) :
  5.00000  0.00000 -1.00000 -1.00000  1.00000
  0.00000  5.00000 -1.00000 -1.00000  1.00000
 -1.00000 -1.00000  5.00000 -1.00000  1.00000
 -1.00000 -1.00000 -1.00000  5.00000  1.00000

编译期间没有错误。 有人可以帮忙吗?

我已经复制粘贴了OpenMP代码。

  module cg
     contains
     subroutine cg_method (n,a,y,x)
     use omp_lib
     implicit none
     integer :: n, k , i , j
     integer,parameter :: sze = 24 , nt = 4
     double precision :: tol = 2.d-16
     double precision :: a(0:sze,0:sze),x(0:sze),y(0:sze)
     double precision :: d(0:n-1),g(0:n-1),auxD(0:n-1),alpha,beta
     double precision :: num,den,aux1,aux2,dist,xnorm

    !$call omp_set_num_threads(nt)
    ! start with x at origin

     do i = 0,n-1
        x(i) = 0.d0
     enddo

    ! initialize d and g
    ! d = -g = -(a*x-y) = y as x = 0

     do i = 0,n-1
       aux1 = y(i)
       d(i) = aux1
       g(i) = -aux1
     enddo

    ! perform at most n steps of CG algo

     do k = 0,n

    ! compute new alpha
    ! alpha = -(d(transp)*g)/(d(transp)*(a*d))

       num = 0.d0
       den = 0.d0
       do i = 0,n-1
          num = num + d(i)*g(i)
          aux1 = 0.d0
         do j = 0 , i-1
           aux1 = aux1 + a(j,i)*d(j)
         enddo
            do j = i,n-1
               aux1 = aux1 + a(i,j)*d(j)
            enddo
          auxD(i) = aux1
          den = den + d(i)*aux1
        enddo


     alpha = -num/den

    ! compute the norm of x and alpha*d and find a new x
    !x = x + alpha*d , then check if x is close in order to stop the process
    !before n complete steps

     xnorm = 0.d0
     dist = 0.d0

     do i = 0,n-1
        aux1 = x(i)
        xnorm = xnorm + aux1*aux1
        aux2 = alpha*d(i)
        dist = dist + aux2*aux2
        x(i) = aux1 + aux2
     enddo

    !compute new g : g + alpha*(a*d)

     do i = 0,n-1
        g(i) = g(i) + alpha*auxD(i)
     enddo

    ! compute new beta :
    ! beta = (g(transp)*(a*d))/(d(transp)*(a*d))

     num = 0.d0
     do i = 0,n-1
        num = num + g(i)*auxD(i)
     enddo

     beta = num/den

    !compute new d : d = -g + beta*d
    !$omp parallel default(none) shared(beta,d,g) private(i,n)
    !$omp do
     do i = 0,n-1
        d(i) = -g(i) + beta*d(i)
     enddo
    !$omp enddo
    !$omp end parallel
     enddo !k loop

     end subroutine cg_method 
     end module cg

     program test

     use cg
     use omp_lib
     integer,parameter :: sze = 24
     double precision :: a(0:sze,0:sze), y(0:sze),x(0:sze)
     integer :: n , i , j

     n = 4

     !define a matrix
     a(0,0)=5.d0;a(0,2)=-1.d0;a(0,3)=-1.d0
     a(1,1)=5.d0;a(1,2)=-1.d0;a(1,3)=-1.d0
     a(2,2)=5.d0;a(2,3)=-1.d0;a(3,3)=5.d0

    !define b vector
     y(0)=1.d0;y(1)=1.d0;y(2)=1.d0;y(3)=1.d0

     print*,'Test data (matrix and right hand side) :'
     do i = 0,n-1
       write(*,100) (a(j,i),j=0,i-1),(a(i,j),j=i,n-1),y(i)
     enddo

     call cg_method(n,a,y,x) !perform CG method
     print *,' Solution for the linear system:'
        write(*,100)  (x(i),i=0,n-1)
    100 format(10F9.5)
     end program test

1 个答案:

答案 0 :(得分:1)

解决方案非常简单:进入OpenMP部分时,以及离开后,private变量未定义。只需将相应的行更改为

即可
!$omp parallel default(none) shared(beta,d,g) private(i) firstprivate(n)

一切都按预期工作。使用firstprivate,告诉编译器在进入并行部分时将原始变量的值复制到所有线程。

但为什么你需要声明n私有?它只是阅读!您的代码也适用于共享的n

!$omp parallel default(none) shared(beta,d,g,n) private(i)