Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Track memory usage in Fortran 90

Tags:

memory

fortran

I am trying to track the memory usage and cpu time of a subroutine in a Fortran 90 program. To track the track the cpu time, I use the following:

call cpu_time(tic) call subroutine(args) call cpu_time(toc) time = toc-tic

Is there a way to do something similar to record memory usage? What is the best way to do this? Thanks in advance for the help.

like image 872
Eleutharios Avatar asked Feb 25 '14 23:02

Eleutharios


2 Answers

liskawc has a very nice solution and I've been looking for something like this for a while.

He asked for feedback, and there were a couple of areas that could be improved.

  • there are several system calls that can be eliminated by just reading the system file directly from your Fortran program
  • the solution depends on a temporary file in the users directory
  • my fortran compiler didn't like opening a file starting with the tilde

I've modified his original program to overcome these issues:

subroutine system_mem_usage(valueRSS)
implicit none
use ifport !if on intel compiler
integer, intent(out) :: valueRSS

character(len=200):: filename=' '
character(len=80) :: line
character(len=8)  :: pid_char=' '
integer :: pid
logical :: ifxst

valueRSS=-1    ! return negative number if not found

!--- get process ID

pid=getpid()
write(pid_char,'(I8)') pid
filename='/proc/'//trim(adjustl(pid_char))//'/status'

!--- read system file

inquire (file=filename,exist=ifxst)
if (.not.ifxst) then
  write (*,*) 'system file does not exist'
  return
endif

open(unit=100, file=filename, action='read')
do
  read (100,'(a)',end=120) line
  if (line(1:6).eq.'VmRSS:') then
     read (line(7:),*) valueRSS
     exit
  endif
enddo
120 continue
close(100)

return
end subroutine system_mem_usage

Please feel free to update if you can improve this program any further!

like image 153
NuclearFission Avatar answered Oct 13 '22 13:10

NuclearFission


By memory usage i will assume you want RSS at a given moment in your program on a linux machine. If you dont want to use a profiler, then this routine might help a bit:

I use this routine (which actually quite ugly to be honest) but worked so far. Brief description of subroutine:

when you call the subroutine it issues a series of system calls, that search within the /proc/ filesystem information about your program. whatever is in there you can get, if you modify this sub, i use this one specifically to get RSS value for example. The routine returns valueRSS as a character, which you can then write to a specific file if you wish to have a profile of how ram usage is within your program. You could also convert the string to a number, but i leave that to you if you need it.

subroutine system_mem_usage(valueRSS)
 use ifport !if on intel compiler
 character(len=30) :: count_char,pid_char, dummy
 character(len=200) :: filename
 character(len=200) :: command
 integer :: count,pid,res
 character(len=50), intent(out) :: valueRSS

 call system_clock(count)

 pid=getpid()

 write(count_char,'(I10)') count
 write(pid_char,'(I10)') pid

 filename='~/tmp/mem_use.'//trim(count_char)

 command='cat /proc/'//trim(adjustl(pid_char))//'/status >'//trim(adjustl(filename))

 res=system(command)

 command='cat '//trim(adjustl(filename))//' | grep RSS > ~/tmp/rss_use.'//trim(count_char)

 res=system(command)

 open(unit=100, file='~/tmp/rss_use.'//trim(count_char))
 read(100,*) dummy, valueRSS
 close(100)

 return
end subroutine

if you are interested in some other value than RSS, then just edit the part at "grep RSS". This subroutine also assumes you have a tmp directory within your home.

Oh yea, feel free to modify the script as you wish and if anyone has any ideas on how to do this more elegantly i would much appreciate it.

like image 29
liskawc Avatar answered Oct 13 '22 13:10

liskawc