首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我不能让!$acc并行工作(但acc内核可以)

我不能让!$acc并行工作(但acc内核可以)
EN

Stack Overflow用户
提问于 2018-04-16 21:14:08
回答 1查看 66关注 0票数 0

我一直在尝试用一个简单的代码来使用OpenACC,但是我想我并不完全理解如何编写嵌套的OpenACC循环,或者私有是做什么的。我尝试并行化的例程是:

代码语言:javascript
复制
SUBROUTINE zcs(zc,kmin,kmax,ju2,jl2)                                                                                                                                                            
INTEGER, INTENT(IN) :: kmin,kmax,ju2,jl2                                                                                                                                                      
DOUBLE PRECISION, DIMENSION(-jl2:jl2,-jl2:jl2,-ju2:ju2,-ju2:ju2,kmin:kmax,kmin:kmax,-kmax:kmax) :: zc                                                                                         

INTEGER :: k,kp,k2,km,kp2,q,q2,mu2,ml2,p2,mup2,pp2,mlp2,ps2,pt2                                                                                                                               
DOUBLE PRECISION :: z0,z1,z2,z3,z4,z5,z6,z7                                                                                                                                                   


! Start loop over K, K' and Q                                                                                                                                                                 
!$acc kernels                                                                                                                                                                                 
do k=kmin,kmax                                                                                                                                                                                
   do kp=kmin,kmax                                                                                                                                                                            
      k2=2*k                                                                                                                                                                                  
      km = MIN(k,kp)                                                                                                                                                                          
      kp2=2*kp                                                                                                                                                                                
      z0=3.d0*dble(ju2+1)*dsqrt(dble(k2+1))*dsqrt(dble(kp2+1))                                                                                                                                
      do q=-km,km                                                                                                                                                                             
         q2=2*q                                                                                                                                                                               

         ! Calculate quantity C and its sum over magnetic quantum numbers                                                                                                                     
         do mu2=-ju2,ju2,2                                                                                                                                                                    
            do ml2=-jl2,jl2,2                                                                                                                                                                 
               p2=mu2-ml2                                                                                                                                                                     
               if(abs(p2).gt.2) cycle                                                                                                                                                         
               z1=w3js(ju2,jl2,2,mu2,-ml2,-p2)                                                                                                                                                
               do mup2=-ju2,ju2,2                                                                                                                                                             
                  if(mu2-mup2.ne.q2) cycle                                                                                                                                                    
                  pp2=mup2-ml2                                                                                                                                                                
                  if(abs(pp2).gt.2) cycle                                                                                                                                                     
                  z2=w3js(ju2,jl2,2,mup2,-ml2,-pp2)                                                                                                                                           
                  do mlp2=-jl2,jl2,2                                                                                                                                                          
                     ps2=mu2-mlp2                                                                                                                                                             
                     if(abs(ps2).gt.2) cycle                                                                                                                                                  
                     pt2=mup2-mlp2                                                                                                                                                            
                     if(abs(pt2).gt.2) cycle                                                                                                                                                  
                     z3=w3js(ju2,jl2,2,mu2,-mlp2,-ps2)                                                                                                                                        
                     z4=w3js(ju2,jl2,2,mup2,-mlp2,-pt2)                                                                                                                                       
                     z5=w3js(2,2,k2,-p2,pp2,q2)                                                                                                                                               
                     z6=w3js(2,2,kp2,-ps2,pt2,q2)                                                                                                                                             
                     z7=1.d0                                                                                                                                                                  
                     if(mod(2*ju2-ml2-mlp2,4).ne.0) z7=-1.d0                                                                                                                                  
                     zc(ml2,mlp2,mu2,mup2,k,kp,q)=z0*z1*z2*z3*z4*z5*z6*z7                                                                                                                     
                  enddo                                                                                                                                                                       
               enddo                                                                                                                                                                          
            enddo                                                                                                                                                                             
         enddo                                                                                                                                                                                

      end do                                                                                                                                                                                  
   end do                                                                                                                                                                                     
end do                                                                                                                                                                                        

!$acc end kernels                                                                                                                                                                             
END SUBROUTINE zcs  

实际上,代码运行良好,如果我在调用此例程后比较zc矩阵,那么非OpenACC和OpenACC版本都给出了相同的答案。但是如果我尝试使用parallel指令来做这件事,似乎有一个竞争条件,那就是我找不到它在哪里。相关的更改只是:

代码语言:javascript
复制
!$acc parallel                                                                                                                                                                                
!$acc loop private(k,kp,k2,km,kp2,z0,q,q2)                                                                                                                                                    
do k=kmin,kmax                                                                                                                                                                                
   do kp=kmin,kmax                                                                                                                                                                            
      k2=2*k                                                                                                                                                                                  
      km = MIN(k,kp)                                                                                                                                                                          
      kp2=2*kp                                                                                                                                                                                
      z0=3.d0*dble(ju2+1)*dsqrt(dble(k2+1))*dsqrt(dble(kp2+1))                                                                                                                                
      do q=-km,km                                                                                                                                                                             
         q2=2*q                                                                                                                                                                               

         ! Calculate quantity C and its sum over magnetic quantum numbers                                                                                                                     
         !$acc loop private(mu2,ml2,p2,z1,mup2,pp2,z2,mlp2,ps2,pt2,z3,z4,z5,z6,z7)                                                                                                            
         do mu2=-ju2,ju2,2                                                                                            


 [...]

!$acc end parallel  

据我所知,我已经将适当的变量声明为private,但我猜我并不完全理解如何嵌套多个循环,以及/或者private真正做什么。有什么建议可以帮助我正确地理解发生了什么吗?

非常感谢,AdV

EN

回答 1

Stack Overflow用户

发布于 2018-04-17 03:00:25

这里的核心问题是通过引用"w3js“例程来传递循环边界变量"ju2”和"jl2“。这意味着循环跳转计数可能会在循环执行期间发生变化,从而阻止并行化。您可以尝试将这些变量设置为私有,但最简单的做法是在w3js的参数上添加" value“属性,这样它们就可以通过值传递。

请注意,它在“内核”的情况下工作,因为编译器只并行外部循环。在“并行”的情况下,您将尝试并行化这些“不可数”的内部循环。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49858252

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档