Shamrock 2025.10.0
Astrophysical Code
Loading...
Searching...
No Matches
stacktrace.cpp
Go to the documentation of this file.
1// -------------------------------------------------------//
2//
3// SHAMROCK code for hydrodynamics
4// Copyright (c) 2021-2026 Timothée David--Cléris <tim.shamrock@proton.me>
5// SPDX-License-Identifier: CeCILL Free Software License Agreement v2.1
6// Shamrock is licensed under the CeCILL 2.1 License, see LICENSE for more information
7//
8// -------------------------------------------------------//
9
18#include "shambase/time.hpp"
19#include <sstream>
20#include <string>
21#include <vector>
22
23namespace shambase::details {
24
27 std::string name;
29 bool is_start;
30
36 std::string format(u32 world_rank);
37 };
38
39 std::string ChromeProfileEntry::format(u32 world_rank) {
40 if (is_start) {
42 R"({
43 "cat": "%s",
44 "pid": %d,
45 "tid": %d,
46 "ts": %zu,
47 "ph": "B",
48 "name": "%s",
49 "args": {
50 }
51 })",
52 name.c_str(),
53 world_rank,
54 world_rank,
56 name.c_str());
57
58 } else {
60 R"({
61 "cat": "%s",
62 "pid": %d,
63 "tid": %d,
64 "ts": %zu,
65 "ph": "E",
66 "name": "%s",
67 "args": {
68 }
69 })",
70 name.c_str(),
71 world_rank,
72 world_rank,
74 name.c_str());
75 }
76 }
77
79 std::vector<ChromeProfileEntry> profile_data_chrome;
80
88 inline void add_entry_chrome(std::source_location loc, f64 time, bool is_start) {
89 // Convert time to microseconds
90 auto to_prof_time = [](f64 in) {
91 return static_cast<u64>(in * 1e6);
92 };
93 // Add the entry to the storage
94 profile_data_chrome.push_back(
95 ChromeProfileEntry{loc.function_name(), to_prof_time(time), is_start});
96 }
97
101 inline void clear_chrome_entry() { profile_data_chrome.clear(); }
102
103 void dump_profilings_chrome(const std::string &process_prefix, u32 world_rank) {
104
105 // Open the file for writing
106 std::ofstream outfile(process_prefix + std::to_string(world_rank));
107 // Write the start of the JSON array
108 outfile << "[";
109
110 // Write each entry
111 u32 len = profile_data_chrome.size();
112
113 for (u32 i = 0; i < len; i++) {
114 // Write the entry in the JSON format
115 outfile << profile_data_chrome[i].format(world_rank);
116 // Add a comma if it's not the last entry
117 if (i != len - 1) {
118 outfile << ",";
119 }
120 }
121
122 // Write the end of the JSON array
123 outfile << "]";
124 // Close the file
125 outfile.close();
126 }
127
128} // namespace shambase::details
129
130namespace shambase::details {
131
133 auto make_timer = []() -> Timer {
134 Timer tmp;
135 tmp.start();
136 return tmp;
137 };
138
141
142 // two entry types,
143 // one with start, end
144 // one with start, end as separate envents
145
156 std::string entry_name;
157
163 std::string format() {
165 R"({"tstart": %f, "tend": %f, "name": "%s"})", time_start, time_end, entry_name);
166 }
167 };
168
172 std::vector<ProfileEntry> profile_data;
173
181 return global_timer.elasped_sec();
182 }
183
187
189 // Add the profile entry to the storage
190 profile_data.push_back({start_time, end_time, loc.function_name()});
191 // Add a Chrome profiling entry to the storage
192 add_entry_chrome(loc, end_time, false);
193 };
194
196 profile_data.clear();
198 }
199
200 void dump_profilings(const std::string &process_prefix, u32 world_rank) {
201 std::ofstream outfile(process_prefix + std::to_string(world_rank));
202 outfile << "[";
203
204 u32 len = profile_data.size();
205
206 for (u32 i = 0; i < len; i++) {
207 outfile << profile_data[i].format();
208 if (i != len - 1) {
209 outfile << ",";
210 }
211 }
212
213 outfile << "]";
214 outfile.close();
215 }
216
217} // namespace shambase::details
218
219namespace shambase {
220
221 std::string _callstack_process_identifier;
222
223 void set_callstack_process_identifier(std::string identifier) {
224 _callstack_process_identifier = std::move(identifier);
225 }
226
227 std::vector<std::function<std::string()>> _callstack_gen_info_generators;
228
229 void add_callstack_gen_info_generator(std::string (*generator)()) {
230 _callstack_gen_info_generators.push_back(std::move(generator));
231 }
232
238 std::string fmt_callstack() {
239 std::stack<SourceLocation> cpy = details::call_stack;
240
241 std::vector<std::string> lines;
242
243 while (!cpy.empty()) {
244 SourceLocation l = cpy.top();
245 lines.push_back(l.format_one_line_func());
246 cpy.pop();
247 }
248
249 std::reverse(lines.begin(), lines.end());
250
251 std::stringstream ss;
252
253 if (!_callstack_process_identifier.empty()) {
254 ss << " -> process identifier: " << _callstack_process_identifier << "\n";
255 }
256
257 for (u32 i = 0; i < lines.size(); i++) {
258 ss << shambase::format(" {:2} : {}\n", i, lines[i]);
259 }
260
261 for (auto &generator : _callstack_gen_info_generators) {
262 ss << generator() << "\n";
263 }
264
265 return ss.str();
266 }
267
268} // namespace shambase
double f64
Alias for double.
std::uint32_t u32
32 bit unsigned integer
std::uint64_t u64
64 bit unsigned integer
Class Timer measures the time elapsed since the timer was started.
Definition time.hpp:96
void end()
Stops the timer and stores the elapsed time in nanoseconds.
Definition time.hpp:111
f64 elasped_sec() const
Converts the stored nanosecond time to a floating point representation in seconds.
Definition time.hpp:123
void start()
Starts the timer.
Definition time.hpp:106
namespace for basic c++ utilities
std::string fmt_callstack()
Get the formatted callstack.
void throw_with_loc(std::string message, SourceLocation loc=SourceLocation{})
Throw an exception and append the source location to it.
void add_entry_chrome(std::source_location loc, f64 time, bool is_start)
Add a Chrome tracing entry to the storage.
auto make_timer
Utility to create a timer and start it.
Timer global_timer
Wall time global timer.
void clear_chrome_entry()
Clear the Chrome tracing entries storage.
std::vector< ChromeProfileEntry > profile_data_chrome
Chrome tracing entries storage.
std::vector< ProfileEntry > profile_data
Vector to hold profiling entries.
This file contains the definition for the stacktrace related functionality.
void register_profile_entry(std::source_location loc, f64 start_time, f64 end_time)
Register a profile entry. This register the end of a profile entry for chrome tracing and a complete ...
void dump_profilings(const std::string &process_prefix, u32 world_rank)
Dump the profiling data in a JSON format to a file.
void dump_profilings_chrome(const std::string &process_prefix, u32 world_rank)
Dump the profiling data in a Chrome Tracing format.
void register_profile_entry_start(std::source_location loc, f64 start_time)
Register the start of a profile entry. This is required for chrome profiling as there is a separate e...
f64 get_wtime()
Returns the current wall clock time in seconds.
void clear_profiling_data()
Clear the profiling data. (should be done in large run to avoid out-of-memory)
provide information about the source location
Chrome tracing profile entry.
u64 time_val
Time value for the profile entry.
std::string name
Name of the profile entry.
bool is_start
Flag indicating if it is the start of the profile entry.
std::string format(u32 world_rank)
Format the Chrome profile entry.
Structure to hold data for a profiling entry.
f64 time_start
Start time of the profiling entry (in sec since program start)
std::string entry_name
Name of the profiling entry.
std::string format()
Format the profile entry as a JSON string.
f64 time_end
End time of the profiling entry (in sec since program start)
Utility class to emulates std::source_location class introduced in c++20 This class provides informat...
constexpr const char * function_name() const noexcept
Returns the function name of the source location.