Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

Heap corruption with OpenMP

Andrew_Smith
Valued Contributor I
2,011 Views

I am still having problems getting consistent numbers from OpenMP code.

I have been enclosing code in CRITICAL blocks and gradually reducing the amount in the block until failure occures but not getting very consistent behaviour with this.

Here is a bug I came accross which has not occured in the actual code but is centered around local allocatables which I am suspicious about since they usually end up in my critical blocks when the code works.

This test code allocates some local variables and they get automatically destroyed on exit.I get heap corruption errors 50% of the times I run it. If I delete the assignmentor delete the local variable b the error goes away!! Please run it with default project settings for debug mode. If you explictly deallocate then the problem is still present.

Using VS2005 and IVF 10.1.024 on Vista64

module

subs

implicit none

contains

subroutine

sub1()

integer status

real, allocatable :: a(:), b(:,:)

allocate(a(6000), stat = status)

allocate(b(6000,6000), stat = status)

a = 1.0

!deallocate(a,b)

end subroutine

end module

program

OpenMPBugTest

use subs

implicit none

integer i

!$OMP PARALLEL DO DEFAULT(SHARED)

do i = 1, 20000

call sub1()

end do

end

program

0 Kudos
7 Replies
jimdempseyatthecove
Honored Contributor III
2,011 Views

I haven't tried to reproduce your error but try changing

real, allocatable :: a(:), b(:,:)

to

real, automatic, allocatable :: a(:), b(:,:)

In the 1st case the descriptors for the arrays _may_ be assumed SAVE'd (depending on options)
and if SAVE'd the multiple threads will trash the allocation/deallocation.

In the 2nd case the descriptors for the arrays are required to be stack local.

If you try a fix using automatic, please report back on success or failure.

Jim Dempsey

0 Kudos
jimdempseyatthecove
Honored Contributor III
2,011 Views
also, remember to deallocate.
0 Kudos
Steven_L_Intel1
Employee
2,011 Views
The deallocate is not required in this case - it should be deallocated automatically at the end of the subroutine.

A few weeks ago I investigated a customer issue that looks a lot like this one - a call to a routine inside a parallel region with a local allocatable array. The symptom there was an access violation. But I can't get your example to fail.
0 Kudos
Andrew_Smith
Valued Contributor I
2,011 Views
The use of the OpenMP compiler option in IVF forces local variables to be automatic so I should not need to use explicit automatic.

I tried anyway and got into another problem. I get status code 151. No memory is allocated however a tghinks it has a size with undefined status for the elements. It crashes on subroutine exit attempting to automatically deallocate the mess. I guessed I might have hit a stack size limit so I tried both stack size options (since I don't know which to use) up to 150000000 (150MByte?) without success. I also tried setting the heap arrays option to 0 without any sucess.
0 Kudos
Andrew_Smith
Valued Contributor I
2,011 Views
I also tried with small arrays and it still fails. I reported a similar allocation failure bug recently but I thought that it only happens with /Qtrapuv. But this time is without /Qtrapuv so it looks like allocatable locals with OpenMP are not behaving properly at all.

module subs
implicit none

contains

subroutine sub1(i,n)
integer, intent(in) :: i,n
integer status
real, allocatable, automatic :: a(:), b(:,:)
real tot
tot = (n + n*n)*4
allocate(a(n), b(n,n), stat = status)
if (status == 0) then
a = 1.0
deallocate(a,b)
else
continue
end if
end subroutine

end module

program OpenMPBugTest
use subs
implicit none

integer i
!$OMP PARALLEL DO
do i = 1, 20000
call sub1(i,6)
end do
end program


0 Kudos
jimdempseyatthecove
Honored Contributor III
2,011 Views

Andrews,

>>The use of the OpenMP compiler option in IVF forces local variables to be automatic so I should not need to use explicit automatic.

I have not tried this with the latest version of IVF, but on the version circa April 2008, my code with OpenMP enabled and using

REAL :: VECTOR(3)

In a subroutine would create VECTOR(3) as a SAVE variable (array). When using

REAL, AUTOMATIC:: VECTOR(3)

The correct code was always generated (correct == stack local storage).

This quirk not only appeared on my system but also on a customer system (via consulting contract) who called me in to resolve intermittant errors in their "looks good to me" code. This error is obvious when stepping through the code section using the Dissassembly window, otherwise the code looks error free (and is error free when run single threaded).

Since I have often experienced fixed bugs returning in later revisions (even in IVF) I have resorted to placing AUTOMATIC on all local vectors that are required to be stack local. (YMMV)

Jim Dempsey

0 Kudos
Steven_L_Intel1
Employee
2,011 Views
When you say /Qopenmp, AUTOMATIC is the default for local variables. With an ALLOCATABLE, this means that the descriptor is on the stack - the allocated memory is on the heap. There is a bug if you say AUTOMATIC and ALLOCATABLE in a main program - the use of /Qtrapuv tends to make it more obvious.
0 Kudos
Reply