Consider a program involving a large real automatic array that is saved on the heap. Suppose that the RAM of the machine is R and the operating system is OS.
Question: What is the largest number of elements this array can have?
As an illustration, I made some tests with R= 32 GB and OS = Ubuntu 22.04.
Code:
module s_mod
implicit none
private
public :: sfunc
contains
function sfunc(n) result(s)
! The purpose of this stupid function is to test a large automatic array.
integer, intent(in) :: n
real :: s
real :: x(n, n)
x = 1.0
s = sum(x)
end function sfunc
end module s_mod
program test_mem
use :: s_mod, only:sfunc
implicit none
integer :: i
integer, parameter :: n = 31
do i = 1, n
write (*, *) 2**i, sfunc(2**i)
end do
end program test_mem
System and hardware:
$ uname -a && lsmem
Linux zX10 5.15.0-56-generic #62-Ubuntu SMP Tue Nov 22 19:54:14 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
RANGE SIZE STATE REMOVABLE BLOCK
0x0000000000000000-0x0000000097ffffff 2.4G online yes 0-18
0x0000000100000000-0x000000085fffffff 29.5G online yes 32-267
Memory block size: 128M
Total online memory: 31.9G
Results:
-
gfortran
:
$ gfrotran --version && gfortran test_auto.f90 && ./a.out
GNU Fortran (Ubuntu 11.3.0-1ubuntu1~22.04) 11.3.0
Copyright (C) 2021 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
2 4.00000000
4 16.0000000
8 64.0000000
16 256.000000
32 1024.00000
64 4096.00000
128 16384.0000
256 65536.0000
512 262144.000
1024 1048576.00
2048 4194304.00
4096 16777216.0
8192 16777216.0
16384 16777216.0
32768 16777216.0
65536 16777216.0
131072 16777216.0
Program received signal SIGSEGV: Segmentation fault - invalid memory reference.
Backtrace for this error:
#0 0x7f4aabd60ad0 in ???
#1 0x7f4aabd5fc35 in ???
#2 0x7f4aabb5751f in ???
at ./signal/../sysdeps/unix/sysv/linux/x86_64/libc_sigaction.c:0
#3 0x55b94045f25a in ???
#4 0x55b94045f3b4 in ???
#5 0x55b94045f42b in ???
#6 0x7f4aabb3ed8f in __libc_start_call_main
at ../sysdeps/nptl/libc_start_call_main.h:58
#7 0x7f4aabb3ee3f in __libc_start_main_impl
at ../csu/libc-start.c:392
#8 0x55b94045f0e4 in ???
#9 0xffffffffffffffff in ???
Segmentation fault (core dumped)
ifort
$ ifort --version && ifort -heap-arrays test_auto.f90 && ./a.out
ifort (IFORT) 2021.8.0 20221119
Copyright (C) 1985-2022 Intel Corporation. All rights reserved.
2 4.000000
4 16.00000
8 64.00000
16 256.0000
32 1024.000
64 4096.000
128 16384.00
256 65536.00
512 262144.0
1024 1048576.
2048 4194304.
4096 1.6777216E+07
8192 6.7108864E+07
16384 1.3421773E+08
32768 1.3421773E+08
65536 1.3421773E+08
131072 1.3421773E+08
forrtl: severe (41): insufficient virtual memory
Image PC Routine Line Source
a.out 000000000040423B Unknown Unknown Unknown
a.out 000000000040415D Unknown Unknown Unknown
libc.so.6 00007F03C34CED90 Unknown Unknown Unknown
libc.so.6 00007F03C34CEE40 __libc_start_main Unknown Unknown
a.out 0000000000404075 Unknown Unknown Unknown
-
ifx
:
$ ifx --version && ifx -heap-arrays test_auto.f90 && ./a.out
ifx (IFORT) 2023.0.0 20221201
Copyright (C) 1985-2022 Intel Corporation. All rights reserved.
2 4.000000
4 16.00000
8 64.00000
16 256.0000
32 1024.000
64 4096.000
128 16384.00
256 65536.00
512 262144.0
1024 1048576.
2048 4194304.
4096 1.6777216E+07
8192 1.6777216E+07
16384 1.6777216E+07
32768 1.6777216E+07
65536 1.6777216E+07
131072 1.6777216E+07
forrtl: severe (41): insufficient virtual memory
Image PC Routine Line Source
a.out 0000000000405405 Unknown Unknown Unknown
a.out 000000000040515D Unknown Unknown Unknown
libc.so.6 00007F86C1A0DD90 Unknown Unknown Unknown
libc.so.6 00007F86C1A0DE40 __libc_start_main Unknown Unknown
a.out 0000000000405075 Unknown Unknown Unknown
nagfor
$ nagfor test_auto.f90 && ./a.out
NAG Fortran Compiler Release 7.0(Yurakucho) Build 7076
[NAG Fortran Compiler normal termination]
2 4.0000000
4 16.0000000
8 64.0000000
16 2.5600000E+02
32 1.0240000E+03
64 4.0960000E+03
128 1.6384000E+04
256 6.5536000E+04
512 2.6214400E+05
1024 1.0485760E+06
2048 4.1943040E+06
4096 1.6777216E+07
8192 1.6777216E+07
16384 1.6777216E+07
32768 1.6777216E+07
65536 1.6777216E+07
131072 1.6777216E+07
Runtime Error: Cannot get storage for variable - out of memory
Program terminated by fatal error
Aborted (core dumped)
flang
flang --version && flang test_auto.f90 && ./a.out
lang version 15.0.3
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /home/zaikunzhang/local/flang/bin
2 4.000000
4 16.00000
8 64.00000
16 256.0000
32 1024.000
64 4096.000
128 16384.00
256 65536.00
512 262144.0
1024 1048576.
2048 4194304.
4096 1.6777216E+07
8192 1.6777216E+07
16384 1.6777216E+07
32768 1.6777216E+07
65536 1.6777216E+07
131072 1.6777216E+07
0: ALLOCATE: 274877906944 bytes requested; not enough memory
nvfortran
$ nvfortran --version && nvfortran test_auto.f90 && ./a.out
nvfortran 22.11-0 64-bit target on x86-64 Linux -tp haswell
NVIDIA Compilers and Tools
Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2 4.000000
4 16.00000
8 64.00000
16 256.0000
32 1024.000
64 4096.000
128 16384.00
256 65536.00
512 262144.0
1024 1048576.
2048 4194304.
4096 1.6777216E+07
8192 1.6777216E+07
16384 1.6777216E+07
32768 1.6777216E+07
65536 1.6777216E+07
131072 1.6777216E+07
0: ALLOCATE: 274877906944 bytes requested; not enough memory
It seems that the program does not crash until it exhausts all the 32GB memory and goes even beyond that (probably by using virtual memory).
Since the array is on the heap, I guess it does not behave very differently compared with allocatable arrays.
Let me repeat my question: What is the largest amount of memory an automatic array can take if it is saved on the heap? (Whether we should use automatic or allocatable arrays is a different question.)
Thanks.