I'm working with Fortran90, but I don't have a lot of familiarity with it.
In some point of the code, I would like to create an array of n linearly equally spaced points between t0 and tf, so I tried this:
t = t0+(/(i,i=0,n-1)/)*(tf-t0)/(n-1)
Which is the same thing as:
do while(i<=n)
t(i) = i-1
i=i+1
end do
t = t*(tf-t0)/(n-1)+t0
However, if n is too large (n=2000001 or bigger), the first option doesn't work. I get the error:
forrtl: severe (170): Program Exception - stack overflow
Why is that? What can I do to make the implied do loops work for n large?
Some Fortran processors use a hardware stack for storage of temporaries created during evaluation of an expression. When the expression involves large objects - such as large arrays - the storage required for the temporaries may exceed the total storage available for the hardware stack, and the stack overflows.
In the first case it is likely that your Fortran processor is creating a large temporary to hold the result of the array constructor.
Different processors have differing capabilities in their ability to evaluate expressions without requiring temporaries - for example you may find that some processors also have stack overflow problems with your second example - the variable t that is assigned to is also referenced in the right hand side expression which may be enough for some Fortran processors to require evaluation of the entire right hand side to a temporary.
Your options are (perhaps in combination):
Use operating system or compiler switches to set aside more storage for the hardware stacks.
Use a compiler switch or similar that directs the processor to create temporaries on the heap instead of the stack.
Restate the overall operation in a different manner such that the compiler no longer creates temporaries (as you have already explored). This may include recasting the operation as an element by element operation in a do loop, rather than using operations directly on the arrays.
These approaches are platform specific. Based on the error message I guess you are using Intel Fortran (or an ancestor) on Windows - if so see the /heap-arrays
compiler option and the Windows linker option /stack
. If you are on linux see the ulimit
command.
With the implied loop, a temporary array is created in the stack, while with the explicit loop, each element is processed separately and no temporary array is created. Stack size is by default limited and hence the error with a sufficiently large array.
I'll add to the third point made by IanH that in order to help decide whether to restructure the code in order to avoid temporary arrays, it is worth considering using -Warray-temporaries with gfortran and -check arg_temp_created or, better, -check all, with ifort.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With