Skip to content

Commit 9d2865a

Browse files
author
Martin D. Weinberg
committed
Merge branch 'InitFromHDF5' into slabUpdate
2 parents a466da9 + a486ae0 commit 9d2865a

2 files changed

Lines changed: 99 additions & 28 deletions

File tree

src/Component.cc

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1479,11 +1479,17 @@ void Component::read_bodies_and_distribute_init()
14791479
// Note: One might need to use H5Fis_hdf5(filename.c_str()) for
14801480
// older HDF5 versions (< 1.12)
14811481

1482+
bool isHDF5 = false;
1483+
1484+
if (myid == 0) {
14821485
#if H5_VERSION_GE(1, 12, 0)
1483-
bool isHDF5 = H5Fis_accessible(pfile.c_str(), H5P_DEFAULT) > 0;
1486+
isHDF5 = H5Fis_accessible(pfile.c_str(), H5P_DEFAULT) > 0;
14841487
#else
1485-
bool isHDF5 = H5Fis_hdf5(pfile.c_str()) > 0;
1488+
isHDF5 = H5Fis_hdf5(pfile.c_str()) > 0;
14861489
#endif
1490+
}
1491+
1492+
MPI_Bcast(&isHDF5, 1, MPI_CXX_BOOL, 0, MPI_COMM_WORLD);
14871493

14881494
if (isHDF5) {
14891495
if (myid==0)
@@ -1501,20 +1507,20 @@ void Component::read_bodies_and_distribute_init()
15011507
// Detect float precision by inspecting dataset type
15021508
size_t Component::detect_precision(const HighFive::DataSet& dataset)
15031509
{
1504-
auto datatype = dataset.getDataType();
1505-
auto class_type = datatype.getClass();
1510+
const auto datatype = dataset.getDataType();
1511+
if (datatype.getClass() != HighFive::DataTypeClass::Float) {
1512+
throw std::runtime_error("Unexpected dataset type: expected float for precision detection");
1513+
}
15061514

15071515
// Get the size in bytes
1508-
size_t type_size = datatype.getSize();
1516+
const size_t type_size = datatype.getSize();
15091517

15101518
// Float32 is 4 bytes, Float64 is 8 bytes
1511-
if (type_size == 4) {
1512-
return type_size;
1513-
} else if (type_size == 8) {
1519+
if (type_size == 4 || type_size == 8) {
15141520
return type_size;
1515-
} else {
1516-
throw std::runtime_error("Unexpected float type size: " + std::to_string(type_size));
15171521
}
1522+
1523+
throw std::runtime_error("Unexpected float type size: " + std::to_string(type_size));
15181524
}
15191525

15201526
void Component::read_bodies_and_distribute_hdf5(void)

utils/PhaseSpace/hdf5bods.cc

Lines changed: 83 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
Draft EXP ascii particle phase-space data HDF5 converter
2+
EXP ascii particle phase-space data HDF5 converter
33
44
This is a possible template for implementing HDF5 input files for
55
EXP. The code reads an ASCII file with particle data and writes it to
@@ -71,9 +71,11 @@ style by porting over the ascii_to_hdf5 routine().
7171
#include <filesystem>
7272
#include <iostream>
7373
#include <iomanip>
74+
#include <cstdlib>
7475
#include <fstream>
7576
#include <sstream>
7677
#include <chrono>
78+
#include <cmath>
7779
#include <vector>
7880
#include <stdexcept>
7981
#include <variant>
@@ -126,9 +128,10 @@ void parse_particle_line(const std::string& line,
126128
T val;
127129

128130
// Parse core PSP fields
129-
if (!(iss >> data.m[particle_idx]
130-
>> data.x[particle_idx] >> data.y[particle_idx] >> data.z[particle_idx]
131-
>> data.u[particle_idx] >> data.v[particle_idx] >> data.w[particle_idx])) {
131+
if (!(iss
132+
>> data.m[particle_idx]
133+
>> data.x[particle_idx] >> data.y[particle_idx] >> data.z[particle_idx]
134+
>> data.u[particle_idx] >> data.v[particle_idx] >> data.w[particle_idx])) {
132135
throw std::runtime_error("Failed to parse core fields at particle " +
133136
std::to_string(particle_idx));
134137
}
@@ -269,7 +272,8 @@ void ascii_to_hdf5_impl(const std::string& ascii_file,
269272
// Define compression filters
270273
DataSetCreateProps props;
271274
hsize_t chunk = static_cast<hsize_t>(std::max(num_particles / 10, 1024));
272-
if (chunk > static_cast<hsize_t>(num_particles)) chunk = static_cast<hsize_t>(num_particles);
275+
if (chunk > static_cast<hsize_t>(num_particles))
276+
chunk = static_cast<hsize_t>(num_particles);
273277
props.add(Chunking(std::vector<hsize_t>{chunk}));
274278
props.add(Shuffle());
275279
props.add(Deflate(4)); // This is a good compromise between
@@ -334,20 +338,22 @@ struct ParticleDataVariant
334338
// Detect float precision by inspecting dataset type
335339
FloatPrecision detect_precision(const DataSet& dataset)
336340
{
337-
auto datatype = dataset.getDataType();
338-
auto class_type = datatype.getClass();
341+
const auto datatype = dataset.getDataType();
342+
if (datatype.getClass() != DataTypeClass::Float) {
343+
throw std::runtime_error("Unexpected dataset type for precision detection (expected float)");
344+
}
339345

340346
// Get the size in bytes
341-
size_t type_size = datatype.getSize();
347+
const size_t type_size = datatype.getSize();
342348

343349
// Float32 is 4 bytes, Float64 is 8 bytes
344350
if (type_size == 4) {
345351
return FloatPrecision::FLOAT32;
346352
} else if (type_size == 8) {
347353
return FloatPrecision::FLOAT64;
348-
} else {
349-
throw std::runtime_error("Unexpected float type size: " + std::to_string(type_size));
350354
}
355+
356+
throw std::runtime_error("Unexpected float type size: " + std::to_string(type_size));
351357
}
352358

353359

@@ -374,8 +380,7 @@ ParticleDataVariant read_hdf5_data(const std::string& hdf5_file)
374380
data.num_aux_floats = num_aux_floats;
375381
data.precision = precision;
376382

377-
std::string precision_str = (precision == FloatPrecision::FLOAT32) ? "float32" : "float64";
378-
std::cout << "Detected precision: " << precision_str << std::endl;
383+
// Precision is available in data.precision; caller decides whether to print it.
379384

380385
// Lambda to read float or double based on precision
381386
auto read_dataset = [&particles_group, precision](const std::string& name) -> FloatData {
@@ -388,9 +393,11 @@ ParticleDataVariant read_hdf5_data(const std::string& hdf5_file)
388393

389394
// Read core PSP fields
390395
data.m = read_dataset("m");
396+
391397
data.x = read_dataset("x");
392398
data.y = read_dataset("y");
393399
data.z = read_dataset("z");
400+
394401
data.u = read_dataset("u");
395402
data.v = read_dataset("v");
396403
data.w = read_dataset("w");
@@ -627,10 +634,14 @@ precision is used.
627634

628635
std::string line_orig, line_rest;
629636
size_t line_num = 0;
630-
bool mismatch_found = false;
631-
637+
632638
std::vector<double> max_diff(7, 0.0); // For m, x, y, z, u, v, w
633639
std::vector<double> vec_orig(7), vec_rest(7);
640+
std::vector<double> max_aux_int_diff;
641+
std::vector<double> max_aux_float_diff;
642+
std::vector<int> aux_int_orig, aux_int_rest;
643+
std::vector<double> aux_float_orig, aux_float_rest;
644+
int num_aux_ints = -1, num_aux_floats = -1;
634645

635646
while (std::getline(original, line_orig) && std::getline(restored, line_rest)) {
636647
++line_num;
@@ -650,16 +661,25 @@ precision is used.
650661
std::cerr << "Header mismatch at line 1:\n"
651662
<< "Original: " << line_orig << "\n"
652663
<< "Restored: " << line_rest << "\n";
653-
mismatch_found = true;
654664
break;
655665
}
666+
667+
num_aux_ints = total_aux_ints_orig;
668+
num_aux_floats = total_aux_floats_orig;
669+
max_aux_int_diff.assign(num_aux_ints, 0.0);
670+
max_aux_float_diff.assign(num_aux_floats, 0.0);
671+
aux_int_orig.assign(num_aux_ints, 0);
672+
aux_int_rest.assign(num_aux_ints, 0);
673+
aux_float_orig.assign(num_aux_floats, 0.0);
674+
aux_float_rest.assign(num_aux_floats, 0.0);
656675

657676
continue;
658677
}
659678

660679
for (int i = 0; i < 7; ++i) {
661-
ss_orig >> vec_orig[i];
662-
ss_rest >> vec_rest[i];
680+
if (!(ss_orig >> vec_orig[i]) || !(ss_rest >> vec_rest[i])) {
681+
throw std::runtime_error("Failed to parse core field at line " + std::to_string(line_num));
682+
}
663683
}
664684

665685
for (int i = 0; i < 7; ++i) {
@@ -668,6 +688,30 @@ precision is used.
668688
}
669689

670690
}
691+
692+
for (int i = 0; i < num_aux_ints; ++i) {
693+
if (!(ss_orig >> aux_int_orig[i]) || !(ss_rest >> aux_int_rest[i])) {
694+
throw std::runtime_error("Failed to parse auxiliary integer field at line " + std::to_string(line_num));
695+
}
696+
}
697+
698+
for (int i = 0; i < num_aux_ints; ++i) {
699+
auto diff_i = std::llabs(static_cast<long long>(aux_int_orig[i]) -
700+
static_cast<long long>(aux_int_rest[i]));
701+
double diff = static_cast<double>(diff_i);
702+
if (diff > max_aux_int_diff[i]) max_aux_int_diff[i] = diff;
703+
}
704+
705+
for (int i = 0; i < num_aux_floats; ++i) {
706+
if (!(ss_orig >> aux_float_orig[i]) || !(ss_rest >> aux_float_rest[i])) {
707+
throw std::runtime_error("Failed to parse auxiliary float field at line " + std::to_string(line_num));
708+
}
709+
}
710+
711+
for (int i = 0; i < num_aux_floats; ++i) {
712+
double diff = std::abs(aux_float_orig[i] - aux_float_rest[i]);
713+
if (diff > max_aux_float_diff[i]) max_aux_float_diff[i] = diff;
714+
}
671715
}
672716

673717
std::cout << "Maximum absolute differences for core fields"
@@ -679,6 +723,28 @@ precision is used.
679723
<< max_diff[4] << ", "
680724
<< max_diff[5] << ", "
681725
<< max_diff[6] << std::endl;
726+
727+
std::cout << "Maximum absolute differences for auxiliary integer fields: ";
728+
if (max_aux_int_diff.empty()) {
729+
std::cout << "(none)";
730+
} else {
731+
for (size_t i = 0; i < max_aux_int_diff.size(); ++i) {
732+
if (i) std::cout << ", ";
733+
std::cout << max_aux_int_diff[i];
734+
}
735+
}
736+
std::cout << std::endl;
737+
738+
std::cout << "Maximum absolute differences for auxiliary float fields: ";
739+
if (max_aux_float_diff.empty()) {
740+
std::cout << "(none)";
741+
} else {
742+
for (size_t i = 0; i < max_aux_float_diff.size(); ++i) {
743+
if (i) std::cout << ", ";
744+
std::cout << max_aux_float_diff[i];
745+
}
746+
}
747+
std::cout << std::endl;
682748
}
683749

684750
} catch (const std::exception& e) {
@@ -746,4 +812,3 @@ precision is used.
746812

747813
return 0;
748814
}
749-

0 commit comments

Comments
 (0)