Stack Overflow with OpenMP and ifort 10.1 using Visual Studio C++

Stack Overflow with OpenMP and ifort 10.1 using Visual Studio C++

I have a mixed C/F95 console application that runs fine without OpenMP on Windows, and also runs fine on Linux with OpenMP (using icc/ifort). Using OpenMP, even with one thread, I'm getting a stack overflow (exception in chkstk) upon entry into a particular subroutine (the first that uses OMP threads). I've tried setting KMP_STACKSIZE to 16m, 64m, 256m, as well as setting STACK:reserve to various values (for the stack of the initial thread). Nothing seems to help. The particular subroutine does have a fairly large fixed array (1 million doubles), but using /heap-array does not help.

The application uses two libraries:
- a F95 static library, compiled with ifort, that contains all of the OpenMP directives
- a C DLL that calls fortran, compiled with Studio 2005 C without OpenMP

Another OpenMP console application using the same static library runs fine (but does not call the offending subroutine).

Is there some issue with mixing ifort and VS2005 C with OpenMP, or something that I've missed related to the stack?

Thanks,
Matt

6 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

I'll note that setting the stack reserve option for the linker is ignored unless you are linking an EXE. A DLL doesn't count. Can you relink the EXE and raise the stack size?

/heap-arrays does NOT affect fixed-dimension arrays that are local variables and the "default local storage" is "automatic", which it is when you use OpenMP. Consider making those arrays ALLOCATABLE instead and allocating them to the desired size.

Steve - Intel Developer Support

Yes, the stack reserve was set on the EXE.

Not sure why the stack still did not fit when the reserve (both main thread and KMP_STACKSIZE) was set to 32MB -- perhaps ifort is putting lots of variables on the stack, but only for OpenMP.

Thanks for the explanation about /heap-arrays. Using allocatable did indeed fix the issue.

The ifort default, if you are NOT using OpenMP, is /auto-scalar, which causes local scalar variables of INTEGER, REAL, COMPLEX and LOGICAL types, which do not have the SAVE attribute, to be allocated on the stack (or perhaps just in registers) - all other variables are allocated statically.

If you say /Qopenmp (or /Qopenmp-stubs), this changes to /automatic - ALL local scalar variables are allocated on the stack. This is required to allow for thread-safety.

So if you have a subroutine with a large, fixed-dimension local array, such as:

real x(1000000)

that will be statically allocated without OpenMP but stack-allocated with OpenMP (unless you also say SAVE.) /heap-arrays does not affect this. What /heap-arrays would affect is if you had this:

subroutine sub (n)
integer n
real x(n)

This is what the language calls an "automatic array". The default (with or without OpenMP) is that X is stack-allocated, but /heap-arrays changes that to heap-allocated. The confusion comes when one looks at the switches such as /automatic and the AUTOMATIC declaration (which is an extension that dates back to the 1980s). The switch and declaration affect the choice of storage for local variables, but not what the language calls automatic arrays (a new concept in F90.) /heap-arrays affects automatic arrays (F90 meaning) but not AUTOMATIC arrays (extension meaning).

Steve - Intel Developer Support

steve,

How about my problem?

Joey_Hylton:
After changed the "implicit none"

I got new problem.

In one of my subroutines, I have to allocate some (many) arrays, and the sizes of these arrays are very large. If I defined them as this way

subroutine works(N)

implicit none

integer,intent(in)::N

real a(N),b(N),c(N)

a=0d0
...

end

this OpenMP process always give me a stack overflow error even I changed both the heap reserve and stack reserve sizes to large number, say 800,000,000

Acording to someone's suggestions, I changed the definition as

subroutine works(N)

implicit none

integer,intent(in)::N

real,save,allocatable,dimension(:) a,b,c

allocate(a(N),b(n),c(N))

a=0d0
...

end

I got an error as "attempt to fetch from allocatable variable a when it is not allocated" at the line of "a=0d0".

See my reply in your other thread.

Steve - Intel Developer Support

Leave a Comment

Please sign in to add a comment. Not a member? Join today