OpenMP代码在英特尔Fortran中未给出任何结果
我为共轭梯度法编写了一个串行代码,并尝试将其与OpenMP并行(我的平台是Intel cluster) 当我使用串行代码时,我得到如下输出:-OpenMP代码在英特尔Fortran中未给出任何结果,fortran,openmp,intel-fortran,Fortran,Openmp,Intel Fortran,我为共轭梯度法编写了一个串行代码,并尝试将其与OpenMP并行(我的平台是Intel cluster) 当我使用串行代码时,我得到如下输出:- 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
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
但是,当我为特定的do循环使用Openmp时,我没有得到解决方案。输出仅为以下内容:
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
解决方案非常简单:
private
变量在进入OpenMP节时以及离开OpenMP节后都未定义。只需将相应的行更改为
!$omp parallel default(none) shared(beta,d,g) private(i) firstprivate(n)
一切都按预期进行。使用firstprivate
,可以告诉编译器在进入并行部分时将原始变量的值复制到所有线程
但是为什么需要声明n
private?这只是阅读!您的代码也适用于共享的n
:
!$omp parallel default(none) shared(beta,d,g,n) private(i)