OpenPFC  0.1.4
Phase Field Crystal simulation framework
Loading...
Searching...
No Matches
memory_reporter.hpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2025 VTT Technical Research Centre of Finland Ltd
2// SPDX-License-Identifier: AGPL-3.0-or-later
3
41#pragma once
42
45#include "openpfc/logging.hpp"
46#include "openpfc/mpi.hpp"
47#include "openpfc/utils.hpp"
48#include <cstddef>
49#include <fstream>
50#include <iomanip>
51#include <mpi.h>
52#include <sstream>
53#include <string>
54
55namespace pfc {
56namespace utils {
57
67 size_t m_fft_bytes = 0;
68
74};
75
88 std::ifstream meminfo("/proc/meminfo");
89 if (!meminfo) return 0;
90
91 std::string line;
92 while (std::getline(meminfo, line)) {
93 if (line.find("MemTotal:") == 0) {
94 // Format: "MemTotal: 16384000 kB"
95 std::istringstream iss(line);
96 std::string label;
97 size_t mem_kb;
98 iss >> label >> mem_kb;
99 return mem_kb * 1024; // Convert kB to bytes
100 }
101 }
102 return 0;
103}
104
111inline std::string format_bytes(size_t bytes) {
112 const double KB = 1024.0;
113 const double MB = KB * 1024.0;
114 const double GB = MB * 1024.0;
115 const double TB = GB * 1024.0;
116
117 std::ostringstream oss;
118 oss.precision(2);
119 oss << std::fixed;
120
121 if (bytes >= TB) {
122 oss << (bytes / TB) << " TB";
123 } else if (bytes >= GB) {
124 oss << (bytes / GB) << " GB";
125 } else if (bytes >= MB) {
126 oss << (bytes / MB) << " MB";
127 } else if (bytes >= KB) {
128 oss << (bytes / KB) << " KB";
129 } else {
130 oss << bytes << " B";
131 }
132 return oss.str();
133}
134
169template <typename WorldType>
170inline void report_memory_usage(const MemoryUsage &usage, const WorldType &world,
171 const Logger &logger,
172 MPI_Comm comm = MPI_COMM_WORLD) {
173 int rank = pfc::mpi::get_comm_rank(comm);
174 int num_ranks = pfc::mpi::get_comm_size(comm);
175
176 // Gather memory data to rank 0
177 size_t local_mem[3] = {usage.m_application_bytes, usage.m_fft_bytes,
178 usage.total_bytes()};
179 size_t global_mem[3] = {0, 0, 0};
180
181 MPI_Reduce(local_mem, global_mem, 3, MPI_UNSIGNED_LONG_LONG, MPI_SUM, 0, comm);
182
183 // Only rank 0 logs the report
184 if (rank == 0) {
185 log_info(logger, "");
186 log_info(logger, "=== Memory Usage Report ===");
187
188 // Per-rank memory
189 std::ostringstream rank_msg;
190 rank_msg << " Rank 0 - Application: " << format_bytes(usage.m_application_bytes)
191 << ", FFT: " << format_bytes(usage.m_fft_bytes)
192 << ", Total: " << format_bytes(usage.total_bytes());
193 log_info(logger, rank_msg.str());
194
195 // Global total
196 std::ostringstream global_msg;
197 global_msg << " Global Total: " << format_bytes(global_mem[2]) << " ("
198 << num_ranks << " ranks)";
199 log_info(logger, global_msg.str());
200
201 // Per-voxel memory
202 auto [Nx, Ny, Nz] = get_size(world);
203 size_t total_voxels = static_cast<size_t>(Nx) * Ny * Nz;
204 double mem_per_voxel = static_cast<double>(global_mem[2]) / total_voxels;
205
206 std::ostringstream voxel_msg;
207 voxel_msg << " Per Voxel: " << format_bytes(static_cast<size_t>(mem_per_voxel))
208 << "/voxel (" << total_voxels << " voxels)";
209 log_info(logger, voxel_msg.str());
210
211 // System memory (if available)
212 size_t system_mem = get_system_memory_bytes();
213 if (system_mem > 0) {
214 double usage_pct = (static_cast<double>(global_mem[2]) / system_mem) * 100.0;
215 std::ostringstream sys_msg;
216 sys_msg << " System Memory: " << format_bytes(system_mem)
217 << ", Usage: " << std::fixed << std::setprecision(1) << usage_pct
218 << "%";
219 log_info(logger, sys_msg.str());
220 }
221
222 log_info(logger, "===========================");
223 log_info(logger, "");
224 }
225}
226
227} // namespace utils
228} // namespace pfc
Minimal structured logging utilities for OpenPFC.
size_t get_system_memory_bytes() noexcept
Attempt to read total system memory from /proc/meminfo.
Definition memory_reporter.hpp:87
std::string format_bytes(size_t bytes)
Format bytes as human-readable string (KB, MB, GB, TB)
Definition memory_reporter.hpp:111
MPI utilities and wrappers.
Lightweight logger configuration.
Definition logging.hpp:29
Memory usage statistics for a single MPI rank.
Definition memory_reporter.hpp:65
size_t m_application_bytes
Memory allocated by user application (bytes)
Definition memory_reporter.hpp:66
size_t m_fft_bytes
Memory allocated by FFT library (bytes)
Definition memory_reporter.hpp:67
size_t total_bytes() const noexcept
Calculate total memory usage.
Definition memory_reporter.hpp:73
Represents the global simulation domain (the "world").
Definition world.hpp:91
General utility functions.
World class definition and unified interface.
World query and coordinate transformation functions.