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