Fortran allocate large variable memory
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.
A good practice in Fortran is to put non-trivial arrays intended to be static/unchanged memory into an
allocatable,
protected
array.
Example:
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.
Fortran allocate large variables
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.