chombo-discharge
Loading...
Searching...
No Matches
Functions
MemoryReport Namespace Reference

Namespace containing utility functions for reporting memory usage in various formats. More...

Functions

void getMaxMinMemoryUsage ()
 Print the global maximum and minimum memory usage. This includes peak memory and unfreed memory.
 
void getMaxMinMemoryUsage (Real &a_maxPeak, Real &a_minPeak, Real &a_maxUnfreed, Real &a_minUnfreed)
 Print the global maximum and minimum memory usage. This includes peak memory and unfreed memory.
 
void getMemoryUsage (Vector< Real > &a_peak, Vector< Real > &a_unfreed)
 Get peak and unfreed memory usage per rank.
 
void getResidentSetSize (Real &a_currentRSS, Real &a_peakRSS)
 Get the calling process' current and peak resident set size.
 
void getMaxMinResidentSetSize (Real &a_maxCurrent, Real &a_minCurrent, Real &a_maxPeak, Real &a_minPeak)
 Get the global maximum and minimum resident set size over all ranks.
 
std::string bytesAsMB (const long long a_bytes)
 Format a byte count as megabytes for a report line.
 
std::string bytesAsMB (const Real a_bytes)
 Format a byte count as megabytes for a report line.
 
void printMemoryTable (std::ostream &a_out, const std::string &a_indent)
 Write the full memory report as a table.
 

Detailed Description

Namespace containing utility functions for reporting memory usage in various formats.

Function Documentation

◆ bytesAsMB() [1/2]

std::string MemoryReport::bytesAsMB ( const long long  a_bytes)

Format a byte count as megabytes for a report line.

Fixed to three decimals, i.e. a resolution of about a kilobyte. Megabytes are what a reader wants for a figure in the gigabyte range, but rounding to whole megabytes destroys the signal these reports exist to carry: a ratchet of tens of kilobytes per step reads as an unchanging integer, and a counter that is quietly climbing looks flat. Formatted into its own stream so the caller's formatting flags are left alone.

Parameters
[in]a_bytesByte count.
Returns
The value in MB, as a fixed-point string with three decimals.

◆ bytesAsMB() [2/2]

std::string MemoryReport::bytesAsMB ( const Real  a_bytes)

Format a byte count as megabytes for a report line.

Overload for the byte counts this namespace reports as Real. See bytesAsMB(long long).

Parameters
[in]a_bytesByte count.
Returns
The value in MB, as a fixed-point string with three decimals.

◆ getMaxMinMemoryUsage()

void MemoryReport::getMaxMinMemoryUsage ( Real &  a_maxPeak,
Real &  a_minPeak,
Real &  a_maxUnfreed,
Real &  a_minUnfreed 
)

Print the global maximum and minimum memory usage. This includes peak memory and unfreed memory.

Parameters
[out]a_maxPeakMaximum peak memory (maximized over ranks)
[out]a_minPeakMinimum peak memory (minimuzed over ranks)
[out]a_maxUnfreedMaximum unfreed memory (maximized over ranks)
[out]a_minUnfreedMinimum unfreed memory (minimized over ranks)

◆ getMaxMinResidentSetSize()

void MemoryReport::getMaxMinResidentSetSize ( Real &  a_maxCurrent,
Real &  a_minCurrent,
Real &  a_maxPeak,
Real &  a_minPeak 
)

Get the global maximum and minimum resident set size over all ranks.

See getResidentSetSize(). The maximum is what decides an out-of-memory failure, because the job dies when the worst rank exceeds its limit and not when the average does.

Parameters
[out]a_maxCurrentMaximum current RSS, in bytes (maximized over ranks).
[out]a_minCurrentMinimum current RSS, in bytes (minimized over ranks).
[out]a_maxPeakMaximum peak RSS, in bytes (maximized over ranks).
[out]a_minPeakMinimum peak RSS, in bytes (minimized over ranks).

◆ getMemoryUsage()

void MemoryReport::getMemoryUsage ( Vector< Real > &  a_peak,
Vector< Real > &  a_unfreed 
)

Get peak and unfreed memory usage per rank.

If using MPI, this will do an Allgather so that every rank can see usage.

Parameters
[out]a_peakPeak memory usage
[in]a_unfreedUnfreed memory usage

◆ getResidentSetSize()

void MemoryReport::getResidentSetSize ( Real &  a_currentRSS,
Real &  a_peakRSS 
)

Get the calling process' current and peak resident set size.

This is the memory the operating system has actually given the process, read from /proc/self/status (VmRSS and VmHWM). Unlike every other figure in this namespace it counts the whole process – mesh arenas, particle arenas, every std::vector buffer, MPI internals and the binary itself – so it is the quantity a job is killed for exceeding, and the only one that can tell real growth from a miscounting allocator. When a tracked figure climbs and this does not, the growth is in the counter rather than in the process.

Both outputs are zero on platforms without /proc, so a zero reading means "unavailable" rather than "no memory in use".

Parameters
[out]a_currentRSSCurrent resident set size (VmRSS), in bytes.
[out]a_peakRSSPeak resident set size (VmHWM), in bytes.

◆ printMemoryTable()

void MemoryReport::printMemoryTable ( std::ostream &  a_out,
const std::string &  a_indent 
)

Write the full memory report as a table.

Three sources that do not overlap, gathered here so that they cannot drift apart: the resident set is the whole process, Chombo's counter sees only its own Arena (BaseFab-backed mesh data), and ParticleMemory sees only particle storage. Neither counter can adjudicate itself – a tracked figure that climbs while the resident set does not is a bug in the counter rather than memory the process is holding – which is why all three are printed together.

The table has two independent axes, and conflating them has cost real time. A "high-water" row is over time and never falls; the columns are over ranks at this instant. The figure a job is killed for exceeding is the high-water of the worst rank, i.e. the rightmost value of a high-water row. A dash marks a quantity that does not exist rather than one that is zero: there is no useful minimum over ranks of a high-water mark, because the ranks reach theirs at different moments.

Prints nothing unless Chombo was compiled with memory tracking. The arena figures are the reason the table exists, and a table reporting two of its three sources would invite exactly the confusion between counter and process that the third column is there to prevent. The guard lives here rather than at the call sites, so callers need no preprocessor conditionals of their own.

Collective: the rank columns are reductions, so every rank must call this.

Parameters
[in,out]a_outStream to print to.
[in]a_indentPrefix written before every line, so the table can sit inside any report.