From beb0ff98a73d1cb35b7b78865bf1c1da5c0c76c2 Mon Sep 17 00:00:00 2001 From: Daniel Schwen Date: Thu, 23 Feb 2017 12:09:47 -0700 Subject: [PATCH] Add memory usage diagnostic Postprocessor (#8619) --- .../include/postprocessors/MemoryUsage.h | 56 ++++++++ framework/src/base/Moose.C | 2 + framework/src/postprocessors/MemoryUsage.C | 123 ++++++++++++++++++ 3 files changed, 181 insertions(+) create mode 100644 framework/include/postprocessors/MemoryUsage.h create mode 100644 framework/src/postprocessors/MemoryUsage.C diff --git a/framework/include/postprocessors/MemoryUsage.h b/framework/include/postprocessors/MemoryUsage.h new file mode 100644 index 000000000000..25b0bfca3cc6 --- /dev/null +++ b/framework/include/postprocessors/MemoryUsage.h @@ -0,0 +1,56 @@ +/****************************************************************/ +/* DO NOT MODIFY THIS HEADER */ +/* MOOSE - Multiphysics Object Oriented Simulation Environment */ +/* */ +/* (c) 2010 Battelle Energy Alliance, LLC */ +/* ALL RIGHTS RESERVED */ +/* */ +/* Prepared by Battelle Energy Alliance, LLC */ +/* Under Contract No. DE-AC07-05ID14517 */ +/* With the U. S. Department of Energy */ +/* */ +/* See COPYRIGHT for full restrictions */ +/****************************************************************/ + +#ifndef MEMORYUSAGE_H +#define MEMORYUSAGE_H + +#include "GeneralPostprocessor.h" + +class MemoryUsage; + +template<> +InputParameters validParams(); + +/** + * Output maximum, average, or total process memory usage + */ +class MemoryUsage : public GeneralPostprocessor +{ +public: + MemoryUsage(const InputParameters & parameters); + + virtual void initialize() override; + virtual void execute() override; + virtual void finalize() override; + virtual PostprocessorValue getValue() override; + +protected: + enum class MemType { + virtual_memory, + physical_memory, + page_faults + } _mem_type; + + enum class ValueType { + total, + average, + max_process, + min_process + } _value_type; + + /// memory usage metric in bytes + Real _value; +}; + +#endif // MEMORYUSAGE_H diff --git a/framework/src/base/Moose.C b/framework/src/base/Moose.C index 2dcbcb7fa642..0100b073e657 100644 --- a/framework/src/base/Moose.C +++ b/framework/src/base/Moose.C @@ -192,6 +192,7 @@ #include "TimestepSize.h" #include "RunTime.h" #include "PerformanceData.h" +#include "MemoryUsage.h" #include "NumElems.h" #include "NumNodes.h" #include "NumNonlinearIterations.h" @@ -627,6 +628,7 @@ registerObjects(Factory & factory) registerPostprocessor(TimestepSize); registerPostprocessor(RunTime); registerPostprocessor(PerformanceData); + registerPostprocessor(MemoryUsage); registerPostprocessor(NumElems); registerPostprocessor(NumNodes); registerPostprocessor(NumNonlinearIterations); diff --git a/framework/src/postprocessors/MemoryUsage.C b/framework/src/postprocessors/MemoryUsage.C new file mode 100644 index 000000000000..cc9f794f7edd --- /dev/null +++ b/framework/src/postprocessors/MemoryUsage.C @@ -0,0 +1,123 @@ +/****************************************************************/ +/* DO NOT MODIFY THIS HEADER */ +/* MOOSE - Multiphysics Object Oriented Simulation Environment */ +/* */ +/* (c) 2010 Battelle Energy Alliance, LLC */ +/* ALL RIGHTS RESERVED */ +/* */ +/* Prepared by Battelle Energy Alliance, LLC */ +/* Under Contract No. DE-AC07-05ID14517 */ +/* With the U. S. Department of Energy */ +/* */ +/* See COPYRIGHT for full restrictions */ +/****************************************************************/ + +#include "MemoryUsage.h" + +#include +#include + +#if defined(__unix__) || defined(__unix) || defined(unix) || (defined(__APPLE__) && defined(__MACH__)) +#include +#define RUSAGE_AVAILABLE +#endif + +template<> +InputParameters validParams() +{ + InputParameters params = validParams(); + MooseEnum mem_type("virtual_memory physical_memory page_faults", "virtual_memory"); + params.addParam("mem_type", mem_type, "Memory metric to report."); + MooseEnum value_type("total average max_process min_processs", "total"); + params.addParam("value_type", value_type, "Aggregation method to apply to the requested memory metric."); + return params; +} + +MemoryUsage::MemoryUsage(const InputParameters & parameters) : + GeneralPostprocessor(parameters), + _mem_type(getParam("mem_type").getEnum()), + _value_type(getParam("value_type").getEnum()) +{ +} + +void +MemoryUsage::initialize() +{ + _value = 0.0; +} + +void +MemoryUsage::execute() +{ + // inspect /proc + std::ifstream stat_stream("/proc/self/stat", std::ios_base::in); + std::array val; + if (stat_stream) + { + std::string pid, comm, state; + stat_stream >> pid >> comm >> state; + for (unsigned int i = 0; i < 21; ++i) + stat_stream >> val[i]; + } + else + { + val.fill(0); + + // obtain rusage data for limited functionality on mac OS + #ifdef RUSAGE_AVAILABLE + struct rusage rusage; + getrusage( RUSAGE_SELF, &rusage ); + val[8] = rusage.ru_maxrss * 1024; + val[20] = rusage.ru_majflt * 1024; + #endif + } + + // get the requested per core metric + switch (_mem_type) + { + case MemType::virtual_memory: + _value = val[19]; + break; + + case MemType::physical_memory: + _value = val[20] * sysconf(_SC_PAGE_SIZE); + break; + + case MemType::page_faults: + _value = val[8]; + break; + } +} + +void +MemoryUsage::finalize() +{ + // perform the requested reduction + switch (_value_type) + { + case ValueType::total: + gatherSum(_value); + break; + + case ValueType::average: + gatherSum(_value); + _value /= n_processors(); + break; + + case ValueType::max_process: + gatherMax(_value); + break; + + case ValueType::min_process: + gatherMin(_value); + break; + } +} + +PostprocessorValue +MemoryUsage::getValue() +{ + return _value; +} + +#undef RUSAGE_AVAILABLE