diff --git a/include/openPMD/backend/Attributable.hpp b/include/openPMD/backend/Attributable.hpp index c7b92b8b44..3621a22369 100644 --- a/include/openPMD/backend/Attributable.hpp +++ b/include/openPMD/backend/Attributable.hpp @@ -229,6 +229,8 @@ class Attributable /** Reconstructs a path that can be passed to a Series constructor */ std::string filePath() const; + /** Return the path ob the object within the openPMD file */ + std::string openPMDPath() const; }; /** diff --git a/src/backend/Attributable.cpp b/src/backend/Attributable.cpp index 7eaf47dd07..357914d8b9 100644 --- a/src/backend/Attributable.cpp +++ b/src/backend/Attributable.cpp @@ -28,6 +28,7 @@ #include #include #include +#include namespace openPMD { @@ -187,6 +188,26 @@ std::string Attributable::MyPath::filePath() const return directory + seriesName + seriesExtension; } +std::string Attributable::MyPath::openPMDPath() const +{ + if (group.empty()) + { + return std::string(); + } + else + { + std::stringstream res; + auto it = group.begin(); + auto end = group.end(); + res << *it++; + for (; it != end; ++it) + { + res << '/' << *it; + } + return res.str(); + } +} + auto Attributable::myPath() const -> MyPath { MyPath res; diff --git a/test/SerialIOTest.cpp b/test/SerialIOTest.cpp index 7f126e104f..94f2fe65a3 100644 --- a/test/SerialIOTest.cpp +++ b/test/SerialIOTest.cpp @@ -5096,6 +5096,39 @@ bool areEqual(T a, T b) } // namespace epsilon #if openPMD_HAVE_ADIOS2 + +#define openPMD_VERBOSE_CHUNKS 0 + +#if openPMD_VERBOSE_CHUNKS +static std::string format_chunk(ChunkInfo const &chunk_info) +{ + std::stringstream result; + auto print_vector = [&result](auto const &vec) { + if (vec.empty()) + { + result << "[]"; + } + else + { + auto it = vec.begin(); + result << '[' << *it++; + auto end = vec.end(); + for (; it != end; ++it) + { + result << ',' << *it; + } + result << ']'; + } + }; + result << '('; + print_vector(chunk_info.offset); + result << '|'; + print_vector(chunk_info.extent); + result << ')'; + return result.str(); +} +#endif + TEST_CASE("git_adios2_sample_test", "[serial][adios2]") { using namespace epsilon; @@ -5105,11 +5138,71 @@ TEST_CASE("git_adios2_sample_test", "[serial][adios2]") std::string const samplePath = "../samples/git-sample/3d-bp4/example-3d-bp4.bp"; + std::string const samplePathFilebased = + "../samples/git-sample/3d-bp4/example-3d-bp4_%T.bp"; if (!auxiliary::directory_exists(samplePath)) { std::cerr << "git sample '" << samplePath << "' not accessible \n"; return; } + + /* + * This checks a regression introduced by + * https://github.com/openPMD/openPMD-api/pull/1498 and fixed by + * https://github.com/openPMD/openPMD-api/pull/1586 + */ + for (auto const &[filepath, access] : + {std::make_pair(samplePath, Access::READ_ONLY), + std::make_pair(samplePathFilebased, Access::READ_ONLY), + std::make_pair(samplePath, Access::READ_LINEAR), + std::make_pair(samplePathFilebased, Access::READ_LINEAR)}) + { + Series read(filepath, access); + + for (auto iteration : read.readIterations()) + { + for (auto &[mesh_name, mesh] : iteration.meshes) + { + for (auto &[component_name, component] : mesh) + { +#if openPMD_VERBOSE_CHUNKS + std::cout << "Chunks for '" + << component.myPath().openPMDPath() + << "':" << std::endl; + for (auto const &chunk : component.availableChunks()) + { + std::cout << "\t" << format_chunk(chunk) << std::endl; + } +#else + component.availableChunks(); +#endif + } + } + for (auto &[particle_species_name, particle_species] : + iteration.particles) + { + for (auto &[record_name, record] : particle_species) + { + for (auto &[component_name, component] : record) + { +#if openPMD_VERBOSE_CHUNKS + std::cout << "Chunks for '" + << component.myPath().openPMDPath() + << "':" << std::endl; + for (auto const &chunk : component.availableChunks()) + { + std::cout << "\t" << format_chunk(chunk) + << std::endl; + } +#else + component.availableChunks(); +#endif + } + } + } + } + } + Series o(samplePath, Access::READ_ONLY, R"({"backend": "adios2"})"); REQUIRE(o.openPMD() == "1.1.0"); REQUIRE(o.openPMDextension() == 0);