Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
Announcements
FPGA community forums and blogs on community.intel.com are migrating to the new Altera Community and are read-only. For urgent support needs during this transition, please visit the FPGA Design Resources page or contact an Altera Authorized Distributor.

available memory with ALLOCATE

gregfi04
Beginner
1,418 Views
Hi,

I'm trying to write some code to determine how much memory is available on the machine, such that processing doesn't start when there's not enough memory to finish the problem. My understanding is that there is no native Fortran command to determine this, correct?

I've hacked together the following, which progressively allocates more and more memory, until it finds the limit:

program mem_test
implicit none

real, dimension(:,:,:), allocatable :: MX
integer :: err_alloc,ng
NG = 1700

DO WHILE (.NOT.ALLOCATED(MX))
IF (.NOT.ALLOCATED(MX)) ALLOCATE (MX(1:NG,1:NG,1:NG), STAT = ERR_ALLOC)
IF (ERR_ALLOC == 0) THEN
NG = NG + 5
DEALLOCATE(MX)
ELSE IF(ERR_ALLOC /= 0) THEN
WRITE (*,*) "STOPPING AT NG=",NG, " WITH ERROR=",ERR_ALLOC
EXIT
ENDIF
END DO

WRITE (*,*) 'ALLOCATED ', 4.0 * (NG**3) / 1000000.0, ' MEGABYTES.'
end program


I'm running this on a quad-core Xeon workstation with 16 GB of memory. See below:

849 fischega@lxlog01[~/testdir/memtest]> free -m
total used free shared buffers cached
Mem: 16054 3852 12201 0 116 3158
-/+ buffers/cache: 578 15476
Swap: 8236 0 8236
850 fischega@lxlog01[~/testdir/memtest]> uname -a
Linux lxlog01 2.6.16.60-0.21-smp #1 SMP Tue May 6 12:41:02 UTC 2008 x86_64 x86_64 x86_64 GNU/Linux

I seem to be hitting a limit around 7 GB, whereas "free" claims there is 12 GB available. What gives? Is my math wrong? 4 bytes for a vanilla REAL, right?

Thanks,
Greg
0 Kudos
7 Replies
Tabrez_Ali
Beginner
1,418 Views
The math seems right.

I think that maximum memory is limited by the OS and not by the compiler.
0 Kudos
Steven_L_Intel1
Employee
1,418 Views
Note that you are fragmenting memory with this scheme. You might try allocating 16GB first and then working your way down until it succeeds.
0 Kudos
gregfi04
Beginner
1,418 Views
I still seem to end up with roughly the same answer. ~7GB instead of ~12 GB. I suppose this is more of a Linux memory management question, eh?
0 Kudos
gregfi04
Beginner
1,418 Views
What kernel-level call is the code making when it allocates memory? I'd like to pose this question to the linux-mm.org folks.

Thanks.
0 Kudos
Steven_L_Intel1
Employee
1,418 Views
malloc

You may want to see if strace provides any useful information. You can also try it with malloc and free in place of ALLOCATE (remembering to get the number of bytes right.)
0 Kudos
jimdempseyatthecove
Honored Contributor III
1,418 Views

Greg,

I am not a Linux programmer so my comment may be for naught.

The 7GB appears to be approximately 1/2 the available memory.

Linux is structured to grow the application stack down from the negative address space (-8, -16, ...) or(-4, -8, ...) depending on x64 or x32.

My guess is without specifying how large of stack space to reserve Linux may assume 50/50 for stack and allocatables.

Try specifying a 1GB stack limit and see if you go above the 7GB. (You will have to read the docs as to how to go about specifying stack limit.)

Jim Dempsey

0 Kudos
Martyn_C_Intel
Employee
1,418 Views

I tried the following variant on a Linux (SLES10) system with 16 GB of physical memory and approximately 8GB of swap space. This seemed to successfully allocate all the memory available, and not more. The stack is not involved here. Note that you need -i8 or a source code change in orderto computeNG**3, else you may get an integeroverflow close to 8 GB (4.0 * 1250**3). You need to access the array after allocating it - you can allocate as much memory as you like, if it is never used.

program mem_test
implicit none

real, dimension(:,:,:), allocatable :: MX
integer :: ng, err_alloc, i
NG = NG3

ALLOCATE (MX(1:NG,1:NG,1:NG), STAT = ERR_ALLOC)

DO I=1,NG,NG/10
WRITE(*,*) MX(I,I,I)
ENDDO

WRITE (*,*)
WRITE (*,*) 'ALLOCATED ', 4.0 * (NG**3) / 1000000.0, ' MEGABYTES.'
end program


ifort -fpp -i8 alloc2.f90 -DNG3=1800;./a.out

.....

ALLOCATED 23328.00 MEGABYTES.

ifort -fpp -i8 alloc2.f90 -DNG3=1850;./a.out

forrtl: severe (174): SIGSEGV, segmentation fault occurred

____________________________________________

In addition, you could call the library function SYSTEM (or SYSTEMQQ) to execute the shell command free -m:

use ifport

IERR=SYSTEM("free -m")

and either parse and redirect the output to a file,so that you can read it back, ortry something more clever. You could even use SYSTEM to run repeatedly a test program like the one above, gradually increasing the memory allocation until it failed, and SYSTEM returns a non-zero error code.

You can find a description of SYSTEM and SYSTEMQQ in the main Fortran compiler documentation.

0 Kudos
Reply