Question

I've read here that move_alloc works since gfortran 4.2. I'm with gfortran 4.6 installed in my ubuntu 12.04 but move_alloc is not working! The move_alloc is used five times inside a loop that runs 10 times. After compiled (without any error or warning) with gfrotran, the program runs only one step (some prints to verify any mistake) of the loop and shows "segmentation fault(kernel image recorded)'. However, when ifort is used, the program runs and works correctly. I also have tried to use gfortran 4.4.6 in CentOS. Both computers are x86_64.

Other important information: this piece of the code is in a subroutine, inside a module, once I don't know previously the size of the vector that are allocated by move_alloc. All these vector are with the attribute intent (out) in the subroutine. xray_all, yray_all and elem_all are double precision and the other are integer. The main and the module are in different files. Here is the piece of the code where I use 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
Was it helpful?

Solution

I have found the solution! In gfortran is necessary to add the following if statement in all five expressions:

 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)

This happens because, in gfortran if the vector is still empty, it is not recognized that nothing is to be added. In ifort (tested in version 12.0), this if statement is not necessary to the program work.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top