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 14449 : VectorMemoryUsage::validParams() 20 : { 21 14449 : InputParameters params = GeneralVectorPostprocessor::validParams(); 22 14449 : params.addClassDescription("Get memory stats for all ranks in the simulation"); 23 43347 : params.addParam<bool>("report_peak_value", 24 28898 : true, 25 : "If the vectorpostprocessor is executed more than once " 26 : "during a time step, report the aggregated peak " 27 : "value."); 28 43347 : params.addParam<MooseEnum>("mem_units", 29 28898 : MemoryUtils::getMemUnitsEnum(), 30 : "The unit prefix used to report memory usage, default: Mebibytes"); 31 14449 : return params; 32 0 : } 33 : 34 92 : VectorMemoryUsage::VectorMemoryUsage(const InputParameters & parameters) 35 : : GeneralVectorPostprocessor(parameters), 36 : MemoryUsageReporter(this), 37 92 : _mem_units(getParam<MooseEnum>("mem_units").getEnum<MemoryUtils::MemUnits>()), 38 92 : _col_hardware_id(declareVector("hardware_id")), 39 92 : _col_total_ram(declareVector("total_ram")), 40 92 : _col_physical_mem(declareVector("physical_mem")), 41 92 : _col_virtual_mem(declareVector("virtual_mem")), 42 92 : _col_page_faults(declareVector("page_faults")), 43 92 : _col_node_utilization(declareVector("node_utilization")), 44 92 : _report_peak_value(getParam<bool>("report_peak_value")), 45 92 : _peak_physical_mem(0.0), 46 92 : _peak_virtual_mem(0.0) 47 : { 48 92 : _col_hardware_id.resize(_nrank); 49 92 : _col_total_ram.resize(_nrank); 50 92 : _col_physical_mem.resize(_nrank); 51 92 : _col_virtual_mem.resize(_nrank); 52 92 : _col_page_faults.resize(_nrank); 53 92 : _col_node_utilization.resize(_nrank); 54 : 55 92 : if (_my_rank == 0) 56 : { 57 65 : std::copy(_hardware_id.begin(), _hardware_id.end(), _col_hardware_id.begin()); 58 157 : for (std::size_t i = 0; i < _nrank; ++i) 59 92 : _col_total_ram[i] = 60 92 : MemoryUtils::convertBytes(_hardware_memory_total[_hardware_id[i]], _mem_units); 61 : } 62 92 : } 63 : 64 : void 65 122 : VectorMemoryUsage::timestepSetup() 66 : { 67 122 : _peak_physical_mem = 0.0; 68 122 : _peak_virtual_mem = 0.0; 69 122 : } 70 : 71 : void 72 166 : VectorMemoryUsage::execute() 73 : { 74 : // skip during checking uo/aux state so that this postprocessor returns the memory 75 : // usage during the regular execution 76 166 : if (_fe_problem.checkingUOAuxState()) 77 33 : return; 78 : 79 : MemoryUtils::Stats stats; 80 133 : MemoryUtils::getMemoryStats(stats); 81 : 82 133 : if (_report_peak_value) 83 : { 84 133 : _peak_physical_mem = std::max(_peak_physical_mem, static_cast<Real>(stats._physical_memory)); 85 133 : _peak_virtual_mem = std::max(_peak_virtual_mem, static_cast<Real>(stats._virtual_memory)); 86 : } 87 : 88 133 : _col_physical_mem[_my_rank] = _report_peak_value ? _peak_physical_mem : stats._physical_memory; 89 133 : _col_virtual_mem[_my_rank] = _report_peak_value ? _peak_virtual_mem : stats._virtual_memory; 90 133 : _col_page_faults[_my_rank] = stats._page_faults; 91 : } 92 : 93 : void 94 166 : VectorMemoryUsage::finalize() 95 : { 96 : // skip during checking uo/aux state so that this postprocessor returns the memory 97 : // usage during the regular execution 98 166 : if (_fe_problem.checkingUOAuxState()) 99 33 : return; 100 : 101 : // send data to rank zero (avoid buffer aliasing error using out-of-vector copies) 102 133 : auto local_physical_mem = _col_physical_mem[_my_rank]; 103 133 : _communicator.gather(0, local_physical_mem, _col_physical_mem); 104 : 105 133 : auto local_virtual_mem = _col_virtual_mem[_my_rank]; 106 133 : _communicator.gather(0, local_virtual_mem, _col_virtual_mem); 107 : 108 : #ifndef __APPLE__ 109 133 : auto local_page_faults = _col_page_faults[_my_rank]; 110 133 : _communicator.gather(0, local_page_faults, _col_page_faults); 111 : #endif 112 : 113 : // prepare node utilization column 114 133 : if (_my_rank == 0) 115 : { 116 94 : std::vector<Real> physical_per_node(_hardware_memory_total.size()); 117 227 : for (std::size_t i = 0; i < _nrank; ++i) 118 133 : physical_per_node[_hardware_id[i]] += _col_physical_mem[i]; 119 : 120 227 : for (std::size_t i = 0; i < _nrank; ++i) 121 266 : _col_node_utilization[i] = physical_per_node[_hardware_id[i]] / 122 133 : static_cast<Real>(_hardware_memory_total[_hardware_id[i]]); 123 94 : } 124 : 125 : // unit prefix conversion 126 344 : for (std::size_t i = 0; i < _nrank; ++i) 127 : { 128 211 : _col_physical_mem[i] = MemoryUtils::convertBytes(_col_physical_mem[i], _mem_units); 129 211 : _col_virtual_mem[i] = MemoryUtils::convertBytes(_col_virtual_mem[i], _mem_units); 130 : } 131 : }