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