I get a stack overflow exception when calling a subroutine containing an internal subroutine. If I rewrite my code and remove the internal, the exception goes away (the initial intention was to remove duplicated code).
Exception is thrown from chkstk.asm, not surprisingly. "test dword ptr [eax],eax ; probe page."
Not sure what would be the best course of action from there?
I am using VS 2019 with Intel Fortran Compiler 19.1. By the way, I looked everywhere but could not find the Disassembly View.
Do you have a (preferrably small) complete program that demonstates the issue? This will help to analyse what is going on. If your internal procedure uses a lot of local memory (automatic arrays), that could be the cause. But there are other possibilities. So the description you gave is not enough for a proper diagnosis.
I understand, however I don't have a complete program to share that demonstrates the issue. My program is thousands of lines of pure fun!
I was more looking for pointers (no pun intended), i.e., where should I look, what kind of tools could help me, etc. I was told INTERNAL functions regularly cause problems with Intel Compiler.
That is common enough a situation - a large program exhibiting a problem and no way to isolate it. I myself regularly use internal procedures but I have never seen anything specifically going wrong with that construct.
What are the characteristics of the internal procedure? Does it use a lot of local arrays? Is it part of a recursive procedure? Can you allocate large arrays instead of using automatic arrays?
Does setting the stack size larger (by a few KB) make any difference?
Does the code fail on the 1st call?
Is your program multi-threaded and the failure occurs only with non-master thread? If so, have you specified sufficient stack size for OpenMP created threads?
BTW using an internal (CONTAINS) subroutine won't necessarily eliminate duplicate code as the compiler optimization can potentially inline this subroutine (unless you make coding directives to not inline the subroutine).
Thanks for the article, very interesting indeed.
By tries and errors, I found that the threshold for the stack size is precisely 8MB.
"Does setting the stack size larger (by a few KB) make any difference?": yes.
"Does the code fail on the 1st call?": yes.
"Is your program multi-threaded": no.
I tried forcing the allocation of arrays on the heap with /heap-arrays set to 0, to no avail. I left it to 0 though, maybe better to put it back to blank.
OK there is really something going on with the INTERNAL subroutine, specifically.
My code has this structure:
subroutine A(a,b,c,d,e,f,g,...,z) ! Declare many arrays, everything is confirmed to be on the heap. call B() call B() Contains Subroutine B(scalar_a,scalar_b,scalar_c) ! Some stuff going on with A arrays. End Subroutine B End Subroutine A
With that code, stack is 8MB. If i undo B to duplicate the code the way it was before, the stack is well below 1MB.
Please show us an actual example that demonstrates the problem. My experience is that psuedocode or "it's like this" omits key information.
I don't know what you've been told, but I have never heard of an issue with internal procedures using excessive stack, and I've written a lot of them myself.
Create a new test case that shows the problem, omitting or changing code you don't want to show. We're not psychics.
If you are right, I won't be able to reproduce my problem with a simple example, that seems rather obvious to me. Otherwise, like you said, you would have heard about that before.
And since I cannot share my code, it sounds like this brings us back to square one.
You can work on this yourself. Selectively remove bits of subroutine B and see what changes. You can also look at the assembly code, or step through the call and see where the stack pointer is being subtracted from (allocating space on the stack.) It is almost certainly something not included in what you have posted so far.
I have a suggestion, though. you say "some stuff going on with A arrays". Array expressions are a common eater of stack space. Are you SURE you enabled heap-arrays? Setting the option to 0 and recompiling should do the trick.