Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
Announcements
Welcome to the Intel Community. If you get an answer you like, please mark it as an Accepted Solution to help others. Thank you!
26730 Discussions

double free or corruption with private pointer and OpenMP parallel do

Ines_F_
Beginner
548 Views

Hi all,

I'm having a double free or corruption problem when trying to use the Reallocate function (from Fortran 90 Numerical Recipes) within an OpenMP parallel do directive

*** glibc detected *** ./myprog: double free or corruption (out): 0x00007ffdf7d770f0 ***

Here is the reallocate function :

FUNCTION reallocate_iv(p,n)
    INTEGER(I4B), DIMENSION(:), POINTER :: p, reallocate_iv
    INTEGER(I4B), INTENT(IN) :: n
    INTEGER(I4B) :: nold,ierr
    allocate(reallocate_iv(n),stat=ierr)
  
    if (ierr /= 0) call &
	nrerror('reallocate_iv: problem in attempt to allocate memory')
    if (.not. associated(p)) RETURN
	nold=size(p)
  
    reallocate_iv(1:min(nold,n))=p(1:min(nold,n))
    deallocate(p)
END FUNCTION reallocate_iv

and here is the main body of the code calling reallocate within an OpenMP parallel do directive :

Integer, Dimension(:), POINTER :: col_sprZ
Integer :: nnz, size,spr_perc,spr_size

!$OMP PARALLEL PRIVATE (size,spr_size,,col_sprZ,nnz) 
!$OMP DO SCHEDULE(DYNAMIC)
do kk=1,NB
      spr_size = nint((spr_perc*9.*size**2.)/100.)
      Allocate(col_sprZ(spr_size));
      !! here Call a Subroutine which calculates nnz and col_sprZ (sparse format storage)   
      col_sprZ => Reallocate(col_sprZ,nnz);            
      - - - - - - - - - - - - -                
      Deallocate(col_sprZ);
enddo
!$OMP END DO
!$OMP END PARALLEL

The code works perfectly and yields good results if I discard/comment the OpenMP directive or compile with the -O0 -openmp  -heap arrays. It works also fine if I keep the openmp directive and compile with -O3 -openmp -heap arrays but use a classic temporary allocatable array to reallocate col_sprZ instead of the reallocate function.

I also noticed that the problem could disappear if I decrease the size of the array col_sprZ. I haven't the required authorization to check if the problem is caused by the stack size limits.

I am using intel composer 13.1.3 on Linux.

Did anyone understand or see the cause of this problem ? Thanks !

0 Kudos
7 Replies
jimdempseyatthecove
Black Belt
548 Views

Try this:

Prior to the parallel region, nullify col_sprZ
on the $omp parallel statement, identify col_sprZ as firstprivate (this is to copy in the NULLed pointer)
Following the Deallocate(col_sprZ), nullify col_sprZ

I cannot say that this will fix your problem (you have a rather old version of Fortran), the changes above make the program more conforming to the standard.

Jim Dempsey
 

Ines_F_
Beginner
548 Views

Thank your for taking the time to answer my question !

I tried what recommended and I got this :

forrtl: severe (174): SIGSEGV, segmentation fault occurred
Image              PC                Routine            Line        Source             
myprog             00000000004BC379  nrutil_mp_realloc         219  nrutil.f90

The segmentation fault occurs from the beginning in the reallocate function here :

reallocate_iv(1:min(nold,n))=p(1:min(nold,n))

I checked nold and n and they correspond well to the initial/old size of p and the new size (nnz). So I don't really see what causes this segmentation fault. I increased the stack size limit : ulimit -s 2048 but I didn't change anything.

When I keep the nullify before and inside the parallel region, but I declare the pointer as PRIVATE and not FIRSTPRIVATE, I have

glibc detected *** ./myprog: munmap_chunk(): invalid pointer: 0x00002ae5e6b8bcc0

But the code runs longer, it seems to crash when leaving the do loop ! But I haven't any information about the line causing the problem. When I compile with -O3 -openmp -check all -traceback -heap-arrays, I of course loose the optimization (disabling optimization; runtime debug checks enabled) and the code runs perfectly and give accurate results ! so I haven't any further information about the 'munmap_chunk(): invalid pointer' problem.

 Would you have any other suggestion ?  

Thanks !

jimdempseyatthecove
Black Belt
548 Views

>>But the code runs longer, it seems to crash when leaving the do loop

Verify this by something like:

...
!$OMP END DO
print *,omp_get_thread_num()
!$omp barrier
!$omp master
print *,"exiting region"
!$omp end master
!$OMP END PARALLEL
print *,"out of region"

This may be a case where the problem lies with code not shown (-  -  -  -).

Jim Dempsey

jimdempseyatthecove
Black Belt
548 Views

Also as an aid:

!$OMP PARALLEL DEFAULT(NONE), PRIVATE (size,spr_size,,col_sprZ,nnz) 

** then specifically add , SHARED(...) for those you know can be shared and won't be reallocated while running the parallel region.

Jim Dempsey

Ines_F_
Beginner
548 Views

I accidentally removed the subroutine, and when I modified a previous version very quickly, the code ran perfectly with the reallocate function the -O3 debug option and the OpenMP directive !!! 

The only difference I noticed is a certain M=3*size inside the parallel region, which I used to avoid repeating 3*size each time I need it (see code below) ! I checked by using M=3*size again and the code crashes. I don't understand exactly what was the problem, since M is declared as private and used also later in the same do loop, but I think that NULLIFY did the biggest part of the job. Many thanks for your help !

Allocate(Zspr(spr_size),row_sprZ(3*size+1),col_sprZ(spr_size));  
Call SR_Green_s_tr(size,Cells,spr_size,sameEps,nnz,Zspr,row_sprZ,col_sprZ)
            
Zspr => reallocate(Zspr,nnz);
col_sprZ => reallocate(col_sprZ,nnz);
             
iparm3 = 0; ! here iparm3 is not used
Call pardiso_solver(3*size,2*Nb,nnz,mtype,iparm3,row_sprZ,col_sprZ,Zspr,ER,E) 
Deallocate(Zspr,row_sprZ,col_sprZ);
NULLIFY(Zspr,row_sprZ,col_sprZ);

Ines

Ines_F_
Beginner
548 Views

Finally I think that what solved the problem, in addition to NULLIFY is that I increased the stack size limit to 2048 (ulimit -s 2048). 

Thanks !

 

jimdempseyatthecove
Black Belt
548 Views

>>The only difference I noticed is a certain M=3*size inside the parallel region, which I used to avoid repeating 3*size each time I need it

Perhaps M was unexpectedly modified after being set. Note: call Something(M,...) may potentially modify M whereas trashing the expression argument would do no harm.

Glad you are working.

Jim Dempsey

Reply