MoCSI API Reference
Loading...
Searching...
No Matches
SnapshotCreator.h
Go to the documentation of this file.
1#include <algorithm>
2#include <cstdint>
3#include <fstream>
4#include <iomanip>
5#include <map>
6#include <memory>
7#include <ostream>
8#include <valarray>
9#include <vector>
10
12#include "GenericSubmodule.h"
14
15#ifdef MPI_PRESENT
16#include <mpi.h>
17
19#endif
20
26template <typename T>
28{
29 private:
30 std::ofstream m_global_ini_file_content;
31 std::vector<std::string> m_save_fields{"Temperature"};
32 void gatherIniFileContent(
33 std::vector<std::shared_ptr<GenericManagingModule<double>>>& all_modules,
34 std::vector<std::shared_ptr<GenericSubmodule<double>>>& all_submodules);
35 void writeFields(SimulationClassBase<T>* sim);
36#ifdef MPI_PRESENT
41 int count{0};
45 std::string footer{};
46 std::string field_file{};
49 MPI_Offset _calcDisplacement(const std::valarray<T>& field, SimulationClassBase<T>* sim);
51#endif
52
53 public:
55 std::vector<std::shared_ptr<GenericManagingModule<double>>>& all_modules,
56 std::vector<std::shared_ptr<GenericSubmodule<double>>>& all_submodules);
57};
58
62template <typename T>
65 std::vector<std::shared_ptr<GenericManagingModule<double>>>& all_modules,
66 std::vector<std::shared_ptr<GenericSubmodule<double>>>& all_submodules)
67{
68 try
69 {
70 if (sim->m_simulation_config.getStringParameters("snapshot_save_file") == "None")
71 {
72 // I wanted to use return here, but this is apparently disallowed by the standard
73 throw BadInput("String is None.");
74 }
75 if (sim->my_rank == 0)
76 {
77 m_global_ini_file_content.open(
78 sim->m_simulation_config.getStringParameters("snapshot_save_file"),
79 std::ios::binary | std::ios::out | std::ios::trunc);
80 }
81 // Write the data from the specified fields (m_save_fields) into the snapshot.
82#ifdef MPI_PRESENT
83 if (sim->my_rank == 0)
84 {
85 m_global_ini_file_content << "INIFILEDATA:\n";
86 }
87 _getFieldFile(sim);
88 // Get information necessary to calculate byte sizes of output
89 numerical_layers = sim->m_simulation_config.getIntParameters("numerical_layers");
90 local_number_of_facets = sim->m_simulation_config.getIntParameters("number_of_facets");
92 sim->m_simulation_config.getIntParameters("global_number_of_facets");
93 // Set datatype of field to the one used across this simulation
99 _writeDataMpi(sim);
100 _writeFooter(sim);
102#else
103 writeFields(sim);
104#endif
105 // Get and write the data from the simulation config (default.ini + user supplied run ini).
106 if (sim->my_rank == 0)
107 {
108 std::unordered_map<std::string, std::any> ini_file_content{
109 sim->m_simulation_config.data()};
110 for (const auto& [key, map_content] : ini_file_content)
111 {
112 m_global_ini_file_content << "SimulationConfig" << "$" << key << " = "
113 << std::any_cast<std::string>(map_content) << "\n";
114 }
115 // Get an write the data from the module ini files.
116 gatherIniFileContent(all_modules, all_submodules);
117 m_global_ini_file_content.close();
118 std::cout << "\033[32m[SnapshotCreator] Successfully created snapshot file!\033[0m\n";
119 }
120 }
121 catch (const BadInput&)
122 {
123 // Do nothing here
124 }
125}
126
132template <typename T>
134{
135 // I will probably add a little header with timestamp and maybe some more infos.
136 m_global_ini_file_content << "FIELDDATA:\n";
137 for (const auto& field_name : m_save_fields)
138 {
139 m_global_ini_file_content << field_name << "," << sim->elapsed_time << ",";
140 const std::valarray<T>& field{sim->getField(field_name)};
141 for (int i{0}; i < field.size() - 1; i++)
142 {
143 m_global_ini_file_content << field[i] << std::setprecision(15) << ",";
144 }
145 m_global_ini_file_content << field[field.size() - 1] << std::setprecision(15) << "\n";
146 }
147 m_global_ini_file_content << "INIFILEDATA:\n";
148}
149
156template <typename T>
158 std::vector<std::shared_ptr<GenericManagingModule<double>>>& all_modules,
159 std::vector<std::shared_ptr<GenericSubmodule<double>>>& all_submodules)
160{
161 for (auto& module : all_modules)
162 {
163 module->writeToGlobalIniContent(m_global_ini_file_content);
164 }
165
166 for (auto& submodule : all_submodules)
167 {
168 submodule->writeToGlobalIniContent(m_global_ini_file_content);
169 }
170}
171
172#ifdef MPI_PRESENT
182template <typename T>
184{
186 {
187 std::cerr << "Trying to access an unopened file. Please also use init and output chains "
188 "when using MPI I/O.\n";
189 throw std::runtime_error(
190 "Trying to access an unopened file. Please also use init and output chains when using "
191 "MPI I/O.\n");
192 }
193 for (const auto& field_name : m_save_fields)
194 {
195 const std::valarray<T>& field{sim->getField(field_name)};
199 // Update the starting position (in bytes) for the next write
200 // Each process from the first k can write at position rank * size of its array.
201 // Each process > k needs to account for the larger k processes to determine its pointer
202 // start.
204 {
206 footer += field_name + "," + std::to_string(sim->elapsed_time) + ","
207 + std::to_string(numerical_layers * global_number_of_facets) + ",";
208 }
209 else if (field.size() == local_number_of_facets)
210 {
212 footer += field_name + "," + std::to_string(sim->elapsed_time) + ","
213 + std::to_string(global_number_of_facets) + ",";
214 }
215 else
216 {
217 start += type_size * field.size() * sim->world_size;
218 footer += field_name + "," + std::to_string(sim->elapsed_time) + ","
219 + std::to_string(field.size() * sim->world_size) + ",";
220 }
221 }
222}
223
236template <typename T>
239{
242 {
243 // For the block of same size processes, displacement is rank * local_field_size *
244 // data_type_byte_size.
245 if (sim->my_rank < sim->number_of_larger_procs)
246 {
247 proc_displacement = sim->my_rank * field.size() * type_size;
248 }
249 // For the second block, add the first block displacement and count how many second block
250 // processes are between the targeted position and the first block.
251 // local_field_size_large_proc = local_field_size_small_proc + numerical_layers.
252 else
253 {
254 proc_displacement = (sim->number_of_larger_procs * (field.size() + numerical_layers)
255 + (sim->my_rank - sim->number_of_larger_procs) * field.size())
256 * type_size;
257 }
258 }
259 else if (field.size() == local_number_of_facets)
260 {
261 // For the block of same size processes, displacement is rank * local_field_size *
262 // data_type_byte_size.
263 if (sim->my_rank < sim->number_of_larger_procs)
264 {
265 proc_displacement = sim->my_rank * field.size() * type_size;
266 }
267 // For the second block, add the first block displacement and count how many second block
268 // processes are between the targeted position and the first block.
269 // local_field_size_large_proc = local_field_size_small_proc + 1.
270 else
271 {
272 proc_displacement = (sim->number_of_larger_procs * (field.size() + 1)
273 + (sim->my_rank - sim->number_of_larger_procs) * field.size())
274 * type_size;
275 }
276 }
277 else
278 {
279 // Replace this section in the new MR with handling of "irregular" field sizes.
280 std::cerr
281 << "[SnapshotCreator]: Field in SnapshotCreator is of irregular size! Currently only "
282 "supporting sizes of numerical_layers * numbers_of_facets or numbers_of_facets.\n";
283 throw std::runtime_error(
284 "[SnapshotCreator]: Field in SnapshotCreator is of irregular size! Currently only "
285 "supporting sizes of numerical_layers * numbers_of_facets or numbers_of_facets.\n");
286 }
287 return proc_displacement;
288}
289
298template <typename T>
300{
303 static_cast<MPI_Offset>(start + footer_type_size * footer.size())};
304 if (sim->my_rank == 0)
305 {
307 static_cast<int>(footer.size()), MPI_UNSIGNED_CHAR, MPI_STATUS_IGNORE);
309 data_sizes[1] = footer.size();
312 }
313}
314
322template <typename T>
324{
325 field_file = sim->m_simulation_config.getStringParameters("snapshot_save_file");
326 const auto& file_type_start{std::find(field_file.begin(), field_file.end(), '.')};
327 if (file_type_start == field_file.end())
328 {
329 std::cerr << "Could not find file type separator '.' in supplied snapshot file path. "
330 "Please specify the full path with file type.";
331 throw std::runtime_error(
332 "Could not find file type separator '.' in supplied snapshot file path. "
333 "Please specify the full path with file type.");
334 }
335 std::string insertion{"_fields"};
336 field_file.insert(file_type_start, insertion.begin(), insertion.end());
337}
338#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 creates MoCSI snapshot files. Saves all the specified fields from m_save_fields and all t...
Definition SnapshotCreator.h:28
SnapshotCreator(SimulationClassBase< T > *sim, std::vector< std::shared_ptr< GenericManagingModule< double > > > &all_modules, std::vector< std::shared_ptr< GenericSubmodule< double > > > &all_submodules)
Constructor of the Snapshot Creator.
Definition SnapshotCreator.h:63