fortran和分段错误中!$ OMP PARALLEL的问题

问题描述

我对于fortran还是相当陌生,对于openmp还是很陌生。我已经从同事那里继承了一个fortran代码,并被要求使用openmp对其进行并行化。该代码最初是从matlab转换而来的,无需使用openmp即可正常运行。但是当我尝试并行化它时,我遇到了不同的问题。

我只有一个do循环,里面包含多个计算,例如:maxval,reshape,sum,sum和product和几个where语句(我正在复制下面的一些代码)。我正在阅读教程,有些建议使用关键部分,其他建议减少使用,另一些则使用工作共享。现在的代码如下,我没有显示所有变量,因为它会更长:

subroutine COMPUTE_RIM(variables)
    use hdf5   
    use omp_lib
    use precision,only: pr => sp !it's a module to define number precision,I'm using single prec.
    implicit none
    
    !variable declaration. I'm showing some as an example
    integer                                    :: NAN = -9999
    integer(hsize_t),dimension(1:2)            :: lat_dims
    real(pr),dimension(480,1440,96)            :: precipitation_new
    real(pr)                                   :: dilf,rim,hyc,pick
    real(pr),allocatable,dimension(:)          :: dilIns,dil,wVec
    real(pr),dimension(:,:)        :: t_rain,dil_Hyst,dilM,cc,time
    integer                                    :: a,b,aa,bb,id1,kz1,cc2,timeIns
    integer,dimension(:)           :: lat_indF,long_indF,ind_rowF,ind_colF,indNan2
    integer,:)         :: indNan1
    real(pr),dimension(1,lat_dims(2))          :: sec
    real(pr),dimension(lat_dims(1),lat_dims(2)):: anc_sss
    
    !arrays allocation,I'm showing some
    allocate(sample_time(1,48),t_dif(1,t_rain(13,49),indNan1(13,indNan2(13))
    allocate(dilM(13,time(13,cc(13,dilIns(13),dil_Hyst(13,dil(13))
    allocate(wVec(13),RIM_SSS(lat_dims(1),lat_dims(2)))
    
    !arrays initialization,showing some
    t_rain(:,:) = NAN
    RIM_SSS(:,:) = NAN
    
    !defining parameters
    z = 0.005_pr !just one example,there are more param. that are used in the loop
    
    !$OMP PARALLEL PRIVATE(b,a,pick,id1)    
    !$OMP DO  
    do itemp = 1,size(lat_indF)     
       a = ind_rowF(itemp)        
       b = ind_colF(itemp)          
       aa = lat_indF(itemp) - 120     
       bb = long_indF(itemp)         
    
       t_dif = (sample_time - (sec(1,b)/3600._pr))    
       hyc = anc_sss(a,b)     
    
       !$OMP CRITICAL    
            pick = maxval(pack(t_dif,t_dif .lt. 0))
            id1 = maxloc((pack(t_dif,t_dif .lt. 0)),dim=1)    
       !$OMP END CRITICAL
    
       timeIns = -pick*3600._pr;
    
       !$OMP CRITICAL
            t_rain(1,:) = reshape(precipitation_new(aa - 2,id1:id1 + 48),shape(t_rain(1,:)))
       .
       .
       .
       !$OMP END CRITICAL
    
       where (t_rain .ge. 0)
            indNan1 = 1
       elsewhere
            indNan1 = 0
       endwhere
    
       dilM = (1._pr + (((t_rain(:,1:48)*real(indNan1(:,1:48),pr)*(cc/1000._pr))/&
       (sqrt(time*kz1)))*exp((-z**2._pr)/(4._pr*kz1*time))))
       dilIns = (1._pr + (((t_rain(:,49)*real(indNan1(:,pr)*((1800._pr*cc2)/&
       3600._pr)/(1000._pr))/(sqrt(timeIns*kz1)))*exp((-z**2._pr)/(4._pr*kz1*timeIns))))
       dil_Hyst(1:13,1:48) = dilM
       dil_Hyst(1:13,49) = dilIns
    
       dil = (product(dil_Hyst,2))**(-1._pr)
       dilf = (sum((dil*wVec*real(indNan2,pr)),1))/(sum(wVec*real(indNan2,pr),1)) 
       rim = hyc*dilf;

       RIM_SSS(a,b) = rim
    enddo
    !$OMP END DO
    !$OMP END PARALLEL\
 !deallocate variables

我将代码编译为:gfortran -fopenmp -g -fcheck =所有主要main.f90(和hdf5模块)

到目前为止,我已经尝试过:

  1. 原样的代码可以编译并运行(假设我执行ulimit -s unlimited),但是会产生错误的结果。它与应有的外观相似,但有很多噪音(污染,值很大或非常小。可变边距不应大于50或小于0,除非靠近未定义的边界且应为-9999或NaN)。

  2. 即使代码按原样运行,执行perf stat ./main也会出现分段错误。

  3. 如果不执行ulimit -s unlimited,则会出现分段错误。

  4. 如果我将工作共享添加到!$ OMP PARALLEL,它将无法识别!$ OMP DO。它说:意外的!$ OMP DO语句在(1)。

我在另一篇文章中读到我可以做vagrind ./main,然后得到:

==6309== Warning: client switching stacks?  SP change: 0x1ffefffd28 --> 0x1fdf5bf7d0
==6309==          to suppress,use: --max-stackframe=530842968 or greater
==6309== Invalid write of size 8
==6309==    at 0x115974: MAIN__ (main_omp.f90:6)
==6309==  Address 0x1fdf5bf9f8 is on thread 1's stack
==6309== 
==6309== Can't extend stack to 0x1fdf5be888 during signal delivery for thread 1:
==6309==   no stack segment

由于我的经验不足,我无法理解我是否有基本错误或基本错误。我是否以错误的方式使用了openmp指令,或者缺少了一些? 任何帮助表示赞赏。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...