Skip to content
Snippets Groups Projects
Commit 4028d689 authored by Stéphane Del Pino's avatar Stéphane Del Pino
Browse files

Add tests for SubItemValuePerItemVariant checkpointing

parent af903489
No related branches found
No related tags found
1 merge request!199Integrate checkpointing
......@@ -72,11 +72,15 @@ readSubItemValuePerItemVariant(const HighFive::Group& sub_item_value_per_item_va
readSubItemValuePerItem<TinyMatrix<3>, item_type, sub_item_type>(sub_item_value_per_item_variant_group,
"values", connectivity));
} else {
// LCOV_EXCL_START
throw UnexpectedError("unexpected discrete function data type: " + data_type);
// LCOV_EXCL_STOP
}
return p_sub_item_value_per_item_variant;
} else {
// LCOV_EXCL_START
throw UnexpectedError("item_type and sub_item_type must be different");
// LCOV_EXCL_STOP
}
}
......
......@@ -177,6 +177,7 @@ if(PUGS_HAS_HDF5)
test_checkpointing_IWriter.cpp
test_checkpointing_IZoneDescriptor.cpp
test_checkpointing_Mesh.cpp
test_checkpointing_SubItemValuePerItemVariant.cpp
test_checkpointing_Table.cpp
)
endif(PUGS_HAS_HDF5)
......
#include <catch2/catch_test_macros.hpp>
#include <catch2/matchers/catch_matchers_all.hpp>
#include <utils/Messenger.hpp>
#include <language/utils/DataHandler.hpp>
#include <language/utils/EmbeddedData.hpp>
#include <mesh/Mesh.hpp>
#include <mesh/SubItemValuePerItemVariant.hpp>
#include <utils/GlobalVariableManager.hpp>
#include <utils/checkpointing/ReadSubItemValuePerItemVariant.hpp>
#include <utils/checkpointing/ResumingData.hpp>
#include <utils/checkpointing/WriteSubItemValuePerItemVariant.hpp>
#include <MeshDataBaseForTests.hpp>
#include <checkpointing_Connectivity_utilities.hpp>
#include <filesystem>
// clazy:excludeall=non-pod-global-static
namespace test_only
{
template <typename DataType, typename ItemOfItemTypeT>
PUGS_INLINE void
check_is_same(const SubItemValuePerItem<DataType, ItemOfItemTypeT>& reference, const EmbeddedData& e_read_data)
{
auto same_value = [](const auto& a, const auto& b) -> bool {
bool same = true;
for (size_t i = 0; i < a.size(); ++i) {
same &= (a[i] == b[i]);
}
return parallel::allReduceAnd(same);
};
REQUIRE_NOTHROW(dynamic_cast<const DataHandler<const SubItemValuePerItemVariant>&>(e_read_data.get()));
std::shared_ptr<const SubItemValuePerItemVariant> p_new_data_v =
dynamic_cast<const DataHandler<const SubItemValuePerItemVariant>&>(e_read_data.get()).data_ptr();
using SubItemValuePerItemT = SubItemValuePerItem<const DataType, ItemOfItemTypeT>;
SubItemValuePerItemT read_data = p_new_data_v->get<SubItemValuePerItemT>();
switch (reference.connectivity_ptr()->dimension()) {
case 1: {
REQUIRE(test_only::isSameConnectivity(dynamic_cast<const Connectivity<1>&>(*reference.connectivity_ptr()),
dynamic_cast<const Connectivity<1>&>(*read_data.connectivity_ptr())));
break;
}
case 2: {
REQUIRE(test_only::isSameConnectivity(dynamic_cast<const Connectivity<2>&>(*reference.connectivity_ptr()),
dynamic_cast<const Connectivity<2>&>(*read_data.connectivity_ptr())));
break;
}
case 3: {
REQUIRE(test_only::isSameConnectivity(dynamic_cast<const Connectivity<3>&>(*reference.connectivity_ptr()),
dynamic_cast<const Connectivity<3>&>(*read_data.connectivity_ptr())));
break;
}
default: {
throw UnexpectedError("invalid connectivity dimension");
}
}
REQUIRE(same_value(reference.arrayView(), read_data.arrayView()));
}
} // namespace test_only
TEST_CASE("checkpointing_SubItemValuePerItemVariant", "[utils/checkpointing]")
{
std::string tmp_dirname;
{
{
if (parallel::rank() == 0) {
tmp_dirname = [&]() -> std::string {
std::string temp_filename = std::filesystem::temp_directory_path() / "pugs_checkpointing_XXXXXX";
return std::string{mkdtemp(&temp_filename[0])};
}();
}
parallel::broadcast(tmp_dirname, 0);
}
std::filesystem::path path = tmp_dirname;
const std::string filename = path / "checkpoint.h5";
HighFive::FileAccessProps fapl;
fapl.add(HighFive::MPIOFileAccess{MPI_COMM_WORLD, MPI_INFO_NULL});
fapl.add(HighFive::MPIOCollectiveMetadata{});
HighFive::File file = HighFive::File(filename, HighFive::File::Truncate, fapl);
const size_t initial_connectivity_id = GlobalVariableManager::instance().getConnectivityId();
SECTION("Connectivity")
{
using R1 = TinyVector<1>;
using R2 = TinyVector<2>;
using R3 = TinyVector<3>;
using R1x1 = TinyMatrix<1>;
using R2x2 = TinyMatrix<2>;
using R3x3 = TinyMatrix<3>;
HighFive::Group checkpoint_group = file.createGroup("checkpoint");
HighFive::Group symbol_table_group = checkpoint_group.createGroup("symbol_table");
auto mesh_1d = MeshDataBaseForTests::get().unordered1DMesh()->get<Mesh<1>>();
NodeValuePerCell<bool> node_B_per_cell_1d{mesh_1d->connectivity()};
for (CellId cell_id = 0; cell_id < mesh_1d->numberOfCells(); ++cell_id) {
auto node_list = mesh_1d->connectivity().cellToNodeMatrix()[cell_id];
for (size_t i_node = 0; i_node < node_list.size(); ++i_node) {
node_B_per_cell_1d[cell_id][i_node] = (std::rand() / (RAND_MAX / mesh_1d->numberOfCells())) % 2;
}
}
NodeValuePerCell<uint64_t> node_N_per_cell_1d{mesh_1d->connectivity()};
for (CellId cell_id = 0; cell_id < mesh_1d->numberOfCells(); ++cell_id) {
auto node_list = mesh_1d->connectivity().cellToNodeMatrix()[cell_id];
for (size_t i_node = 0; i_node < node_list.size(); ++i_node) {
node_N_per_cell_1d[cell_id][i_node] = (std::rand() / (RAND_MAX / mesh_1d->numberOfCells()));
}
}
CellValuePerNode<int64_t> cell_Z_per_node_1d{mesh_1d->connectivity()};
for (NodeId node_id = 0; node_id < mesh_1d->numberOfNodes(); ++node_id) {
auto cell_list = mesh_1d->connectivity().nodeToCellMatrix()[node_id];
for (size_t i_cell = 0; i_cell < cell_list.size(); ++i_cell) {
cell_Z_per_node_1d[node_id][i_cell] =
100 * (std::rand() - RAND_MAX / 2.) / (RAND_MAX / mesh_1d->numberOfNodes());
}
}
CellValuePerNode<double> cell_R_per_node_1d{mesh_1d->connectivity()};
for (NodeId node_id = 0; node_id < mesh_1d->numberOfNodes(); ++node_id) {
auto cell_list = mesh_1d->connectivity().nodeToCellMatrix()[node_id];
for (size_t i_cell = 0; i_cell < cell_list.size(); ++i_cell) {
cell_R_per_node_1d[node_id][i_cell] = std::rand() / (1. * RAND_MAX / mesh_1d->numberOfNodes());
}
}
NodeValuePerCell<R1> node_R1_per_cell_1d{mesh_1d->connectivity()};
for (CellId cell_id = 0; cell_id < mesh_1d->numberOfCells(); ++cell_id) {
auto node_list = mesh_1d->connectivity().cellToNodeMatrix()[cell_id];
for (size_t i_node = 0; i_node < node_list.size(); ++i_node) {
node_R1_per_cell_1d[cell_id][i_node] = R1{std::rand() / (1. * RAND_MAX / mesh_1d->numberOfCells())};
}
}
CellValuePerNode<R2> cell_R2_per_node_1d{mesh_1d->connectivity()};
for (NodeId node_id = 0; node_id < mesh_1d->numberOfNodes(); ++node_id) {
auto cell_list = mesh_1d->connectivity().nodeToCellMatrix()[node_id];
for (size_t i_cell = 0; i_cell < cell_list.size(); ++i_cell) {
cell_R2_per_node_1d[node_id][i_cell] = R2{std::rand() / (1. * RAND_MAX / mesh_1d->numberOfNodes()),
std::rand() / (1. * RAND_MAX / mesh_1d->numberOfNodes())};
}
}
auto mesh_2d = MeshDataBaseForTests::get().hybrid2DMesh()->get<Mesh<2>>();
CellValuePerFace<R3> cell_R3_per_face_2d{mesh_2d->connectivity()};
for (FaceId face_id = 0; face_id < mesh_2d->numberOfFaces(); ++face_id) {
auto cell_list = mesh_2d->connectivity().faceToCellMatrix()[face_id];
for (size_t i_cell = 0; i_cell < cell_list.size(); ++i_cell) {
cell_R3_per_face_2d[face_id][i_cell] = R3{std::rand() / (1. * RAND_MAX / mesh_2d->numberOfFaces()),
std::rand() / (1. * RAND_MAX / mesh_2d->numberOfFaces()),
std::rand() / (1. * RAND_MAX / mesh_2d->numberOfFaces())};
}
}
FaceValuePerNode<R2x2> face_R2x2_per_node_2d{mesh_2d->connectivity()};
for (NodeId node_id = 0; node_id < mesh_2d->numberOfNodes(); ++node_id) {
auto face_list = mesh_2d->connectivity().nodeToFaceMatrix()[node_id];
for (size_t i_face = 0; i_face < face_list.size(); ++i_face) {
face_R2x2_per_node_2d[node_id][i_face] = R2x2{std::rand() / (1. * RAND_MAX / mesh_2d->numberOfNodes()),
std::rand() / (1. * RAND_MAX / mesh_2d->numberOfNodes()),
std::rand() / (1. * RAND_MAX / mesh_2d->numberOfNodes()),
std::rand() / (1. * RAND_MAX / mesh_2d->numberOfNodes())};
}
}
auto mesh_3d = MeshDataBaseForTests::get().hybrid3DMesh()->get<Mesh<3>>();
FaceValuePerEdge<R3> face_R3_per_edge_3d{mesh_3d->connectivity()};
for (EdgeId edge_id = 0; edge_id < mesh_3d->numberOfEdges(); ++edge_id) {
auto face_list = mesh_3d->connectivity().edgeToFaceMatrix()[edge_id];
for (size_t i_face = 0; i_face < face_list.size(); ++i_face) {
face_R3_per_edge_3d[edge_id][i_face] = R3{std::rand() / (1. * RAND_MAX / mesh_3d->numberOfEdges()),
std::rand() / (1. * RAND_MAX / mesh_3d->numberOfEdges()),
std::rand() / (1. * RAND_MAX / mesh_3d->numberOfEdges())};
}
}
EdgeValuePerFace<R1x1> edge_R1x1_per_face_3d{mesh_3d->connectivity()};
for (FaceId face_id = 0; face_id < mesh_3d->numberOfFaces(); ++face_id) {
auto edge_list = mesh_3d->connectivity().faceToEdgeMatrix()[face_id];
for (size_t i_edge = 0; i_edge < edge_list.size(); ++i_edge) {
edge_R1x1_per_face_3d[face_id][i_edge] = R1x1{std::rand() / (1. * RAND_MAX / mesh_3d->numberOfFaces())};
}
}
EdgeValuePerNode<R3x3> edge_R3x3_per_node_3d{mesh_3d->connectivity()};
for (NodeId node_id = 0; node_id < mesh_3d->numberOfNodes(); ++node_id) {
auto edge_list = mesh_3d->connectivity().nodeToEdgeMatrix()[node_id];
for (size_t i_edge = 0; i_edge < edge_list.size(); ++i_edge) {
edge_R3x3_per_node_3d[node_id][i_edge] = R3x3{std::rand() / (1. * RAND_MAX / mesh_3d->numberOfNodes()),
std::rand() / (1. * RAND_MAX / mesh_3d->numberOfNodes()),
std::rand() / (1. * RAND_MAX / mesh_3d->numberOfNodes()),
std::rand() / (1. * RAND_MAX / mesh_3d->numberOfNodes()),
std::rand() / (1. * RAND_MAX / mesh_3d->numberOfNodes()),
std::rand() / (1. * RAND_MAX / mesh_3d->numberOfNodes()),
std::rand() / (1. * RAND_MAX / mesh_3d->numberOfNodes()),
std::rand() / (1. * RAND_MAX / mesh_3d->numberOfNodes()),
std::rand() / (1. * RAND_MAX / mesh_3d->numberOfNodes())};
}
}
{ // Write
using DataHandlerT = DataHandler<const SubItemValuePerItemVariant>;
auto new_connectivity_1d = test_only::duplicateConnectivity(mesh_1d->connectivity());
NodeValuePerCell<const bool> node_B_per_cell_1d_new{*new_connectivity_1d, node_B_per_cell_1d.arrayView()};
CellValuePerNode<const int64_t> cell_Z_per_node_1d_new{*new_connectivity_1d, cell_Z_per_node_1d.arrayView()};
NodeValuePerCell<const uint64_t> node_N_per_cell_1d_new{*new_connectivity_1d, node_N_per_cell_1d.arrayView()};
CellValuePerNode<const double> cell_R_per_node_1d_new{*new_connectivity_1d, cell_R_per_node_1d.arrayView()};
NodeValuePerCell<const R1> node_R1_per_cell_1d_new{*new_connectivity_1d, node_R1_per_cell_1d.arrayView()};
CellValuePerNode<const R2> cell_R2_per_node_1d_new{*new_connectivity_1d, cell_R2_per_node_1d.arrayView()};
checkpointing::writeSubItemValuePerItemVariant("node_B_per_cell_1d",
EmbeddedData{std::make_shared<DataHandlerT>(
std::make_shared<const SubItemValuePerItemVariant>(
node_B_per_cell_1d_new))},
file, checkpoint_group, symbol_table_group);
checkpointing::writeSubItemValuePerItemVariant("node_N_per_cell_1d",
EmbeddedData{std::make_shared<DataHandlerT>(
std::make_shared<const SubItemValuePerItemVariant>(
node_N_per_cell_1d_new))},
file, checkpoint_group, symbol_table_group);
checkpointing::writeSubItemValuePerItemVariant("cell_Z_per_node_1d",
EmbeddedData{std::make_shared<DataHandlerT>(
std::make_shared<const SubItemValuePerItemVariant>(
cell_Z_per_node_1d_new))},
file, checkpoint_group, symbol_table_group);
checkpointing::writeSubItemValuePerItemVariant("cell_R_per_node_1d",
EmbeddedData{std::make_shared<DataHandlerT>(
std::make_shared<const SubItemValuePerItemVariant>(
cell_R_per_node_1d_new))},
file, checkpoint_group, symbol_table_group);
checkpointing::writeSubItemValuePerItemVariant("node_R1_per_cell_1d",
EmbeddedData{std::make_shared<DataHandlerT>(
std::make_shared<const SubItemValuePerItemVariant>(
node_R1_per_cell_1d_new))},
file, checkpoint_group, symbol_table_group);
checkpointing::writeSubItemValuePerItemVariant("cell_R2_per_node_1d",
EmbeddedData{std::make_shared<DataHandlerT>(
std::make_shared<const SubItemValuePerItemVariant>(
cell_R2_per_node_1d_new))},
file, checkpoint_group, symbol_table_group);
auto new_connectivity_2d = test_only::duplicateConnectivity(mesh_2d->connectivity());
CellValuePerFace<const R3> cell_R3_per_face_2d_new{*new_connectivity_2d, cell_R3_per_face_2d.arrayView()};
FaceValuePerNode<const R2x2> face_R2x2_per_node_2d_new{*new_connectivity_2d, face_R2x2_per_node_2d.arrayView()};
checkpointing::writeSubItemValuePerItemVariant("cell_R3_per_face_2d",
EmbeddedData{std::make_shared<DataHandlerT>(
std::make_shared<const SubItemValuePerItemVariant>(
cell_R3_per_face_2d_new))},
file, checkpoint_group, symbol_table_group);
checkpointing::writeSubItemValuePerItemVariant("face_R2x2_per_node_2d",
EmbeddedData{std::make_shared<DataHandlerT>(
std::make_shared<const SubItemValuePerItemVariant>(
face_R2x2_per_node_2d_new))},
file, checkpoint_group, symbol_table_group);
auto new_connectivity_3d = test_only::duplicateConnectivity(mesh_3d->connectivity());
FaceValuePerEdge<const R3> face_R3_per_edge_3d_new{*new_connectivity_3d, face_R3_per_edge_3d.arrayView()};
EdgeValuePerFace<const R1x1> edge_R1x1_per_face_3d_new{*new_connectivity_3d, edge_R1x1_per_face_3d.arrayView()};
EdgeValuePerNode<const R3x3> edge_R3x3_per_node_3d_new{*new_connectivity_3d, edge_R3x3_per_node_3d.arrayView()};
checkpointing::writeSubItemValuePerItemVariant("face_R3_per_edge_3d",
EmbeddedData{std::make_shared<DataHandlerT>(
std::make_shared<const SubItemValuePerItemVariant>(
face_R3_per_edge_3d_new))},
file, checkpoint_group, symbol_table_group);
checkpointing::writeSubItemValuePerItemVariant("edge_R1x1_per_face_3d",
EmbeddedData{std::make_shared<DataHandlerT>(
std::make_shared<const SubItemValuePerItemVariant>(
edge_R1x1_per_face_3d_new))},
file, checkpoint_group, symbol_table_group);
checkpointing::writeSubItemValuePerItemVariant("edge_R3x3_per_node_3d",
EmbeddedData{std::make_shared<DataHandlerT>(
std::make_shared<const SubItemValuePerItemVariant>(
edge_R3x3_per_node_3d_new))},
file, checkpoint_group, symbol_table_group);
HighFive::Group global_variables_group = checkpoint_group.createGroup("singleton/global_variables");
global_variables_group.createAttribute("connectivity_id",
GlobalVariableManager::instance().getConnectivityId());
global_variables_group.createAttribute("mesh_id", GlobalVariableManager::instance().getMeshId());
}
// reset to reuse after resuming
GlobalVariableManager::instance().setConnectivityId(initial_connectivity_id);
file.flush();
checkpointing::ResumingData::create();
checkpointing::ResumingData::instance().readData(checkpoint_group, nullptr);
GlobalVariableManager::instance().setConnectivityId(initial_connectivity_id);
{ // Read
auto e_cell_B_per_node_1d =
checkpointing::readSubItemValuePerItemVariant("node_B_per_cell_1d", symbol_table_group);
test_only::check_is_same(node_B_per_cell_1d, e_cell_B_per_node_1d);
auto e_cell_N_per_node_1d =
checkpointing::readSubItemValuePerItemVariant("node_N_per_cell_1d", symbol_table_group);
test_only::check_is_same(node_N_per_cell_1d, e_cell_N_per_node_1d);
auto e_node_Z_1d = checkpointing::readSubItemValuePerItemVariant("cell_Z_per_node_1d", symbol_table_group);
test_only::check_is_same(cell_Z_per_node_1d, e_node_Z_1d);
auto e_node_R_1d = checkpointing::readSubItemValuePerItemVariant("cell_R_per_node_1d", symbol_table_group);
test_only::check_is_same(cell_R_per_node_1d, e_node_R_1d);
auto e_cell_R1_1d = checkpointing::readSubItemValuePerItemVariant("node_R1_per_cell_1d", symbol_table_group);
test_only::check_is_same(node_R1_per_cell_1d, e_cell_R1_1d);
auto e_node_R2_1d = checkpointing::readSubItemValuePerItemVariant("cell_R2_per_node_1d", symbol_table_group);
test_only::check_is_same(cell_R2_per_node_1d, e_node_R2_1d);
auto e_face_R3_2d = checkpointing::readSubItemValuePerItemVariant("cell_R3_per_face_2d", symbol_table_group);
test_only::check_is_same(cell_R3_per_face_2d, e_face_R3_2d);
auto e_node_R2x2_2d =
checkpointing::readSubItemValuePerItemVariant("face_R2x2_per_node_2d", symbol_table_group);
test_only::check_is_same(face_R2x2_per_node_2d, e_node_R2x2_2d);
auto e_edge_R3_3d = checkpointing::readSubItemValuePerItemVariant("face_R3_per_edge_3d", symbol_table_group);
test_only::check_is_same(face_R3_per_edge_3d, e_edge_R3_3d);
auto e_face_R1x1_3d =
checkpointing::readSubItemValuePerItemVariant("edge_R1x1_per_face_3d", symbol_table_group);
test_only::check_is_same(edge_R1x1_per_face_3d, e_face_R1x1_3d);
auto e_node_R3x3_3d =
checkpointing::readSubItemValuePerItemVariant("edge_R3x3_per_node_3d", symbol_table_group);
test_only::check_is_same(edge_R3x3_per_node_3d, e_node_R3x3_3d);
}
checkpointing::ResumingData::destroy();
}
}
parallel::barrier();
if (parallel::rank() == 0) {
std::filesystem::remove_all(std::filesystem::path{tmp_dirname});
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment