为什么move_alloc不能在gfortran(4.6.3)中运行,但它在ifort中?

时间:2013-05-13 23:05:59

标签: fortran gfortran dynamic-allocation intel-fortran

我在这里读到,自从gfortran 4.2以来move_alloc正常工作。我在我的ubuntu 12.04中安装了gfortran 4.6但是move_alloc无效! move_alloc在一个运行10次的循环中使用了五次。 在使用gfrotran编译(没有任何错误或警告)之后,程序只运行循环的一步(一些打印以验证任何错误)并显示“分段错误(记录内核映像)”。但是,当使用ifort时,程序运行正常。 我也尝试在CentOS中使用gfortran 4.4.6。 两台计算机都是x86_64。

其他重要信息:这段代码在一个子程序中,在一个模块内部,一旦我以前不知道由move_alloc分配的向量的大小。所有这些向量都在子例程中具有属性intent(out)。 xray_all,yray_all和elem_all是双精度,另一个是整数。主要和模块在不同的文件中。 这是我使用move_alloc的代码片段:

program main
double precision,allocatable,dimension(:)::xrayall,yrayall
(...)other allocatable variables
call yyyy(....,ray_indent,xray_all,...)
end program main 

module xxxx
subroutine yyyy
do j=1,10
  <lots of calculation>

     allocate( vec_aux( 1:(i+size(ray_indent) ) ) )
     vec_aux(1:size(ray_indent))=ray_indent
     vec_aux(size(ray_indent)+1:)=j   
     call MOVE_ALLOC(vec_aux,ray_indent) 

    allocate( vec_auxreal( 1:(i+size(xray_all) ) ) )
    vec_auxreal(1:size(xray_all))=xray_all
    vec_auxreal(size(xray_all)+1:)=xray
    call MOVE_ALLOC(vec_auxreal,xray_all)          

    allocate( vec_auxreal( 1:(i+size(yray_all) ) ) )
    vec_auxreal(1:size(yray_all))=yray_all
    vec_auxreal(size(yray_all)+1:)=yray
    call MOVE_ALLOC(vec_auxreal,yray_all)             

    elemsize=count(icol/=0);

     allocate( vec_auxreal( 1:(elemsize+size(elem_all) ) ) )
     vec_auxreal(1:size(elem_all))=elem_all
     vec_auxreal(size(elem_all)+1:)=elem(1:elemsize)
     call MOVE_ALLOC(vec_auxreal,elem_all)         

     allocate( vec_aux( 1:(elemsize+size(icol_all) ) ) )
     vec_aux(1:size(icol_all))=icol_all
     vec_aux(size(icol_all)+1:)=icol(1:elemsize)
     call MOVE_ALLOC(vec_aux,icol_all)

    allocate( vec_aux( 1:(elemsize+size(irow_all) ) ) )
    vec_aux(1:size(irow_all))=irow_all
    vec_aux(size(irow_all)+1:)=j+control           !
    call MOVE_ALLOC(vec_aux,irow_all)
end do
end module xxxx
end subroutine yyyy

1 个答案:

答案 0 :(得分:0)

我找到了解决方案!在gfortran中,必须在所有五个表达式中添加以下if语句:

 allocate( vec_auxreal( 1:(elemsize+size(elem_all) ) ) )
 if (j/=1) vec_auxreal(1:size(elem_all))=elem_all 
 vec_auxreal(size(elem_all)+1:)=elem(1:elemsize) 
 call MOVE_ALLOC(vec_auxreal,elem_all)

这种情况发生的原因是,如果向量仍为空,则无法识别是否要添加任何内容。在ifort中(在12.0版中测试),此if语句对于程序工作不是必需的。