LCOV - code coverage report
Current view: top level - src/vectorpostprocessors - VectorMemoryUsage.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 419b9d Lines: 65 66 98.5 %
Date: 2025-08-08 20:01:16 Functions: 5 5 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //* This file is part of the MOOSE framework
       2             : //* https://mooseframework.inl.gov
       3             : //*
       4             : //* All rights reserved, see COPYRIGHT for full restrictions
       5             : //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
       6             : //*
       7             : //* Licensed under LGPL 2.1, please see LICENSE for details
       8             : //* https://www.gnu.org/licenses/lgpl-2.1.html
       9             : 
      10             : #include "VectorMemoryUsage.h"
      11             : #include "MemoryUtils.h"
      12             : #include <algorithm>
      13             : 
      14             : #include "Conversion.h"
      15             : 
      16             : registerMooseObject("MooseApp", VectorMemoryUsage);
      17             : 
      18             : InputParameters
      19       14451 : VectorMemoryUsage::validParams()
      20             : {
      21       14451 :   InputParameters params = GeneralVectorPostprocessor::validParams();
      22       14451 :   params.addClassDescription("Get memory stats for all ranks in the simulation");
      23       43353 :   params.addParam<bool>("report_peak_value",
      24       28902 :                         true,
      25             :                         "If the vectorpostprocessor is executed more than once "
      26             :                         "during a time step, report the aggregated peak "
      27             :                         "value.");
      28       43353 :   params.addParam<MooseEnum>("mem_units",
      29       28902 :                              MemoryUtils::getMemUnitsEnum(),
      30             :                              "The unit prefix used to report memory usage, default: Mebibytes");
      31       14451 :   return params;
      32           0 : }
      33             : 
      34          93 : VectorMemoryUsage::VectorMemoryUsage(const InputParameters & parameters)
      35             :   : GeneralVectorPostprocessor(parameters),
      36             :     MemoryUsageReporter(this),
      37          93 :     _mem_units(getParam<MooseEnum>("mem_units").getEnum<MemoryUtils::MemUnits>()),
      38          93 :     _col_hardware_id(declareVector("hardware_id")),
      39          93 :     _col_total_ram(declareVector("total_ram")),
      40          93 :     _col_physical_mem(declareVector("physical_mem")),
      41          93 :     _col_virtual_mem(declareVector("virtual_mem")),
      42          93 :     _col_page_faults(declareVector("page_faults")),
      43          93 :     _col_node_utilization(declareVector("node_utilization")),
      44          93 :     _report_peak_value(getParam<bool>("report_peak_value")),
      45          93 :     _peak_physical_mem(0.0),
      46          93 :     _peak_virtual_mem(0.0)
      47             : {
      48          93 :   _col_hardware_id.resize(_nrank);
      49          93 :   _col_total_ram.resize(_nrank);
      50          93 :   _col_physical_mem.resize(_nrank);
      51          93 :   _col_virtual_mem.resize(_nrank);
      52          93 :   _col_page_faults.resize(_nrank);
      53          93 :   _col_node_utilization.resize(_nrank);
      54             : 
      55          93 :   if (_my_rank == 0)
      56             :   {
      57          66 :     std::copy(_hardware_id.begin(), _hardware_id.end(), _col_hardware_id.begin());
      58         159 :     for (std::size_t i = 0; i < _nrank; ++i)
      59          93 :       _col_total_ram[i] =
      60          93 :           MemoryUtils::convertBytes(_hardware_memory_total[_hardware_id[i]], _mem_units);
      61             :   }
      62          93 : }
      63             : 
      64             : void
      65         124 : VectorMemoryUsage::timestepSetup()
      66             : {
      67         124 :   _peak_physical_mem = 0.0;
      68         124 :   _peak_virtual_mem = 0.0;
      69         124 : }
      70             : 
      71             : void
      72         172 : VectorMemoryUsage::execute()
      73             : {
      74             :   // skip during checking uo/aux state so that this postprocessor returns the memory
      75             :   // usage during the regular execution
      76         172 :   if (_fe_problem.checkingUOAuxState())
      77          36 :     return;
      78             : 
      79             :   MemoryUtils::Stats stats;
      80         136 :   MemoryUtils::getMemoryStats(stats);
      81             : 
      82         136 :   if (_report_peak_value)
      83             :   {
      84         136 :     _peak_physical_mem = std::max(_peak_physical_mem, static_cast<Real>(stats._physical_memory));
      85         136 :     _peak_virtual_mem = std::max(_peak_virtual_mem, static_cast<Real>(stats._virtual_memory));
      86             :   }
      87             : 
      88         136 :   _col_physical_mem[_my_rank] = _report_peak_value ? _peak_physical_mem : stats._physical_memory;
      89         136 :   _col_virtual_mem[_my_rank] = _report_peak_value ? _peak_virtual_mem : stats._virtual_memory;
      90         136 :   _col_page_faults[_my_rank] = stats._page_faults;
      91             : }
      92             : 
      93             : void
      94         172 : VectorMemoryUsage::finalize()
      95             : {
      96             :   // skip during checking uo/aux state so that this postprocessor returns the memory
      97             :   // usage during the regular execution
      98         172 :   if (_fe_problem.checkingUOAuxState())
      99          36 :     return;
     100             : 
     101             :   // send data to rank zero (avoid buffer aliasing error using out-of-vector copies)
     102         136 :   auto local_physical_mem = _col_physical_mem[_my_rank];
     103         136 :   _communicator.gather(0, local_physical_mem, _col_physical_mem);
     104             : 
     105         136 :   auto local_virtual_mem = _col_virtual_mem[_my_rank];
     106         136 :   _communicator.gather(0, local_virtual_mem, _col_virtual_mem);
     107             : 
     108             : #ifndef __APPLE__
     109         136 :   auto local_page_faults = _col_page_faults[_my_rank];
     110         136 :   _communicator.gather(0, local_page_faults, _col_page_faults);
     111             : #endif
     112             : 
     113             :   // prepare node utilization column
     114         136 :   if (_my_rank == 0)
     115             :   {
     116          97 :     std::vector<Real> physical_per_node(_hardware_memory_total.size());
     117         233 :     for (std::size_t i = 0; i < _nrank; ++i)
     118         136 :       physical_per_node[_hardware_id[i]] += _col_physical_mem[i];
     119             : 
     120         233 :     for (std::size_t i = 0; i < _nrank; ++i)
     121         272 :       _col_node_utilization[i] = physical_per_node[_hardware_id[i]] /
     122         136 :                                  static_cast<Real>(_hardware_memory_total[_hardware_id[i]]);
     123          97 :   }
     124             : 
     125             :   // unit prefix conversion
     126         350 :   for (std::size_t i = 0; i < _nrank; ++i)
     127             :   {
     128         214 :     _col_physical_mem[i] = MemoryUtils::convertBytes(_col_physical_mem[i], _mem_units);
     129         214 :     _col_virtual_mem[i] = MemoryUtils::convertBytes(_col_virtual_mem[i], _mem_units);
     130             :   }
     131             : }

Generated by: LCOV version 1.14