MoCSI API Reference
Loading...
Searching...
No Matches
SnapshotLoader.h
Go to the documentation of this file.
1#include <algorithm>
2#include <cstdint>
3#include <exception>
4#include <memory>
5#include <valarray>
6#include <vector>
7
8#include "CsvParser.h"
10#include "GenericSubmodule.h"
11#include "IniParser.h"
13
14#ifdef MPI_PRESENT
15#include <mpi.h>
16
18#endif
19
25template <typename T>
27{
28 private:
29 std::unique_ptr<CsvParser> m_snapshot_field_data;
30 std::unique_ptr<IniParserSnapshot> m_snapshot_ini_data;
31 bool m_no_snapshot{false};
32 bool m_keep_sim_config{false};
33 bool m_keep_module_inis{false};
34#ifdef MPI_PRESENT
40 int count{0};
43 long data_sizes[2];
46 void _parseFooterString(const std::vector<unsigned char>& footer,
47 std::vector<std::string>& field_names, T& elapsed_time,
48 std::vector<MPI_Offset>& field_sizes);
49 void _fillField(const std::string& field_name, const MPI_Offset field_size,
52 std::string field_file{};
53#endif
54
55 public:
57
60 std::vector<std::shared_ptr<GenericManagingModule<T>>>& all_modules,
61 std::vector<std::shared_ptr<GenericSubmodule<T>>>& all_submodules);
63};
64
70template <typename T>
72{
73 // Check if sim config or module ini file retention is selected.
74 try
75 {
76 m_keep_sim_config = sim->m_simulation_config.getBoolParameters("_snapshot_keep_sim");
77 }
78 catch (const BadInput&)
79 {
80 // Do nothing here
81 }
82 try
83 {
84 m_keep_module_inis = sim->m_simulation_config.getBoolParameters("_snapshot_keep_module");
85 }
86 catch (const BadInput&)
87 {
88 // Do nothing here
89 }
90
91 // If a snapshot is given, load it. If not, do nothing, as the user won't have requested a load.
92 try
93 {
94 if (sim->my_rank == 0)
95 {
96 std::cout << sim->m_simulation_config.getStringParameters("snapshot") << "\n";
97 }
98 if (sim->m_simulation_config.getStringParameters("snapshot") == "None")
99 {
100 // I wanted to use return here, but this is apparently disallowed by the standard
101 throw BadInput("String is None.");
102 }
103 std::string filename{sim->m_simulation_config.getStringParameters("snapshot")};
104 std::string filetype{"snapshot"};
105#ifdef MPI_PRESENT
106 _getFieldFile(sim);
107#else
108 m_snapshot_field_data = std::make_unique<CsvParser>(filename, filetype);
109#endif
110 m_snapshot_ini_data = std::make_unique<IniParserSnapshot>(filename);
111 if (sim->my_rank == 0)
112 {
113 std::cout << "\033[32m[SnapshotLoader] Successfully read snapshot file: "
114 << sim->m_simulation_config.getStringParameters("snapshot") << "\033[0m\n";
115 }
116 }
117 catch (const BadInput&)
118 {
119 m_no_snapshot = true;
120 }
121}
122
128template <typename T>
130{
131 if (m_no_snapshot)
132 {
133 return;
134 }
135#ifdef MPI_PRESENT
136 _parseFieldsMPI(sim);
137#else
138 std::vector<std::vector<T>> all_fields_content;
139 std::vector<std::string> all_field_names;
140 double elapsed_time{0.0};
141
142 m_snapshot_field_data->getSnapshotContents(all_fields_content, all_field_names, elapsed_time);
143
144 // For each field that is part of the snapshot
145 for (int i{0}; i < all_field_names.size(); i++)
146 {
147 // Write the snapshot data into the field map. Can't just copy here due to valarray vector
148 // mismatch.
149 for (int j{0}; j < all_fields_content[i].size(); j++)
150 {
151 sim->m_field_map[all_field_names[i]][j] = all_fields_content[i][j];
152 }
153 }
154
155 sim->elapsed_time = elapsed_time;
156 sim->time_step = int(elapsed_time / sim->m_simulation_config.getDoubleParameters("time_delta"));
157#endif
158 if (sim->my_rank == 0)
159 {
160 std::cout
161 << "\033[32m[SnapshotLoader] Successfully loaded snapshot file field data\033[0m\n";
162 }
163}
164
174template <typename T>
177 std::vector<std::shared_ptr<GenericManagingModule<T>>>& all_modules,
178 std::vector<std::shared_ptr<GenericSubmodule<T>>>& all_submodules)
179{
180 if (m_no_snapshot || m_keep_module_inis)
181 {
182 return;
183 }
184 std::vector<std::string> all_module_names;
185 all_module_names = m_snapshot_ini_data->getModuleNames();
186
187 bool module_placed{false};
188 for (const auto& module_name : all_module_names)
189 {
190 if (module_name == "SimulationConfig")
191 {
192 module_placed = true;
193 }
194 for (const auto& loaded_module : all_modules)
195 {
196 if (module_placed)
197 {
198 break;
199 }
200 if (module_name == loaded_module->getNameLocal())
201 {
202 loaded_module->overwriteLocalIniContent(
203 m_snapshot_ini_data->getModuleContents(module_name));
204 module_placed = true;
205 }
206 }
207
208 for (const auto& loaded_submodule : all_submodules)
209 {
210 if (module_placed)
211 {
212 break;
213 }
214 if (module_name == loaded_submodule->getNameLocal())
215 {
216 loaded_submodule->overwriteLocalIniContent(
217 m_snapshot_ini_data->getModuleContents(module_name));
218 module_placed = true;
219 }
220 }
221 if (module_placed)
222 {
223 module_placed = false;
224 }
225 else
226 {
227 std::cerr << "[SnapshotLoader]: Couldn't find module: " << module_name
228 << " in all loaded modules. Please load this module to complete snapshot "
229 "loading.\n";
230 throw std::runtime_error(
231 static_cast<std::string>("[SnapshotLoader]: Couldn't find specified module from "
232 "snapshot file in all loaded modules."));
233 }
234 }
235 if (sim->my_rank == 0)
236 {
237 std::cout << "\033[32m[SnapshotLoader] Successfully loaded snapshot file module ini "
238 "files\033[0m\n";
239 }
240}
241
247template <typename T>
249{
250 if (m_no_snapshot || m_keep_sim_config)
251 {
252 return;
253 }
254 for (const auto& [key, map_content] :
255 m_snapshot_ini_data->getModuleContents("SimulationConfig"))
256 {
257 // Do not write snapshot save file into the config/overwrite it, as it would lead to a loop
258 // that always overwrites the current snapshot.
259 if (key != "snapshot_save_file")
260 {
261 sim->m_simulation_config.forceValueOverwrite(key,
262 std::any_cast<std::string>(map_content));
263 }
264 }
265 if (sim->my_rank == 0)
266 {
267 std::cout << "\033[32m[SnapshotLoader] Successfully loaded snapshot file simulation "
268 "configuration data\033[0m\n";
269 }
270}
271
272#ifdef MPI_PRESENT
280template <typename T>
282{
285 T elapsed_time{};
286 std::vector<std::string> field_names{};
287 std::vector<MPI_Offset> field_sizes{};
288
289 numerical_layers = sim->m_simulation_config.getIntParameters("numerical_layers");
290 local_number_of_facets = sim->m_simulation_config.getIntParameters("number_of_facets");
291 global_number_of_facets = sim->m_simulation_config.getIntParameters("global_number_of_facets");
292 // Set datatype of field to the one used across this simulation
296
303 std::vector<unsigned char> footer_content(footer_data_size);
307 for (int i{0}; i < field_names.size(); i++)
308 {
310 }
311 sim->elapsed_time = elapsed_time;
312 sim->time_step = int(elapsed_time / sim->m_simulation_config.getDoubleParameters("time_delta"));
313}
314
324template <typename T>
325void SnapshotLoader<T>::_parseFooterString(const std::vector<unsigned char>& footer,
326 std::vector<std::string>& field_names, T& elapsed_time,
327 std::vector<MPI_Offset>& field_sizes)
328{
329 std::string footer_string{footer.begin(), footer.end()};
330 auto starting_it{footer_string.begin()};
331 int current_entry{0};
332 for (auto it{footer_string.begin()}; it != footer_string.end(); it++)
333 {
334 if (*it == ',')
335 {
336 std::string current_string{starting_it, it};
337 if (current_entry % 3 == 0)
338 {
339 field_names.push_back(current_string);
340 }
341 else if (current_entry % 3 == 1)
342 {
343 elapsed_time = std::stod(current_string);
344 }
345 else if (current_entry % 3 == 2)
346 {
347 field_sizes.push_back(std::stoi(current_string));
348 }
349 starting_it = it + 1;
351 }
352 }
353}
354
362template <typename T>
364{
365 field_file = sim->m_simulation_config.getStringParameters("snapshot");
366 const auto& file_type_start{std::find(field_file.begin(), field_file.end(), '.')};
367 if (file_type_start == field_file.end())
368 {
369 std::cerr << "Could not find file type separator '.' in supplied snapshot file path. "
370 "Please specify the full path with file type.";
371 throw std::runtime_error(
372 "Could not find file type separator '.' in supplied snapshot file path. "
373 "Please specify the full path with file type.");
374 }
375 std::string insertion{"_fields"};
376 field_file.insert(file_type_start, insertion.begin(), insertion.end());
377}
378
390template <typename T>
393{
394 if (sim->m_field_map.find(field_name) == sim->m_field_map.end())
395 {
396 std::cerr << "Field: " << field_name
397 << " not found in m_field_map! Could not fully load snapshot - terminating.";
398 throw std::runtime_error(
399 "Field could not be found in m_field_map despite loading snapshot. Check "
400 "your snapshot file and configuration!");
401 }
402
405 static_cast<int>((sim->m_field_map[field_name]).size()), m_dtype,
408}
409
422template <typename T>
425{
428 {
429 // For the block of same size processes, displacement is rank * local_number_of_facets *
430 // data_type_byte_size.
431 if (sim->my_rank < sim->number_of_larger_procs)
432 {
435 }
436 // For the second block, add the first block displacement and count how many second block
437 // processes are between the targeted position and the first block.
438 // local_number_of_facets_large_proc = local_number_of_facets_small_proc + numerical_layers.
439 else
440 {
442 (sim->number_of_larger_procs * (local_number_of_facets + 1)
443 + (sim->my_rank - sim->number_of_larger_procs) * local_number_of_facets)
445 }
446 }
448 {
449 // For the block of same size processes, displacement is rank * local_number_of_facets *
450 // data_type_byte_size.
451 if (sim->my_rank < sim->number_of_larger_procs)
452 {
454 }
455 // For the second block, add the first block displacement and count how many second block
456 // processes are between the targeted position and the first block.
457 // local_number_of_facets_large_proc = local_number_of_facets_small_proc + 1.
458 else
459 {
461 (sim->number_of_larger_procs * (local_number_of_facets + 1)
462 + (sim->my_rank - sim->number_of_larger_procs) * local_number_of_facets)
463 * type_size;
464 }
465 }
466 else
467 {
468 // Replace this section in the new MR with handling of "irregular" field sizes.
469 std::cerr
470 << "[SnapshotLoader]: Field in SnapshotLoader is of irregular size! Currently only "
471 "supporting sizes of numerical_layers * numbers_of_facets or numbers_of_facets.\n";
472 throw std::runtime_error(
473 "[SnapshotLoader]: Field in SnapshotLoader is of irregular size! Currently only "
474 "supporting sizes of numerical_layers * numbers_of_facets or numbers_of_facets.\n");
475 }
476 return proc_displacement;
477}
478#endif
This error class inherits from std::exception and marks faulty parameter or CL inputs....
Definition IniParser.h:71
Concrete implementation of a matrix class representing a Compressed Sparse Rows (CSR) matrix....
Definition CsrMatrix.h:37
CsrSparseMatrix()
Constructor for an empty CsrSparseMatrix object. Leaves all storage arrays empty but sets the flag to...
Definition CsrMatrix.h:94
std::pair< int, int > size() const
Function that returns the size of the matrix as a pair in (rows, columns) format.
Definition GenericMatrix.h:120
Class which loads snapshot files and writes their data to the inis and fields. Loads any file created...
Definition SnapshotLoader.h:27
SnapshotLoader(SimulationClassBase< T > *sim)
Constructor of the SnapshotLoader.
Definition SnapshotLoader.h:71
void overwriteIniFiles(SimulationClassBase< T > *sim, std::vector< std::shared_ptr< GenericManagingModule< T > > > &all_modules, std::vector< std::shared_ptr< GenericSubmodule< T > > > &all_submodules)
Overwrites the content of the module ini files within each module. Throws an error,...
Definition SnapshotLoader.h:175
void overwriteSimFields(SimulationClassBase< T > *sim)
Overwrites the fields in sim with the ones from the snapshot.
Definition SnapshotLoader.h:129
void overwriteSimConfig(SimulationClassBase< T > *sim)
Overwrite the simulation config data (default.ini + user supplied run ini).
Definition SnapshotLoader.h:248