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

Add tests for Table checkpointing

parent d7c092cd
No related branches found
No related tags found
1 merge request!199Integrate checkpointing
......@@ -24,11 +24,11 @@ readTable(const HighFive::Group& group, const std::string& name)
const std::vector<size_t> number_of_rows_per_rank =
dataset.getAttribute("number_of_rows_per_rank").read<std::vector<size_t>>();
std::vector<size_t> offset{0, 0ul};
std::vector<size_t> offset = {0, 0ul};
for (size_t i = 0; i < parallel::rank(); ++i) {
offset[0] += number_of_rows_per_rank[i] * number_of_columns;
offset[0] += number_of_rows_per_rank[i] * number_of_columns; // LCOV_EXCL_LINE
}
std::vector<size_t> count{number_of_rows_per_rank[parallel::rank()]};
std::vector<size_t> count = {number_of_rows_per_rank[parallel::rank()] * number_of_columns};
Table<DataType> table(number_of_rows_per_rank[parallel::rank()], number_of_columns);
if constexpr (std::is_same_v<CellType, data_type>) {
......
......@@ -22,7 +22,7 @@ write(HighFive::Group& group, const std::string& name, const Array<DataType>& ar
size_t current_offset = 0;
for (size_t i = 0; i < parallel::rank(); ++i) {
current_offset += size_per_rank[i];
current_offset += size_per_rank[i]; // LCOV_EXCL_LINE
}
std::vector<size_t> offset{current_offset, 0ul};
std::vector<size_t> count{array.size()};
......
......@@ -3,6 +3,8 @@
#include <utils/HighFivePugsUtils.hpp>
#include <mesh/CellType.hpp>
#include <mesh/ItemId.hpp>
#include <utils/Messenger.hpp>
#include <utils/Table.hpp>
......@@ -14,9 +16,11 @@ PUGS_INLINE void
write(HighFive::Group& group, const std::string& name, const Table<DataType>& table)
{
const size_t number_of_columns = parallel::allReduceMax(table.numberOfColumns());
// LCOV_EXCL_START
if ((table.numberOfColumns() != number_of_columns) and (table.numberOfRows() > 0)) {
throw UnexpectedError("table must have same number of columns in parallel");
}
// LCOV_EXCL_STOP
auto get_address = [](auto& t) { return (t.numberOfRows() * t.numberOfColumns() > 0) ? &(t(0, 0)) : nullptr; };
......@@ -25,7 +29,7 @@ write(HighFive::Group& group, const std::string& name, const Table<DataType>& ta
size_t current_offset = 0;
for (size_t i = 0; i < parallel::rank(); ++i) {
current_offset += number_of_rows_per_rank[i] * table.numberOfColumns();
current_offset += number_of_rows_per_rank[i] * table.numberOfColumns(); // LCOV_EXCL_LINE
}
std::vector<size_t> offset{current_offset, 0ul};
std::vector<size_t> count{table.numberOfRows() * table.numberOfColumns()};
......@@ -39,9 +43,24 @@ write(HighFive::Group& group, const std::string& name, const Table<DataType>& ta
auto xfer_props = HighFive::DataTransferProps{};
xfer_props.add(HighFive::UseCollectiveIO{});
HighFive::DataSet dataset =
group.createDataSet<data_type>(name, HighFive::DataSpace{std::vector<size_t>{global_size}}, properties);
HighFive::DataSet dataset;
if constexpr (std::is_same_v<CellType, data_type>) {
using base_type = std::underlying_type_t<CellType>;
dataset = group.createDataSet<base_type>(name, HighFive::DataSpace{std::vector<size_t>{global_size}}, properties);
dataset.select(offset, count)
.template write_raw<base_type>(reinterpret_cast<const base_type*>(get_address(table)), xfer_props);
} else if constexpr ((std::is_same_v<CellId, data_type>) or (std::is_same_v<FaceId, data_type>) or
(std::is_same_v<EdgeId, data_type>) or (std::is_same_v<NodeId, data_type>)) {
using base_type = typename data_type::base_type;
dataset = group.createDataSet<base_type>(name, HighFive::DataSpace{std::vector<size_t>{global_size}}, properties);
dataset.select(offset, count)
.template write_raw<base_type>(reinterpret_cast<const base_type*>(get_address(table)), xfer_props);
} else {
dataset = group.createDataSet<data_type>(name, HighFive::DataSpace{std::vector<size_t>{global_size}}, properties);
dataset.select(offset, count).template write_raw<data_type>(get_address(table), xfer_props);
}
std::vector<size_t> number_of_rows_per_rank_vector;
for (size_t i = 0; i < number_of_rows_per_rank.size(); ++i) {
......
......@@ -171,6 +171,7 @@ if(PUGS_HAS_HDF5)
test_checkpointing_ItemType.cpp
test_checkpointing_IWriter.cpp
test_checkpointing_IZoneDescriptor.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 <utils/checkpointing/ReadTable.hpp>
#include <utils/checkpointing/WriteTable.hpp>
#include <filesystem>
// clazy:excludeall=non-pod-global-static
TEST_CASE("checkpointing_Table", "[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);
SECTION("Table")
{
HighFive::Group checkpoint_group = file.createGroup("checkpoint_group");
HighFive::Group useless_group;
Table<CellType> cell_type_table{19 + 3 * parallel::rank(), 3};
cell_type_table.fill(CellType::Line);
for (size_t i = 0; i < 10; ++i) {
for (size_t j = 0; j < cell_type_table.numberOfColumns(); ++j) {
cell_type_table[std::rand() / (RAND_MAX / cell_type_table.numberOfRows())][j] = CellType::Line;
cell_type_table[std::rand() / (RAND_MAX / cell_type_table.numberOfRows())][j] = CellType::Triangle;
cell_type_table[std::rand() / (RAND_MAX / cell_type_table.numberOfRows())][j] = CellType::Quadrangle;
cell_type_table[std::rand() / (RAND_MAX / cell_type_table.numberOfRows())][j] = CellType::Polygon;
cell_type_table[std::rand() / (RAND_MAX / cell_type_table.numberOfRows())][j] = CellType::Tetrahedron;
cell_type_table[std::rand() / (RAND_MAX / cell_type_table.numberOfRows())][j] = CellType::Diamond;
cell_type_table[std::rand() / (RAND_MAX / cell_type_table.numberOfRows())][j] = CellType::Hexahedron;
cell_type_table[std::rand() / (RAND_MAX / cell_type_table.numberOfRows())][j] = CellType::Prism;
cell_type_table[std::rand() / (RAND_MAX / cell_type_table.numberOfRows())][j] = CellType::Pyramid;
}
}
checkpointing::write(checkpoint_group, "cell_type_table", cell_type_table);
Table<CellId> cell_id_table{27 + 2 * parallel::rank(), 3};
cell_id_table.fill(0);
for (size_t i = 0; i < 20; ++i) {
for (size_t j = 0; j < cell_id_table.numberOfColumns(); ++j) {
cell_id_table[std::rand() / (RAND_MAX / cell_id_table.numberOfRows())][j] =
std::rand() / (RAND_MAX / cell_id_table.numberOfRows());
}
}
checkpointing::write(checkpoint_group, "cell_id_table", cell_id_table);
Table<FaceId> face_id_table{29 + 2 * parallel::rank(), 2};
face_id_table.fill(0);
for (size_t i = 0; i < 20; ++i) {
for (size_t j = 0; j < face_id_table.numberOfColumns(); ++j) {
face_id_table[std::rand() / (RAND_MAX / face_id_table.numberOfRows())][j] =
std::rand() / (RAND_MAX / face_id_table.numberOfRows());
}
}
checkpointing::write(checkpoint_group, "face_id_table", face_id_table);
Table<EdgeId> edge_id_table{13 + 2 * parallel::rank(), 4};
edge_id_table.fill(0);
for (size_t i = 0; i < 20; ++i) {
for (size_t j = 0; j < edge_id_table.numberOfColumns(); ++j) {
edge_id_table[std::rand() / (RAND_MAX / edge_id_table.numberOfRows())][j] =
std::rand() / (RAND_MAX / edge_id_table.numberOfRows());
}
}
checkpointing::write(checkpoint_group, "edge_id_table", edge_id_table);
Table<NodeId> node_id_table{22 + 2 * parallel::rank(), 3};
node_id_table.fill(0);
for (size_t i = 0; i < 20; ++i) {
for (size_t j = 0; j < node_id_table.numberOfColumns(); ++j) {
node_id_table[std::rand() / (RAND_MAX / node_id_table.numberOfRows())][j] =
std::rand() / (RAND_MAX / node_id_table.numberOfRows());
}
}
checkpointing::write(checkpoint_group, "node_id_table", node_id_table);
Table<double> double_table{16 + 3 * parallel::rank(), 5};
double_table.fill(0);
for (size_t i = 0; i < 20; ++i) {
for (size_t j = 0; j < double_table.numberOfColumns(); ++j) {
double_table[std::rand() / (RAND_MAX / double_table.numberOfRows())][j] =
(1. * std::rand()) / (1. * RAND_MAX / double_table.numberOfRows());
}
}
checkpointing::write(checkpoint_group, "double_table", double_table);
file.flush();
auto is_same = [](const auto& a, const auto& b) {
bool same = true;
for (size_t i = 0; i < a.numberOfRows(); ++i) {
for (size_t j = 0; j < a.numberOfColumns(); ++j) {
if (a(i, j) != b(i, j)) {
same = false;
}
}
}
return parallel::allReduceAnd(same);
};
Table read_cell_type_table = checkpointing::readTable<CellType>(checkpoint_group, "cell_type_table");
REQUIRE(is_same(cell_type_table, read_cell_type_table));
Table read_cell_id_table = checkpointing::readTable<CellId>(checkpoint_group, "cell_id_table");
REQUIRE(is_same(cell_id_table, read_cell_id_table));
Table read_face_id_table = checkpointing::readTable<FaceId>(checkpoint_group, "face_id_table");
REQUIRE(is_same(face_id_table, read_face_id_table));
Table read_edge_id_table = checkpointing::readTable<EdgeId>(checkpoint_group, "edge_id_table");
REQUIRE(is_same(edge_id_table, read_edge_id_table));
Table read_node_id_table = checkpointing::readTable<NodeId>(checkpoint_group, "node_id_table");
REQUIRE(is_same(node_id_table, read_node_id_table));
Table read_double_table = checkpointing::readTable<double>(checkpoint_group, "double_table");
REQUIRE(is_same(double_table, read_double_table));
}
}
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