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

Is there an easy way to determine the maximum stackspace needed by a large program

butette
Beginner
889 Views

instead of having to keep guessing and moving the stack limit boundary ?

thanks.

0 Kudos
8 Replies
Steven_L_Intel1
Employee
889 Views
Not that I am aware of. But you may find it simpler to just enable /heap-arrays (in VS, set the property Optimization > Heap Arrays to 0.)
0 Kudos
butette
Beginner
889 Views

Yes I am aware of the -heap-arrays option. I was just wondering if it is possible to determine the stackspace requirement for portability purpose.

Thanks.

0 Kudos
jimdempseyatthecove
Honored Contributor III
889 Views

Assuming your development system has sufficient memory

Near the start of the program (in the main)call a subroutine that creates a large stack object that consumes several times the size that you think you will require (maybe do this in C/C++). Then prefill the large stack object with a signature (e.g. longs of 123456789). Exit this function (reclaiming the stack space). Run your program under a stress test (what you think will produce a worst case stack consuming situation). At the end of the program, call a second subroutine (maybe do this in C/C++) that creates the same large stack object, but this time it counts the number of longs that are NOT your signature. Multiply the result by sizeof(long) and you will have some idea as to the stack requirements.

Note, this will not determine the size of stack consumed by OpenMP threads. For that, run the stack set and stack check within seperate !$OMP PARALLEL/!$OMPEND PARALLELregions.

Jim Dempsey

0 Kudos
butette
Beginner
889 Views

Steve,

Does heap-array handling apply to the private arrays in an parallel region as well if you use that option ?

Thanks.

0 Kudos
Ron_Green
Moderator
889 Views

you really do NOT want to use -heap-arrays if you use -openmp or -parallel. Private need to go on stack, heap is global and all threads will have access to the same memory.

Don't use -heap-arrays with -openmp.

Another thought is to download and install the Ganglia utility. This tool monitors a server for cpu utilization, IO, disk activity and memory and paging activity. It has a nice graphical display too and saves history. I use this to tweak programs to use almost all of the node memory, avoiding paging. Generally, I target 80% of real memory for the program use, the other 20% leaving free for IO buffers, MPI buffers, misc system overhead.

0 Kudos
jimdempseyatthecove
Honored Contributor III
889 Views

>>Don't use -heap-arrays with -openmp

Ron,

When you structure your code such that the array descriptors are on the stack then -heap-arrays will work with OpenMP

recursive subroutine foo()
real :: array(123456789)
...
end subroutine foo
...
!$omp parallel
call foo()
!$omp end parallel

The above should be fine.
(unfortunately the standards committee decided to re-use recursive instead of creating a new, and more meaningful, keyword)

Jim Dempsey

0 Kudos
Tim_Gallagher
New Contributor II
889 Views

This is semi-related --

Are you saying that a routine declared as RECURSIVE puts the arrays on the stack always? I have a code with a recursive routine that allocates arrays (it's to build an oct-tree) and I get the segfault from the stack overflowing. I've used heap-arrays/ulimit to avoid it, but I couldn't figure out why it was doing it.

If I understood you correctly and RECURSIVE routines always put stuff on the stack, then I know how to fix the problem...

Tim

0 Kudos
jimdempseyatthecove
Honored Contributor III
888 Views

>>Are you saying that a routine declared as RECURSIVE puts the arrays on the stack always?

No. Re-read my message.

RECURSIVE routine places array descriptors on stack (excepting for those with SAVE attribute)

Then -- depending on size and/or if -heap-arrays is in effect, the allocation will come from either stack or heap.
The array descriptor is thread private.

If from heap then "only" the the thread that has access to the array descriptor (only one of the OpenMP threads) will be able to access the memory (excepting when pointer made into or reference made to array/part of array is passed into shared memory for access by other thread).

When allocated from stack you can still construct a pointer to it (in it) and place that where another thread can use it and thus "share" a stack allocated variable/array (or "share" where it used to live should you exit scope prior to other thread's use or errant use).

I used to program using Intel specific AUTOMATIC attribute (until Steve insisted that RECURSIVE was all that was necessary).

subroutine foo()
real(8), automatic :: point(3)

recursive subroutine foo()
real(8) :: point(3)

Will both place point on stack. automatic is not portable, recursive is portable.

I think that the Fortran standards committee should address the issue to permit a formal attribute to specify the intentions of where the array descriptor is to be placed. Hypothetically PRIVATE could be used for this

real :: y(3) ! placement unknown in the context of this statement
real, SAVE :: x(3) ! static (descriptor not on stack, data not on stack)
real, AUTOMATIC :: z(3) ! IVF descriptor on stack (data stack or heap depending on circumstance)
real, PRIVATE: q(3) ! invalid, but could potentially be used to specify stack based descriptor)
real, PRIVATE, AUTOMATIC :: qq(1234) ! could be used to required descriptor on stack, data on heap

Jim Dempsey

0 Kudos
Reply