Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ enable_language(Fortran)
option(BUILD_MPI "Build MPI version of MPI" ON)
option(FG "Build the Fine-Grained ModEM Version - (Only compatiable with SP2)" OFF)
option(USE_C_TIMERS "Use the C timers in ModEM_timers" OFF)
option(MODEM_MEMORY "Compile the ModEM Memory utilitie and C memory routines" OFF)

set(FORWARD_FORMULATION "SP2" CACHE STRING "Set the forward formulation: < MF | SP | SP2 >")
set(MODEM_BUILD_DIMS "3D" CACHE STRING "Specify whether to build either the 2D or 3D versino of ModEM < 2D | 3D >")
Expand All @@ -31,6 +32,11 @@ if (USE_C_TIMERS)
enable_language(C)
endif()

if (MODEM_MEMORY)
enable_language(C)
add_compile_definitions(MODEM_MEMORY)
endif()

if (NOT BUILD_GPU IN_LIST SUPPORTED_GPU_OPTS)
message(FATAL_ERROR "-DBUILD_GPU option ('${BUILD_GPU}') was not valid - choose from: ${SUPPORTED_GPU_OPTS}")
endif()
Expand Down
7 changes: 7 additions & 0 deletions f90/UTILS/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,10 @@ if (USE_C_TIMERS)

add_compile_definitions(USE_C_TIMERS)
endif()

if (MODEM_MEMORY)
target_sources(${MODEM_EXE}
PRIVATE ModEM_memory.f90
PRIVATE ModEM_getrusage.c
)
endif()
38 changes: 38 additions & 0 deletions f90/UTILS/ModEM_getrusage.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#include <sys/resource.h>
#include <stdio.h>

/* It should be noted that the below function might have different
* results depending on the system you are on. POSIX doesn't guarantee
* ru_maxrss even be implemented.
*
* It's on most systems, but your results may very.
*/

/*
* To call this C function from Fortran, use this interface:
*
* interface
* subroutine get_maxrss() result(maxrss) bind(c)
* use iso_c_binding, only : c_long
* integer (c_long), intent(out) :: maxrss
* end subroutine get_maxrss
* end interface
*/
void get_maxrss(long *maxrss_bytes) {

int conversion;
struct rusage usage;

#if defined(__APPLE_) || defined(__MACH__)
// BSD's ru_maxrss (used by Apple) is in bytes
conversion = 1.0;
#elif __linux__
// Linux's ru_maxrss is in KiB
conversion = 1000.0;
#else
conversion = 1.0;
#endif
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need to double check this conversion is right...


getrusage(RUSAGE_SELF, &usage);
*maxrss_bytes = usage.ru_maxrss / conversion;
}
143 changes: 143 additions & 0 deletions f90/UTILS/ModEM_memory.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
! module ModEM_memory
!
! Use getrusage to track memory high-water mark.
!
! This module contains helpful routines to call and
! log the results of ru_maxrss by calling the
! getrusage system call.
!
! The public routines print ru_maxrss, which is
! a high-water mark of memory. More information on
! getrusage can be found by in `man 2 getrusage`.
!

module ModEM_memory

use utilities
use iso_c_binding, only : c_long
#ifdef MPI
use mpi
#endif
use ModEM_logger

implicit none

private

integer :: task_id

public ModEM_memory_print_report
public ModEM_memory_log_report
#ifdef MPI
public ModEM_memory_get_all
#endif

contains

subroutine ModEM_memory_create_log_fname()

end subroutine

subroutine ModEM_memory_get_maxrss(maxrss_bytes)

implicit none

integer, intent(out) :: maxrss_bytes
integer (c_long) :: maxrss_bytes_c

#ifdef MODEM_MEMORY
interface
subroutine get_maxrss(maxrss_bytes) bind(c)
use iso_c_binding, only : c_long
integer (c_long), intent(out) :: maxrss_bytes
end subroutine get_maxrss
end interface

call get_maxrss(maxrss_bytes_c)
maxrss_bytes = maxrss_bytes_c
#else
write(0,*) "ERROR: ModEM was not built with the ModEM_getrusage.c file!"
write(0,*) "ERROR: In order to use ModEM_memory routines you must"
write(0,*) "ERROR: build ModEM with CMake and specify '-DMODEM_MEMORY=on'"
call ModEM_abort()
#endif

end subroutine ModEM_memory_get_maxrss

subroutine ModEM_memory_print_report(message)

implicit none

integer :: maxrss
character (len=*), intent(in) :: message
real :: maxrss_bytes, maxrss_kb, maxrss_mb, maxrss_gb
character (len=*), parameter :: LOG_MSG_FMT = "(I4.4, A, A, A, F18.1, A, F18.1, A, F18.1, A)"
character (len=512) :: log_message

call ModEM_memory_get_maxrss(maxrss)
call ModEM_memory_convert_maxrss(maxrss, maxrss_kb, maxrss_mb, maxrss_gb)

write(log_message, LOG_MSG_FMT) task_id, ' - ', trim(message), ", ", maxrss_kb, ' kb ', maxrss_mb, ' mb ', maxrss_gb, ' gb'
write(6,*) trim(log_message)

end subroutine ModEM_memory_print_report

subroutine ModEM_memory_convert_maxrss(maxrss_bytes, maxrss_kb, maxrss_mb, maxrss_gb)

implicit none

integer :: maxrss_bytes
real, intent(out) :: maxrss_kb
real, intent(out) :: maxrss_mb
real, intent(out) :: maxrss_gb

maxrss_kb = maxrss_bytes / 1.0
maxrss_mb = maxrss_kb / 1000.0
maxrss_gb = maxrss_mb / 1000.1

end subroutine ModEM_memory_convert_maxrss

subroutine ModEM_memory_log_report(message)

implicit none

character (len=*), intent(in) :: message
character (len=*), parameter :: LOG_MSG_FMT = "(A, A, F18.1, A, F18.1, A, F18.1, A)"
integer :: maxrss
real :: maxrss_kb, maxrss_mb, maxrss_gb
character (len=512) :: log_message

call ModEM_memory_get_maxrss(maxrss)

call ModEM_memory_convert_maxrss(maxrss, maxrss_kb, maxrss_mb, maxrss_gb)
write(log_message, LOG_MSG_FMT) trim(message), ", ", maxrss_kb, ' kb ', maxrss_mb, ' mb ', maxrss_gb, ' gb'
call ModEM_log(log_message, mainOnly=.false., flush_log=.true.)

end subroutine ModEM_memory_log_report

#ifdef MPI
subroutine ModEM_memory_get_all(message)

implicit none

character (len=*), intent(in) :: message
character (len=*), parameter :: LOG_MSG_FMT = "(A, A, F18.1, A, F18.1, A, F18.1, A)"
character (len=512) :: log_message

integer :: maxrss, global_maxrss
real :: maxrss_kb, maxrss_mb, maxrss_gb

call ModEM_memory_get_maxrss(maxrss)

call MPI_reduce(maxrss, global_maxrss, 1, MPI_INTEGER, MPI_SUM, 0, MPI_COMM_WORLD, ierr)

if (taskid == 0) then
call ModEM_memory_convert_maxrss(global_maxrss, maxrss_kb, maxrss_mb, maxrss_gb)
write(log_message, LOG_MSG_FMT) trim(message), ", ", maxrss_kb, ' kb ', maxrss_mb, ' mb ', maxrss_gb, ' gb'
call ModEM_log(log_message, mainOnly=.false., flush_log=.true.)
end if

end subroutine ModEM_memory_get_all
#endif

end module ModEM_memory
Loading