- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I think that maximum memory is limited by the OS and not by the compiler.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page