Variables that are larger than a few kilobytes often should be put into heap memory instead of stack memory.
In Fortran, compilers typically put variables with
parameter property into stack memory.
Our practice in Fortran is to put non-trivial arrays intended to be static/unchanged memory into an
module foo implicit none (type, external) integer, allocatable, protected :: x(:,:) contains subroutine init() allocate(x(1024,256)) !! in real life, this would be some constant data array or !! expression filling the "constant" array x. x = 1 end subroutine init end module program bar use foo, only : init, x call init() if (any(x /= 1)) error stop "did not init" end program
In this example, x is approximately a one megabyte variable, assuming kind=int32.
Even though the compiler may not warn if we instead declare this variable as
parameter, it can cause segfaults and other seemingly random runtime errors.
Normally we would use a derived type instead of a bare module, but we did it here for simplicity.
If the variable to be allocated is about one gigabyte or larger, sometimes special techniques are needed, even on systems with very large amounts of RAM including HPC. This is especially the case on Windows systems.
The error messages one may get upon allocating large variables in Fortran include:
Error allocating <N> bytes: Not enough space Segmentation fault (core dumped)
For Windows, a peculiar limitation is that each variable (including allocatable) cannot exceed the virtual paging file size, even if the Windows computer has large amount of RAM that isn’t being exceeded. The paging file size may be inspected and set under: Control Panel | System and Security | System | Advanced system settings | Advanced | Performance | Settings | Advanced | Virtual memory
In general, the compiler may need to have the memory model flag set for the situation. This flag has a set of implications.