Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Fortran OpenACC回路并行化故障_Fortran_Gpgpu_Openacc - Fatal编程技术网

Fortran OpenACC回路并行化故障

Fortran OpenACC回路并行化故障,fortran,gpgpu,openacc,Fortran,Gpgpu,Openacc,我有一个用FORTRAN编写的旧代码,我需要使用OpenACC来加速它,但当我尝试使用指令时,它说存在un、vn、pn的依赖性,这会阻止并行性。可以并行化这个循环吗?我是OpenACC新手,但已经与OpenMP并行 !$acc parallel loop do 9000 j=2,jmaxm jm=j-1 jp=j+1 do 9001 i=2,imaxm im=i-1 ip=i+1 if(rmask(i,j).eq.1.0) t

我有一个用FORTRAN编写的旧代码,我需要使用OpenACC来加速它,但当我尝试使用指令时,它说存在un、vn、pn的依赖性,这会阻止并行性。可以并行化这个循环吗?我是OpenACC新手,但已经与OpenMP并行

    !$acc parallel loop
    do 9000 j=2,jmaxm
    jm=j-1 
    jp=j+1

    do 9001 i=2,imaxm
    im=i-1
    ip=i+1

    if(rmask(i,j).eq.1.0) then


   ! Calculate un field

un(i,j,kp)=un(i,j,km)+ tdt*rmask(i,j)*(
 +    txsav(i,j)*zn(nmm)/xpsi2(nmm)+ visch*zetun(i,j)
 +   -recdx*(pn(ip,j,k)-pn(i,j,k))-a*un(i,j,km)/cn(nmm)**2
 +   +0.25* fu(i,j)*(vn(i,j,k)+vn(ip,j,k)+vn(i,jm,k)+
 +    vn(ip,jm,k))
 +   -damp(i,j)*un(i,j,km)
 +   )

 c SBnd damper is not used
 cc     +   -(1./timkwd)*dampu(i,j)*un(i,j,km)

 ! Calculate vn field

    vn(i,j,kp)=vn(i,j,km)+ tdt*rmask(i,j)*(
 +    tysav(i,j)*zn(nmm)/xpsi2(nmm)+visch*zetvn(i,j)
 +   -recdy*(pn(i,jp,k)-pn(i,j,k))-a*vn(i,j,km)/cn(nmm)**2
 +   -0.25*fv(i,j)*(un(im,jp,k)+un(i,jp,k)+un(im,j,k)+
 +    un(i,j,k))
 +   )

 c EBnd damper is not used
 cc     +   -(1./timkwd)*dampv(i,j)*vn(i,j,km)

 ! Calculate pn field

    pn(i,j,kp)=pn(i,j,km)+tdt*rmask(i,j)*(
 +    cn(nmm)**2*(
 +   -recdx*(un(i,j,k)-un(im,j,k))
 +   -recdy*(vn(i,j,k)-vn(i,jm,k)))
 +   -a*pn(i,j,k)/cn(nmm)**2
 +   -dampu(i,j)*cn(nmm)/dx*pn(i,j,km)
 +   -dampv(i,j)*cn(nmm)/dx*pn(i,j,km)
 +   -damp(i,j)*pn(i,j,km)
 +   )

    rhon(i,j)=-pn(i,j,kp)/g
    wn(i,j)=
 +   -recdx*(un(i,j,kp)-un(im,j,kp))
 +   -recdy*(vn(i,j,kp)-vn(i,jm,kp))

    endif
 9001    continue
 9000    continue
 !$acc end parallel loop

你有数据依赖性,这意味着你的算法本质上是连续的


一个简单的例子是Gauss-Seidel和Jacobi迭代之间的差异,以及为什么人们在GPU中使用Jacobi而不是Gauss-Seidel,

问题是什么?它到底说了什么?看来您的循环在迭代中有一些复杂的依赖关系。您可以尝试使用独立关键字强制编译器生成内核并忽略依赖项检测,但这可能会生成一个连续的内核。你用的是什么编译器?你在哪里写的pragmas?我需要知道是否有可能在GPU上用openacc@Ruyk我在已编辑的代码中添加了pragmas。我两个都试过了$行政协调会各部分和$acc平行环普拉格马,两者在我的情况下训练相同。我正在使用PGI Fortran Workstation 2013。我认为这可能是并行化的,但您还没有充分展示正在发生的事情。我猜在
k
中的某个地方有一个循环,您还没有显示出来。无论如何,您有循环携带的依赖项,例如,
un
计算依赖于其他相邻的
un
数量(例如,
un(i,j,km)
),编译器将对此感到窒息。一种方法是使用两个
un
数组,例如
un
unn
,并在它们之间进行乒乓计算,即
unn(i,j,kp)=un(i,j,km+tdt…
等。另外,我通常会先尝试
!$acc内核,然后再尝试其他内核。你可以使用红黑高斯-赛德尔。当然,我只是想指出不同之处,如果你想也可以使用GMRES:-),spasiba