Commit ebd48e48 authored by Lorenz Huedepohl's avatar Lorenz Huedepohl
Browse files

Add funtionality to track the resident set size

parent 3d828456
......@@ -11,6 +11,7 @@ lib_LTLIBRARIES = libftimings-@FTIMINGS_API_VERSION@-@FC@.la
libftimings_@FTIMINGS_API_VERSION@_@FC@_la_SOURCES = \
ftimings/time.c \
ftimings/papi.c \
ftimings/resident_set_size.c \
ftimings/ftimings_type.F90 \
ftimings/ftimings_value.F90 \
ftimings/ftimings_node.F90 \
......
......@@ -305,7 +305,8 @@ module ftimings
character(len=name_length), parameter :: group = "Group"
character(len=12), parameter :: seconds = " [s]"
character(len=8), parameter :: fract = "fraction"
character(len=7), parameter :: flops = "Mflop/s"
character(len=8), parameter :: flops = " Mflop/s"
character(len=8), parameter :: ram = " RSS"
if (.not. self%active) then
return
......@@ -348,17 +349,14 @@ module ftimings
end if
! I really do hate it ..
write(format_spec,'("("" /= "",a",i0,",2x,a12,5x,a8)")') name_length
write(unit_act, format_spec,advance='no') adjustl(group), seconds, fract
write(format_spec,'("("" /= "",a",i0,",2x,a12,5x,a8,5x,a8)")') name_length
write(unit_act, format_spec,advance='no') adjustl(group), seconds, fract, ram
#ifdef HAVE_LIBPAPI
if (papi_supported) then
write(unit_act,'(5x,a7)') flops
else
write(unit_act,'(a)') ""
write(unit_act,'(5x,a8)',advance='no') flops
endif
#else
write(unit_act,'(a)') ""
#endif
write(unit_act,'(a)') ""
call node%print_graph(0, threshold, is_sorted, unit=unit_act)
end subroutine
......
module ftimings_type
use, intrinsic :: iso_c_binding, only : C_INT64_T, C_DOUBLE, C_LONG_LONG
use, intrinsic :: iso_c_binding, only : C_INT64_T, C_DOUBLE, C_LONG_LONG, C_LONG, C_INT
implicit none
integer, parameter :: rk = C_DOUBLE
integer, parameter :: name_length = 40
......
......@@ -27,8 +27,17 @@ module ftimings_value
end interface
#endif
interface
function resident_set_size() result(rsssize) bind(C, name="ftimings_resident_set_size")
use, intrinsic :: iso_c_binding
implicit none
integer(kind=C_LONG) :: rsssize
end function
end interface
type value_t
integer(kind=C_INT64_T) :: micros = 0 ! Cumulative microseconds spent in this node
integer(kind=C_LONG) :: rsssize = 0
#ifdef HAVE_LIBPAPI
integer(kind=C_LONG_LONG) :: flop_count = 0 ! Cumulative floating point operations done in this node
#endif
......@@ -46,7 +55,7 @@ module ftimings_value
end interface
type(value_t), parameter :: null_value = value_t( &
micros = 0 &
micros = 0, rsssize = 0 &
#ifdef HAVE_LIBPAPI
,flop_count = 0 &
#endif
......@@ -54,14 +63,17 @@ module ftimings_value
contains
! This is the function that actually returns the current timestamp and all other counters
function now() result(val)
use, intrinsic :: iso_c_binding
type(value_t) :: val
! current time
val%micros = microseconds_since_epoch()
! current memory
val%rsssize = resident_set_size()
#ifdef HAVE_LIBPAPI
if (papi_supported) then
! flop counter
......@@ -77,6 +89,7 @@ module ftimings_value
class(value_t), intent(in) :: a, b
type(value_t) :: c
c%micros = a%micros + b%micros
c%rsssize = a%rsssize + b%rsssize
#ifdef HAVE_LIBPAPI
c%flop_count = a%flop_count + b%flop_count
#endif
......@@ -86,6 +99,7 @@ module ftimings_value
class(value_t), intent(in) :: a, b
type(value_t) :: c
c%micros = a%micros - b%micros
c%rsssize = a%rsssize - b%rsssize
#ifdef HAVE_LIBPAPI
c%flop_count = a%flop_count - b%flop_count
#endif
......@@ -95,6 +109,7 @@ module ftimings_value
class(value_t), intent(in) :: a
type(value_t) :: neg_a
neg_a%micros = - a%micros
neg_a%rsssize = - a%rsssize
#ifdef HAVE_LIBPAPI
neg_a%flop_count = - a%flop_count
#endif
......@@ -108,33 +123,43 @@ module ftimings_value
character(len=64) :: format_spec
integer :: unit
write(format_spec,'("(",i0,"x,""|_ "",a",i0,",2x,f12.6,5x,f8.3)")') indent_level * 2 + 1, name_length
write(format_spec,'("(",i0,"x,""|_ "",a",i0,",2x,f12.6,5x,f8.3,5x,a8)")') indent_level * 2 + 1, name_length
write(unit,format_spec,advance='no') &
label, real(self%micros, kind=rk) * 1e-6_rk, real(self%micros, kind=rk) / real(total%micros, kind=rk)
label, &
real(self%micros, kind=rk) * 1e-6_rk, &
real(self%micros, kind=rk) / real(total%micros, kind=rk), &
nice_format(real(self%rsssize, kind=C_DOUBLE))
#ifdef HAVE_LIBPAPI
if (papi_supported) then
write(unit,'(5x,f7.2)') real(self%flop_count, kind=C_DOUBLE) / self%micros
else
write(unit,'(a)') ""
write(unit,'(5x,f8.2)',advance='no') real(self%flop_count, kind=C_DOUBLE) / self%micros
endif
#else
write(unit,'(a)') ""
#endif
write(unit,'(a)') ""
end subroutine
pure elemental function format_flops(flops) result(string)
pure elemental function nice_format(flops) result(string)
real(kind=C_DOUBLE), intent(in) :: flops
character(len=7) :: string
if (flops > 1e12) then
write(string,'(f5.1,'' T'')') flops / 1e12
else if (flops > 1e9) then
write(string,'(f5.1,'' G'')') flops / 1e9
else if (flops > 1e6) then
write(string,'(f5.1,'' M'')') flops / 1e6
else if (flops > 1e3) then
write(string,'(f5.1,'' K'')') flops / 1e3
character(len=8) :: string
real(kind=C_DOUBLE), parameter :: &
kibi = 2.0_C_DOUBLE**10, &
mebi = 2.0_C_DOUBLE**20, &
gibi = 2.0_C_DOUBLE**30, &
tebi = 2.0_C_DOUBLE**40, &
pebi = 2.0_C_DOUBLE**50
if (abs(flops) >= pebi) then
write(string,'(es8.1)') flops
else if (abs(flops) >= tebi) then
write(string,'(f5.1,'' Ti'')') flops / tebi
else if (abs(flops) >= gibi) then
write(string,'(f5.1,'' Gi'')') flops / gibi
else if (abs(flops) >= mebi) then
write(string,'(f5.1,'' Mi'')') flops / mebi
else if (abs(flops) >= kibi) then
write(string,'(f5.1,'' ki'')') flops / kibi
else
write(string,'(f7.1)') flops
write(string,'(f5.1,'' '')') flops
endif
end function
......
#include <stdio.h>
#include <unistd.h>
/*#include <sys/time.h>
#include <sys/resource.h>*/
long ftimings_resident_set_size() {
/* struct rusage usage;
if (getrusage(RUSAGE_SELF, &usage) != 0) {
perror("getrusage");
exit(1);
}
return usage.ru_maxrss;
*/
long rss = 0L;
FILE* fp = NULL;
if ((fp = fopen( "/proc/self/statm", "r" )) == NULL ) {
return 0L;
}
if (fscanf(fp, "%*s%ld", &rss) != 1) {
fclose(fp);
return (size_t)0L; /* Can't read? */
}
fclose(fp);
return rss * sysconf( _SC_PAGESIZE);
}
......@@ -27,7 +27,7 @@ program test_timings
endif
write(*,*) "Iteration", i
call timer%start("cycle", replace=.true.)
call timer%start("cycle") ! replace=.true.)
!$ call timer%start("parallel")
!$omp parallel do
do j = 1,30
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment