Shamrock 2025.10.0
Astrophysical Code
Loading...
Searching...
No Matches
PhantomDump.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
21#include "shambase/sets.hpp"
23#include "shambase/string.hpp"
25#include "shamcomm/logs.hpp"
31#include <unordered_map>
32#include <string>
33#include <vector>
34
35template<class T>
44
45template<class T>
47 shambase::FortranIOFile &phfile, i64 tot_count) {
48 StackEntry stack_loc{};
49 phfile.write_fixed_string(tag, 16);
50 phfile.write_val_array(vals, tot_count);
51}
52
53template<class T>
55 logger::raw_ln("tag =", tag, "size =", vals.size());
56}
57
58template<class T>
61 StackEntry stack_loc{};
62
64
65 int nvars;
66
67 phfile.read(nvars);
68
69 if (nvars == 0) {
70 return tmp;
71 }
73 std::vector<std::string> tags;
74 phfile.read_string_array(tags, 16, nvars);
75
76 std::vector<T> vals;
77 phfile.read_val_array(vals, nvars);
78
79 for (u32 i = 0; i < nvars; i++) {
80 tmp.entries.push_back({tags[i], vals[i]});
81 }
82
83 return tmp;
84}
85
86template<class T>
88 StackEntry stack_loc{};
89
90 int nvars = entries.size();
91 phfile.write(nvars);
92
93 if (nvars == 0) {
94 return;
95 }
96
97 std::vector<std::string> tags;
98 std::vector<T> vals;
99 for (u32 i = 0; i < nvars; i++) {
100 auto [a, b] = entries[i];
101 tags.push_back(a);
102 vals.push_back(b);
103 }
104
105 phfile.write_string_array(tags, 16, nvars);
106 phfile.write_val_array(vals, nvars);
107}
108
109template<class T>
112 for (auto [key, val] : entries) {
113 logger::raw_ln(key, val);
114 }
115}
116
118
119 logger::raw_ln("--blocks_fort_int --");
120 for (auto b : blocks_fort_int) {
121 b.print_state();
122 }
123 logger::raw_ln("--blocks_i8 --");
124 for (auto b : blocks_i8) {
125 b.print_state();
126 }
127 logger::raw_ln("--blocks_i16 --");
128 for (auto b : blocks_i16) {
129 b.print_state();
130 }
131 logger::raw_ln("--blocks_i32 --");
132 for (auto b : blocks_i32) {
133 b.print_state();
134 }
135 logger::raw_ln("--blocks_i64 --");
136 for (auto b : blocks_i64) {
137 b.print_state();
138 }
139 logger::raw_ln("--blocks_fort_real--");
140 for (auto b : blocks_fort_real) {
141 b.print_state();
142 }
143 logger::raw_ln("--blocks_f32 --");
144 for (auto b : blocks_f32) {
145 b.print_state();
146 }
147 logger::raw_ln("--blocks_f64 --");
148 for (auto b : blocks_f64) {
149 b.print_state();
150 }
151}
152
154 shambase::FortranIOFile &phfile, i64 tot_count, std::array<i32, 8> numarray) {
155 PhantomDumpBlock block;
156
157 block.tot_count = tot_count;
158
159 for (u32 j = 0; j < numarray[0]; j++) {
160 block.blocks_fort_int.push_back(
162 }
163 for (u32 j = 0; j < numarray[1]; j++) {
164 block.blocks_i8.push_back(PhantomDumpBlockArray<i8>::from_file(phfile, block.tot_count));
165 }
166 for (u32 j = 0; j < numarray[2]; j++) {
167 block.blocks_i16.push_back(PhantomDumpBlockArray<i16>::from_file(phfile, block.tot_count));
168 }
169 for (u32 j = 0; j < numarray[3]; j++) {
170 block.blocks_i32.push_back(PhantomDumpBlockArray<i32>::from_file(phfile, block.tot_count));
171 }
172 for (u32 j = 0; j < numarray[4]; j++) {
173 block.blocks_i64.push_back(PhantomDumpBlockArray<i64>::from_file(phfile, block.tot_count));
174 }
175 for (u32 j = 0; j < numarray[5]; j++) {
176 block.blocks_fort_real.push_back(
178 }
179 for (u32 j = 0; j < numarray[6]; j++) {
180 block.blocks_f32.push_back(PhantomDumpBlockArray<f32>::from_file(phfile, block.tot_count));
181 }
182 for (u32 j = 0; j < numarray[7]; j++) {
183 block.blocks_f64.push_back(PhantomDumpBlockArray<f64>::from_file(phfile, block.tot_count));
184 }
185
186 return block;
187}
188
190 shambase::FortranIOFile &phfile, i64 tot_count, std::array<i32, 8> numarray) {
191 StackEntry stack_loc{};
192
193 for (u32 j = 0; j < numarray[0]; j++) {
194 blocks_fort_int[j].write(phfile, tot_count);
195 }
196 for (u32 j = 0; j < numarray[1]; j++) {
197 blocks_i8[j].write(phfile, tot_count);
198 }
199 for (u32 j = 0; j < numarray[2]; j++) {
200 blocks_i16[j].write(phfile, tot_count);
201 }
202 for (u32 j = 0; j < numarray[3]; j++) {
203 blocks_i32[j].write(phfile, tot_count);
204 }
205 for (u32 j = 0; j < numarray[4]; j++) {
206 blocks_i64[j].write(phfile, tot_count);
207 }
208 for (u32 j = 0; j < numarray[5]; j++) {
209 blocks_fort_real[j].write(phfile, tot_count);
210 }
211 for (u32 j = 0; j < numarray[6]; j++) {
212 blocks_f32[j].write(phfile, tot_count);
213 }
214 for (u32 j = 0; j < numarray[7]; j++) {
215 blocks_f64[j].write(phfile, tot_count);
216 }
217}
218
220
221 s = shambase::format("{:16s}", s);
222 auto &blocks = blocks_fort_real;
223
224 for (u32 i = 0; i < blocks_fort_real.size(); i++) {
225 if (blocks_fort_real[i].tag == s) {
226 return i;
227 }
228 }
229
231 tmp.tag = s;
232 blocks_fort_real.push_back(std::move(tmp));
233
234 for (u32 i = 0; i < blocks_fort_real.size(); i++) {
235 if (blocks_fort_real[i].tag == s) {
236 return i;
237 }
238 }
239
240 return 0;
241}
242
244
245 s = shambase::format("{:16s}", s);
246
247 auto &blocks = blocks_f32;
248
249 for (u32 i = 0; i < blocks_f32.size(); i++) {
250 if (blocks_f32[i].tag == s) {
251 return i;
252 }
253 }
254
256 tmp.tag = s;
257 blocks_f32.push_back(std::move(tmp));
258
259 for (u32 i = 0; i < blocks_f32.size(); i++) {
260 if (blocks_f32[i].tag == s) {
261 return i;
262 }
263 }
264
265 return 0;
266}
267
269 StackEntry stack_loc{};
270
272 phfile.write(i1, r1, i2, iversion, i3);
273
274 phfile.write_fixed_string(fileid, 100);
275
276 table_header_fort_int.write(phfile);
277 table_header_i8.write(phfile);
278 table_header_i16.write(phfile);
279 table_header_i32.write(phfile);
280 table_header_i64.write(phfile);
281 table_header_fort_real.write(phfile);
282 table_header_f32.write(phfile);
283 table_header_f64.write(phfile);
284
285 int nblocks = blocks.size();
286 phfile.write(nblocks);
287
288 std::vector<i64> block_tot_counts;
289 std::vector<std::array<i32, 8>> block_numarray;
290 for (u32 i = 0; i < nblocks; i++) {
291
292 i64 tot_count = blocks[i].tot_count;
293 std::array<i32, 8> counts
294 = {i32(blocks[i].blocks_fort_int.size()),
295 i32(blocks[i].blocks_i8.size()),
296 i32(blocks[i].blocks_i16.size()),
297 i32(blocks[i].blocks_i32.size()),
298 i32(blocks[i].blocks_i64.size()),
299 i32(blocks[i].blocks_fort_real.size()),
300 i32(blocks[i].blocks_f32.size()),
301 i32(blocks[i].blocks_f64.size())};
302
303 phfile.write(tot_count, counts);
304 block_tot_counts.push_back(tot_count);
305 block_numarray.push_back(counts);
306 }
307
308 for (u32 i = 0; i < nblocks; i++) {
309 blocks[i].write(phfile, block_tot_counts[i], block_numarray[i]);
310 }
311
312 return phfile;
313}
314
316 shambase::FortranIOFile &phfile) {
317 PhantomDump phdump;
318
319 // first line
320 //<4 bytes>i1,r1,i2,iversion,i3<4 bytes>
321 phfile.read(phdump.i1, phdump.r1, phdump.i2, phdump.iversion, phdump.i3);
322 phdump.check_magic_numbers();
323
324 // The second line contains a 100-character file identifier:
325 // <4 bytes>fileid<4 bytes>
326 phfile.read_fixed_string(phdump.fileid, 100);
327
328 // loop i=1,8
329 // <4 bytes>nvars<4 bytes>
330 // <4 bytes>tags(1:nvars)<4 bytes>
331 // <4 bytes>vals(1:nvals)<4 bytes>
332 // end loop
341
342 int nblocks;
343 phfile.read(nblocks);
344
345 std::vector<i64> block_tot_counts;
346 std::vector<std::array<i32, 8>> block_numarray;
347
348 for (u32 i = 0; i < nblocks; i++) {
349
350 i64 tot_count;
351 std::array<i32, 8> counts;
352
353 phfile.read(tot_count, counts);
354
355 block_tot_counts.push_back(tot_count);
356 block_numarray.push_back(counts);
357 }
358 for (u32 i = 0; i < nblocks; i++) {
359 phdump.blocks.push_back(
360 PhantomDumpBlock::from_file(phfile, block_tot_counts[i], block_numarray[i]));
361 }
362
363 if (!phfile.finished_read()) {
364 logger::warn_ln("[PhantomReader]", "some data was not read");
365 }
366
367 return phdump;
368}
369
371 logger::raw_ln("--- dump state ---");
372
373 logger::raw_ln("table_header_fort_int len =", table_header_fort_int.entries.size());
374 table_header_fort_int.print_state();
375 logger::raw_ln("table_header_i8 len =", table_header_i8.entries.size());
376 table_header_i8.print_state();
377 logger::raw_ln("table_header_i16 len =", table_header_i16.entries.size());
378 table_header_i16.print_state();
379 logger::raw_ln("table_header_i32 len =", table_header_i32.entries.size());
380 table_header_i32.print_state();
381 logger::raw_ln("table_header_i64 len =", table_header_i64.entries.size());
382 table_header_i64.print_state();
383 logger::raw_ln("table_header_fort_real len =", table_header_fort_real.entries.size());
384 table_header_fort_real.print_state();
385 logger::raw_ln("table_header_f32 len =", table_header_f32.entries.size());
386 table_header_f32.print_state();
387 logger::raw_ln("table_header_f64 len =", table_header_f64.entries.size());
388 table_header_f64.print_state();
389
390 for (u32 i = 0; i < blocks.size(); i++) {
391 logger::raw_ln("block ", i, ":");
392 blocks[i].print_state();
393 }
394 logger::raw_ln("------------------");
395}
396
398
399 u64 offenses = 0;
400
401 auto load_header = [](PhantomDump &dump) {
402 std::unordered_map<std::string, f64> header;
403
404 dump.table_header_fort_int.add_to_map(header);
405 dump.table_header_i8.add_to_map(header);
406 dump.table_header_i16.add_to_map(header);
407 dump.table_header_i32.add_to_map(header);
408 dump.table_header_i64.add_to_map(header);
409 dump.table_header_fort_real.add_to_map(header);
410 dump.table_header_f32.add_to_map(header);
411 dump.table_header_f64.add_to_map(header);
412 return header;
413 };
414
415 std::unordered_map<std::string, f64> header_ref = load_header(dump_ref);
416 std::unordered_map<std::string, f64> header_comp = load_header(dump_comp);
417
418 auto get_keys = [](std::unordered_map<std::string, f64> &map) {
419 std::set<std::string> ret;
420 for (auto [key, val] : map) {
421 ret.insert(key);
422 }
423 return ret;
424 };
425
426 std::set<std::string> header_key_ref = get_keys(header_ref);
427 std::set<std::string> header_key_comp = get_keys(header_comp);
428
429 std::vector<std::string> missing = {};
430 std::vector<std::string> matching = {};
431 std::vector<std::string> extra = {};
432
433 shambase::set_diff(header_key_comp, header_key_ref, missing, matching, extra);
434
435 for (std::string &missing_key : missing) {
436 logger::warn_ln(
437 "PhantomDump",
438 "The dump we are comparing against is missing the key",
439 missing_key,
440 "in the header");
441 offenses++;
442 }
443 for (std::string &matching_key : matching) {
444 if (header_ref[matching_key] != header_comp[matching_key]) {
445 logger::warn_ln(
446 "PhantomDump",
447 shambase::format(
448 "Mismatch in the header key {}, ref={}, comp={}",
449 matching_key,
450 header_ref[matching_key],
451 header_comp[matching_key]));
452 offenses++;
453 }
454 }
455 for (std::string &extra_key : extra) {
456 logger::warn_ln(
457 "PhantomDump",
458 "The dump we are comparing against has the extra key",
459 extra_key,
460 "in the header");
461 offenses++;
462 }
463
464 logger::info_ln("PhantomDump", "This comparison reported", offenses, "offenses");
465
466 return offenses == 0;
467}
std::uint32_t u32
32 bit unsigned integer
std::uint64_t u64
64 bit unsigned integer
std::int64_t i64
64 bit integer
std::int32_t i32
32 bit integer
Class for reading and writing Fortran-style binary files.
void write(Args &...args)
Write a list of arguments to the internal buffer.
void write_string_array(std::vector< std::string > &svec, u32 strlen, u32 str_count)
Write a fixed-length string array to the buffer.
void write_val_array(std::vector< T > &vec, u32 val_count)
Write an array of values to the buffer.
void read_fixed_string(std::string &s, u32 len)
Read a fixed-length string from the buffer.
void read(Args &...args)
Read a list of arguments from the internal buffer.
void read_string_array(std::vector< std::string > &svec, u32 strlen, u32 str_count)
Read a fixed-length string array from the buffer.
void read_val_array(std::vector< T > &vec, u32 val_count)
Read an array of values from the buffer.
void write_fixed_string(std::string &s, u32 len)
Write a fixed-length string to the buffer.
bool finished_read()
Check if the end of the file has been reached.
This header file contains utility functions related to exception handling in the code.
void set_diff(Container1 &c1, Container2 &ref, std::vector< T > &missing, std::vector< T > &matching, std::vector< T > &extra)
Compute the difference between two containers as three separate vectors.
Definition sets.hpp:41
bool compare_phantom_dumps(PhantomDump &dump1, PhantomDump &dump2)
Compare two phantom dumps and report offenses.
This file contains the definition for the stacktrace related functionality.
A helper class to represent a single block of data in a Phantom dump.
void write(shambase::FortranIOFile &phfile, i64 tot_count)
Writes a block to a file.
std::string tag
The tag of the block.
void print_state()
Prints the state of the block.
std::vector< T > vals
The values of the block.
static PhantomDumpBlockArray from_file(shambase::FortranIOFile &phfile, i64 tot_count)
Reads a block from a file.
A class to represent a single block of data in a Phantom dump.
std::vector< PhantomDumpBlockArray< fort_int > > blocks_fort_int
The blocks of values of type fort_int.
static PhantomDumpBlock from_file(shambase::FortranIOFile &phfile, i64 tot_count, std::array< i32, 8 > numarray)
Reads a block from a file.
u64 get_ref_f32(std::string s)
Gets the index of a block of type f32 with the given name.
std::vector< PhantomDumpBlockArray< i16 > > blocks_i16
The blocks of values of type i16.
std::vector< PhantomDumpBlockArray< i8 > > blocks_i8
The blocks of values of type i8.
std::vector< PhantomDumpBlockArray< f64 > > blocks_f64
The blocks of values of type f64.
std::vector< PhantomDumpBlockArray< i64 > > blocks_i64
The blocks of values of type i64.
void write(shambase::FortranIOFile &phfile, i64 tot_count, std::array< i32, 8 > numarray)
Writes a block to a file.
u64 get_ref_fort_real(std::string s)
Gets the index of a block of type fort_real with the given name.
std::vector< PhantomDumpBlockArray< i32 > > blocks_i32
The blocks of values of type i32.
i64 tot_count
The total number of values in the block.
std::vector< PhantomDumpBlockArray< fort_real > > blocks_fort_real
The blocks of values of type fort_real.
std::vector< PhantomDumpBlockArray< f32 > > blocks_f32
The blocks of values of type f32.
void print_state()
Prints the state of the block.
Phantom dump table header for a specific type.
static PhantomDumpTableHeader< T > from_file(shambase::FortranIOFile &phfile)
Reads the header from a Phantom dump file.
std::vector< std::pair< std::string, T > > entries
A vector of pairs containing the name and the value of each entry in the table.
void print_state()
Prints the state of the header.
void write(shambase::FortranIOFile &phfile)
Writes the header to a Phantom dump file.
Class representing a Phantom dump file.
PhantomDumpTableHeader< i16 > table_header_i16
Table header for signed 16-bit integer data.
fort_int i3
Magic number used in the phantom dump format.
void check_magic_numbers()
Checks if the magic numbers in the PhantomDump struct match the expected values.
PhantomDumpTableHeader< fort_int > table_header_fort_int
Table header for integer data.
std::string fileid
Magic number used in the phantom dump format.
fort_int i1
Magic number used in the phantom dump format.
PhantomDumpTableHeader< f32 > table_header_f32
Table header for 32-bit floating-point data.
PhantomDumpTableHeader< i64 > table_header_i64
Table header for signed 64-bit integer data.
PhantomDumpTableHeader< i32 > table_header_i32
Table header for signed 32-bit integer data.
static PhantomDump from_file(shambase::FortranIOFile &phfile)
Reads a Phantom dump file and returns a PhantomDump object.
shambase::FortranIOFile gen_file()
Generates a Phantom dump file from the current state of the object.
fort_int i2
Magic number used in the phantom dump format.
std::vector< PhantomDumpBlock > blocks
List of blocks in the Phantom dump file.
PhantomDumpTableHeader< fort_real > table_header_fort_real
Table header for floating-point data.
PhantomDumpTableHeader< f64 > table_header_f64
Table header for 64-bit floating-point data.
fort_int iversion
Magic number used in the phantom dump format.
void print_state()
Print current state of the data stored in the class.
PhantomDumpTableHeader< i8 > table_header_i8
Table header for signed 8-bit integer data.
fort_real r1
Magic number used in the phantom dump format.