From 36e3daf679b0cdca547b95dcaf14b6d5bbeb6071 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Del=20Pino?= <stephane.delpino44@gmail.com> Date: Wed, 31 Mar 2021 15:40:52 +0200 Subject: [PATCH] Add ItemValueUtils tests --- src/mesh/ItemValueUtils.hpp | 12 +- tests/CMakeLists.txt | 1 + tests/test_ItemValueUtils.cpp | 248 ++++++++++++++++++++++++++++++++++ 3 files changed, 259 insertions(+), 2 deletions(-) create mode 100644 tests/test_ItemValueUtils.cpp diff --git a/src/mesh/ItemValueUtils.hpp b/src/mesh/ItemValueUtils.hpp index a1039fdbd..831564e9c 100644 --- a/src/mesh/ItemValueUtils.hpp +++ b/src/mesh/ItemValueUtils.hpp @@ -50,7 +50,8 @@ min(const ItemValue<DataType, item_type, ConnectivityPtr>& item_value) join(volatile data_type& dst, const volatile data_type& src) const { if (src < dst) { - dst = src; + // cannot be reached if initial value is the min + dst = src; // LCOV_EXCL_LINE } } @@ -83,9 +84,11 @@ min(const ItemValue<DataType, item_type, ConnectivityPtr>& item_value) return connectivity_3d.isOwned<item_type>(); break; } + // LCOV_EXCL_START default: { throw UnexpectedError("unexpected dimension"); } + // LCOV_EXCL_STOP } }(*item_value.connectivity_ptr())) { @@ -139,7 +142,8 @@ max(const ItemValue<DataType, item_type, ConnectivityPtr>& item_value) join(volatile data_type& dst, const volatile data_type& src) const { if (src > dst) { - dst = src; + // cannot be reached if initial value is the max + dst = src; // LCOV_EXCL_LINE } } @@ -172,9 +176,11 @@ max(const ItemValue<DataType, item_type, ConnectivityPtr>& item_value) return connectivity_3d.isOwned<item_type>(); break; } + // LCOV_EXCL_START default: { throw UnexpectedError("unexpected dimension"); } + // LCOV_EXCL_STOP } }(*item_value.connectivity_ptr())) { @@ -264,9 +270,11 @@ sum(const ItemValue<DataType, item_type>& item_value) return connectivity_3d.isOwned<item_type>(); break; } + // LCOV_EXCL_START default: { throw UnexpectedError("unexpected dimension"); } + // LCOV_EXCL_STOP } }(*item_value.connectivity_ptr())) { diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 8cd540c76..2fc30ddd2 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -101,6 +101,7 @@ add_executable (mpi_unit_tests test_Messenger.cpp test_Partitioner.cpp test_ItemValue.cpp + test_ItemValueUtils.cpp ) add_library(test_Pugs_MeshDataBase diff --git a/tests/test_ItemValueUtils.cpp b/tests/test_ItemValueUtils.cpp new file mode 100644 index 000000000..73989f3d0 --- /dev/null +++ b/tests/test_ItemValueUtils.cpp @@ -0,0 +1,248 @@ +#include <catch2/catch_test_macros.hpp> +#include <catch2/matchers/catch_matchers_all.hpp> + +#include <MeshDataBaseForTests.hpp> +#include <mesh/Connectivity.hpp> +#include <mesh/ItemValue.hpp> +#include <mesh/ItemValueUtils.hpp> +#include <mesh/Mesh.hpp> +#include <utils/Messenger.hpp> + +// Instantiate to ensure full coverage is performed +template class ItemValue<int, ItemType::cell>; + +// clazy:excludeall=non-pod-global-static + +TEST_CASE("ItemValueUtils", "[mesh]") +{ + SECTION("Synchronize") + { + const Mesh<Connectivity<2>>& mesh_2d = MeshDataBaseForTests::get().cartesianMesh<2>(); + const Connectivity<2>& connectivity = mesh_2d.connectivity(); + + WeakFaceValue<int> weak_face_value{connectivity}; + + weak_face_value.fill(parallel::rank()); + + FaceValue<const int> face_value{weak_face_value}; + + REQUIRE(face_value.connectivity_ptr() == weak_face_value.connectivity_ptr()); + + { // before synchronization + auto face_owner = connectivity.faceOwner(); + auto face_is_owned = connectivity.faceIsOwned(); + + for (FaceId i_face = 0; i_face < mesh_2d.numberOfFaces(); ++i_face) { + if (face_is_owned[i_face]) { + REQUIRE(face_owner[i_face] == face_value[i_face]); + } else { + REQUIRE(face_owner[i_face] != face_value[i_face]); + } + } + } + + synchronize(weak_face_value); + + { // after synchronization + auto face_owner = connectivity.faceOwner(); + auto face_is_owned = connectivity.faceIsOwned(); + + for (FaceId i_face = 0; i_face < mesh_2d.numberOfFaces(); ++i_face) { + REQUIRE(face_owner[i_face] == face_value[i_face]); + } + } + } + + SECTION("min") + { + SECTION("1D") + { + const Mesh<Connectivity<1>>& mesh_1d = MeshDataBaseForTests::get().cartesianMesh<1>(); + const Connectivity<1>& connectivity = mesh_1d.connectivity(); + + CellValue<int> cell_value{connectivity}; + cell_value.fill(-1); + + auto cell_is_owned = connectivity.cellIsOwned(); + parallel_for( + mesh_1d.numberOfCells(), PUGS_LAMBDA(CellId cell_id) { + if (cell_is_owned[cell_id]) { + cell_value[cell_id] = 10 + parallel::rank(); + } + }); + + REQUIRE(min(cell_value) == 10); + } + + SECTION("2D") + { + const Mesh<Connectivity<2>>& mesh_2d = MeshDataBaseForTests::get().cartesianMesh<2>(); + const Connectivity<2>& connectivity = mesh_2d.connectivity(); + + CellValue<int> cell_value{connectivity}; + cell_value.fill(-1); + + auto cell_is_owned = connectivity.cellIsOwned(); + parallel_for( + mesh_2d.numberOfCells(), PUGS_LAMBDA(CellId cell_id) { + if (cell_is_owned[cell_id]) { + cell_value[cell_id] = 10 + parallel::rank(); + } + }); + + REQUIRE(min(cell_value) == 10); + } + + SECTION("3D") + { + const Mesh<Connectivity<3>>& mesh_3d = MeshDataBaseForTests::get().cartesianMesh<3>(); + const Connectivity<3>& connectivity = mesh_3d.connectivity(); + + CellValue<int> cell_value{connectivity}; + cell_value.fill(-1); + + auto cell_is_owned = connectivity.cellIsOwned(); + parallel_for( + mesh_3d.numberOfCells(), PUGS_LAMBDA(CellId cell_id) { + if (cell_is_owned[cell_id]) { + cell_value[cell_id] = 10 + parallel::rank(); + } + }); + + REQUIRE(min(cell_value) == 10); + } + } + + SECTION("max") + { + SECTION("1D") + { + const Mesh<Connectivity<1>>& mesh_1d = MeshDataBaseForTests::get().cartesianMesh<1>(); + const Connectivity<1>& connectivity = mesh_1d.connectivity(); + + CellValue<size_t> cell_value{connectivity}; + cell_value.fill(std::numeric_limits<size_t>::max()); + + auto cell_is_owned = connectivity.cellIsOwned(); + parallel_for( + mesh_1d.numberOfCells(), PUGS_LAMBDA(CellId cell_id) { + if (cell_is_owned[cell_id]) { + cell_value[cell_id] = parallel::rank() + 1; + } + }); + + REQUIRE(max(cell_value) == parallel::size()); + } + + SECTION("2D") + { + const Mesh<Connectivity<2>>& mesh_2d = MeshDataBaseForTests::get().cartesianMesh<2>(); + const Connectivity<2>& connectivity = mesh_2d.connectivity(); + + CellValue<size_t> cell_value{connectivity}; + cell_value.fill(std::numeric_limits<size_t>::max()); + + auto cell_is_owned = connectivity.cellIsOwned(); + parallel_for( + mesh_2d.numberOfCells(), PUGS_LAMBDA(CellId cell_id) { + if (cell_is_owned[cell_id]) { + cell_value[cell_id] = parallel::rank() + 1; + } + }); + + REQUIRE(max(cell_value) == parallel::size()); + } + + SECTION("3D") + { + const Mesh<Connectivity<3>>& mesh_3d = MeshDataBaseForTests::get().cartesianMesh<3>(); + const Connectivity<3>& connectivity = mesh_3d.connectivity(); + + CellValue<size_t> cell_value{connectivity}; + cell_value.fill(std::numeric_limits<size_t>::max()); + + auto cell_is_owned = connectivity.cellIsOwned(); + parallel_for( + mesh_3d.numberOfCells(), PUGS_LAMBDA(CellId cell_id) { + if (cell_is_owned[cell_id]) { + cell_value[cell_id] = parallel::rank() + 1; + } + }); + + REQUIRE(max(cell_value) == parallel::size()); + } + } + + SECTION("sum") + { + SECTION("1D") + { + const Mesh<Connectivity<1>>& mesh_1d = MeshDataBaseForTests::get().cartesianMesh<1>(); + const Connectivity<1>& connectivity = mesh_1d.connectivity(); + + CellValue<size_t> cell_value{connectivity}; + cell_value.fill(5); + + auto cell_is_owned = connectivity.cellIsOwned(); + + const size_t global_number_of_cells = [&] { + size_t number_of_cells = 0; + for (CellId cell_id = 0; cell_id < cell_is_owned.size(); ++cell_id) { + number_of_cells += cell_is_owned[cell_id]; + } + return parallel::allReduceSum(number_of_cells); + }(); + + REQUIRE(sum(cell_value) == 5 * global_number_of_cells); + } + + SECTION("2D") + { + const Mesh<Connectivity<2>>& mesh_2d = MeshDataBaseForTests::get().cartesianMesh<2>(); + const Connectivity<2>& connectivity = mesh_2d.connectivity(); + + FaceValue<size_t> face_value{connectivity}; + face_value.fill(2); + + auto face_is_owned = connectivity.faceIsOwned(); + + const size_t global_number_of_faces = [&] { + size_t number_of_faces = 0; + for (FaceId face_id = 0; face_id < face_is_owned.size(); ++face_id) { + number_of_faces += face_is_owned[face_id]; + } + return parallel::allReduceSum(number_of_faces); + }(); + + REQUIRE(sum(face_value) == 2 * global_number_of_faces); + } + + SECTION("3D") + { + const Mesh<Connectivity<3>>& mesh_3d = MeshDataBaseForTests::get().cartesianMesh<3>(); + const Connectivity<3>& connectivity = mesh_3d.connectivity(); + + NodeValue<size_t> node_value{connectivity}; + node_value.fill(3); + + auto node_is_owned = connectivity.nodeIsOwned(); + + const size_t global_number_of_nodes = [&] { + size_t number_of_nodes = 0; + for (NodeId node_id = 0; node_id < node_is_owned.size(); ++node_id) { + number_of_nodes += node_is_owned[node_id]; + } + return parallel::allReduceSum(number_of_nodes); + }(); + + REQUIRE(sum(node_value) == 3 * global_number_of_nodes); + } + } + +#ifndef NDEBUG + SECTION("checking for bounds violation") + { + // REQUIRE_THROWS_AS(a[10], AssertError); + } +#endif // NDEBUG +} -- GitLab