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

Merge branch 'feature/mesh-based-ci' into 'develop'

Feature/mesh based ci

See merge request !61
parents f9b6ee5c 679bc4ba
Branches
Tags
1 merge request!61Feature/mesh based ci
......@@ -21,7 +21,7 @@ test:clang10-mpi-debug:
- mkdir -p build/clang10-debug-mpi
- cd build/clang10-debug-mpi
- CXX=clang++-10 CC=clang-10 cmake ../.. -DCMAKE_BUILD_TYPE=Debug
- make run_unit_tests
- make test
cache:
key: "${CI_COMMIT_REF_SLUG}-clang10-debug-mpi"
paths:
......
......@@ -21,7 +21,7 @@ test:clang10-mpi-release:
- mkdir -p build/clang10-release-mpi
- cd build/clang10-release-mpi
- CXX=clang++-10 CC=clang-10 cmake ../.. -DCMAKE_BUILD_TYPE=Release -DCLANG_FORMAT=/usr/bin/clang-format-10
- make run_unit_tests
- make test
cache:
key: "${CI_COMMIT_REF_SLUG}-clang10-release-mpi"
paths:
......
......@@ -21,7 +21,7 @@ test:gcc10-mpi-debug:
- mkdir -p build/gcc10-debug-mpi
- cd build/gcc10-debug-mpi
- CXX=g++-10 CC=gcc-10 cmake ../.. -DCMAKE_BUILD_TYPE=Debug
- make run_unit_tests
- make test
cache:
key: "${CI_COMMIT_REF_SLUG}-gcc10-debug-mpi"
paths:
......
......@@ -21,7 +21,7 @@ test:gcc10-mpi-release:
- mkdir -p build/gcc10-release-mpi
- cd build/gcc10-release-mpi
- CXX=g++-10 CC=gcc-10 cmake ../.. -DCMAKE_BUILD_TYPE=Release
- make run_unit_tests
- make test
cache:
key: "${CI_COMMIT_REF_SLUG}-gcc10-release-mpi"
paths:
......
......@@ -21,7 +21,7 @@ test:gcc10-seq-release:
- mkdir -p build/gcc10-release-seq
- cd build/gcc10-release-seq
- CXX=g++-10 CC=gcc-10 cmake ../.. -DCMAKE_BUILD_TYPE=Release
- make run_unit_tests
- make test
cache:
key: "${CI_COMMIT_REF_SLUG}-gcc10-release-seq"
paths:
......
......@@ -313,12 +313,50 @@ include("${CATCH_MODULE_PATH}/contrib/ParseAndAddCatchTests.cmake")
add_subdirectory("${CATCH_MODULE_PATH}")
add_subdirectory(tests)
enable_testing()
add_custom_target(run_unit_tests
COMMAND ${CMAKE_CTEST_COMMAND}
if(${PUGS_HAS_MPI})
set(MPIEXEC_OPTION_FLAGS --oversubscribe)
if (NOT "$ENV{GITLAB_CI}" STREQUAL "")
set(MPIEXEC_OPTION_FLAGS ${MPIEXEC_OPTION_FLAGS} --allow-run-as-root)
endif()
set(MPIEXEC_NUMPROC 3)
set(MPIEXEC_PATH_FLAG --path)
set(MPI_LAUNCHER ${MPIEXEC} ${MPIEXEC_NUMPROC_FLAG} ${MPIEXEC_NUMPROC} ${MPIEXEC_PATH_FLAG} ${PUGS_BINARY_DIR} ${MPIEXEC_OPTION_FLAGS})
endif()
add_custom_target(all_unit_tests
DEPENDS unit_tests mpi_unit_tests
COMMENT "Executing unit tests."
)
add_custom_target(check
DEPENDS test
)
add_custom_target(test
DEPENDS run_all_unit_tests
)
add_custom_target(run_all_unit_tests
DEPENDS run_mpi_unit_tests
)
if(PUGS_HAS_MPI)
set(RUN_MPI_UNIT_TESTS_COMMENT "Running mpi_unit_tests [using ${MPIEXEC_NUMPROC} procs]")
else()
set(RUN_MPI_UNIT_TESTS_COMMENT "Running mpi_unit_tests [sequentially]")
endif()
add_custom_target(run_mpi_unit_tests
COMMAND ${MPI_LAUNCHER} "${PUGS_BINARY_DIR}/mpi_unit_tests"
DEPENDS run_unit_tests
COMMENT ${RUN_MPI_UNIT_TESTS_COMMENT}
)
add_custom_target(run_unit_tests
COMMAND "${PUGS_BINARY_DIR}/unit_tests"
DEPENDS all_unit_tests
COMMENT "Running unit_tests"
)
# unit tests coverage
......@@ -364,16 +402,42 @@ if("${CMAKE_BUILD_TYPE}" STREQUAL "Coverage")
find_program(FASTCOV fastcov fastcov.py)
add_custom_target(coverage_unit_tests
ALL # in coverage mode we do coverage!
COMMAND "${PUGS_BINARY_DIR}/unit_tests"
COMMENT "Running unit_tests"
DEPENDS coverage_zero_counters
)
add_custom_target(coverage_mpi_unit_tests
ALL # in coverage mode we do coverage!
COMMAND ${MPI_LAUNCHER} "mpi_unit_tests"
COMMENT "Running mpi_unit_tests"
DEPENDS coverage_unit_tests
)
add_custom_target(coverage_run_all_unit_tests
ALL # in coverage mode we do coverage!
DEPENDS coverage_mpi_unit_tests
)
if (FASTCOV AND (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") AND (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER "9"))
add_custom_target(coverage
add_custom_target(coverage_zero_counters
ALL # in coverage mode we do coverage!
# zero all counters
COMMAND ${FASTCOV} -q -z --gcov "${GCOV_BIN}"
DEPENDS all_unit_tests
)
# Run tests
COMMAND ${CMAKE_CTEST_COMMAND}
add_custom_target(coverage
ALL # in coverage mode we do coverage!
COMMAND ${FASTCOV} -q --gcov "${GCOV_BIN}"
--include "${PUGS_SOURCE_DIR}/src"
......@@ -382,22 +446,25 @@ if("${CMAKE_BUILD_TYPE}" STREQUAL "Coverage")
COMMAND ${LCOV} --gcov "${GCOV_BIN}" --list coverage.info
DEPENDS unit_tests mpi_unit_tests
DEPENDS coverage_run_all_unit_tests
COMMENT "Running test coverage."
WORKING_DIRECTORY "${PUGS_BINARY_DIR}"
)
else()
add_custom_target(coverage
add_custom_target(coverage_zero_counters
ALL # in coverage mode we do coverage!
# Cleanup previously generated profiling data
COMMAND ${LCOV} -q --gcov "${GCOV_BIN}" --base-directory "${PUGS_BINARY_DIR}/src" --directory "${PUGS_BINARY_DIR}" --zerocounters
# Initialize profiling data with zero coverage for every instrumented line of the project
# This way the percentage of total lines covered will always be correct, even when not all source code files were loaded during the test(s)
COMMAND ${LCOV} -q --gcov "${GCOV_BIN}" --base-directory "${PUGS_BINARY_DIR}/src" --directory "${PUGS_BINARY_DIR}" --capture --initial --output-file coverage_base.info
# Run tests
COMMAND ${CMAKE_CTEST_COMMAND}
DEPENDS all_unit_tests
)
add_custom_target(coverage
# Collect data from executions
COMMAND ${LCOV} --gcov "${GCOV_BIN}" --base-directory "${PUGS_BINARY_DIR}/src" --directory "${PUGS_BINARY_DIR}" --capture --output-file coverage_ctest.info
# Combine base and ctest results
......@@ -412,7 +479,7 @@ if("${CMAKE_BUILD_TYPE}" STREQUAL "Coverage")
COMMAND ${LCOV} --gcov "${GCOV_BIN}" --list coverage.info
DEPENDS unit_tests mpi_unit_tests
DEPENDS coverage_run_all_unit_tests
COMMENT "Running test coverage."
WORKING_DIRECTORY "${PUGS_BINARY_DIR}"
)
......
......@@ -10,5 +10,6 @@
#cmakedefine SYSTEM_IS_WINDOWS
#define PUGS_BUILD_TYPE "@CMAKE_BUILD_TYPE@"
#define PUGS_BINARY_DIR "@PUGS_BINARY_DIR@"
#endif // PUGS_CONFIG_HPP
......@@ -89,7 +89,11 @@ add_executable (mpi_unit_tests
mpi_test_Messenger.cpp
)
add_library(test_Pugs_MeshDataBase
MeshDataBaseForTests.cpp)
target_link_libraries (unit_tests
test_Pugs_MeshDataBase
PugsLanguage
PugsLanguageAST
PugsLanguageModules
......@@ -108,6 +112,7 @@ target_link_libraries (unit_tests
)
target_link_libraries (mpi_unit_tests
test_Pugs_MeshDataBase
PugsUtils
PugsAlgebra
PugsMesh
......
#include <MeshDataBaseForTests.hpp>
#include <mesh/CartesianMeshBuilder.hpp>
#include <mesh/Connectivity.hpp>
#include <utils/PugsAssert.hpp>
const MeshDataBaseForTests* MeshDataBaseForTests::m_instance = nullptr;
MeshDataBaseForTests::MeshDataBaseForTests()
{
m_cartesian_1d_mesh = CartesianMeshBuilder{TinyVector<1>{-1}, TinyVector<1>{3}, TinyVector<1, size_t>{23}}.mesh();
m_cartesian_2d_mesh =
CartesianMeshBuilder{TinyVector<2>{0, -1}, TinyVector<2>{3, 2}, TinyVector<2, size_t>{6, 7}}.mesh();
m_cartesian_3d_mesh =
CartesianMeshBuilder{TinyVector<3>{0, 1, 0}, TinyVector<3>{2, -1, 3}, TinyVector<3, size_t>{6, 7, 4}}.mesh();
}
const MeshDataBaseForTests&
MeshDataBaseForTests::get()
{
return *m_instance;
}
void
MeshDataBaseForTests::create()
{
Assert(m_instance == nullptr);
m_instance = new MeshDataBaseForTests();
}
void
MeshDataBaseForTests::destroy()
{
Assert(m_instance != nullptr);
delete m_instance;
m_instance = nullptr;
}
template <size_t Dimension>
const Mesh<Connectivity<Dimension>>&
MeshDataBaseForTests::cartesianMesh() const
{
if constexpr (Dimension == 1) {
return dynamic_cast<const Mesh<Connectivity<Dimension>>&>(*m_cartesian_1d_mesh);
} else if constexpr (Dimension == 2) {
return dynamic_cast<const Mesh<Connectivity<Dimension>>&>(*m_cartesian_2d_mesh);
} else if constexpr (Dimension == 3) {
return dynamic_cast<const Mesh<Connectivity<Dimension>>&>(*m_cartesian_3d_mesh);
}
}
template const Mesh<Connectivity<1>>& MeshDataBaseForTests::cartesianMesh<1>() const;
template const Mesh<Connectivity<2>>& MeshDataBaseForTests::cartesianMesh<2>() const;
template const Mesh<Connectivity<3>>& MeshDataBaseForTests::cartesianMesh<3>() const;
#ifndef MESH_DATA_BASE_FOR_TESTS_HPP
#define MESH_DATA_BASE_FOR_TESTS_HPP
#include <mesh/IMesh.hpp>
template <size_t Dimension>
class Connectivity;
template <typename ConnectivityT>
class Mesh;
#include <memory>
class MeshDataBaseForTests
{
private:
explicit MeshDataBaseForTests();
static const MeshDataBaseForTests* m_instance;
std::shared_ptr<const IMesh> m_cartesian_1d_mesh;
std::shared_ptr<const IMesh> m_cartesian_2d_mesh;
std::shared_ptr<const IMesh> m_cartesian_3d_mesh;
public:
template <size_t Dimension>
const Mesh<Connectivity<Dimension>>& cartesianMesh() const;
static const MeshDataBaseForTests& get();
static void create();
static void destroy();
~MeshDataBaseForTests() = default;
};
#endif // MESH_DATA_BASE_FOR_TESTS_HPP
......@@ -3,9 +3,17 @@
#include <Kokkos_Core.hpp>
#include <mesh/DiamondDualConnectivityManager.hpp>
#include <mesh/DiamondDualMeshManager.hpp>
#include <mesh/MeshDataManager.hpp>
#include <mesh/SynchronizerManager.hpp>
#include <utils/Messenger.hpp>
#include <utils/pugs_config.hpp>
#include <MeshDataBaseForTests.hpp>
#include <cstdlib>
#include <filesystem>
int
main(int argc, char* argv[])
......@@ -13,19 +21,69 @@ main(int argc, char* argv[])
parallel::Messenger::create(argc, argv);
Kokkos::initialize({4, -1, -1, true});
// Disable outputs from tested classes to the standard output
std::cout.setstate(std::ios::badbit);
const std::string output_base_name{"mpi_test_rank_"};
std::filesystem::path parallel_output(std::string{PUGS_BINARY_DIR});
std::filesystem::path gcov_prefix = [&]() -> std::filesystem::path {
std::string template_temp_dir = std::filesystem::temp_directory_path() / "pugs_gcov_XXXXXX";
return std::filesystem::path{mkdtemp(&template_temp_dir[0])};
}();
if (parallel::rank() != 0) {
setenv("GCOV_PREFIX", "/dev/null", 1);
}
Catch::Session session;
int result = session.applyCommandLine(argc, argv);
if (result == 0) {
const auto& config = session.config();
if (config.listReporters() or config.listTags() or config.listTestNamesOnly() or config.listTests()) {
if (parallel::rank() == 0) {
session.run();
}
} else {
if (parallel::rank() != 0) {
// Disable outputs for ranks != 0
setenv("GCOV_PREFIX", gcov_prefix.string().c_str(), 1);
parallel_output /= output_base_name + std::to_string(parallel::rank());
Catch::ConfigData data{session.configData()};
data.outputFilename = parallel_output.string();
session.useConfigData(data);
}
// Disable outputs from tested classes to the standard output
std::cout.setstate(std::ios::badbit);
SynchronizerManager::create();
MeshDataManager::create();
DiamondDualConnectivityManager::create();
DiamondDualMeshManager::create();
MeshDataBaseForTests::create();
if (parallel::rank() == 0) {
if (parallel::size() > 1) {
session.config().stream() << rang::fgB::green << "Other rank outputs are stored in corresponding files"
<< rang::style::reset << '\n';
for (size_t i_rank = 1; i_rank < parallel::size(); ++i_rank) {
std::filesystem::path parallel_output(std::string{PUGS_BINARY_DIR});
parallel_output /= output_base_name + std::to_string(i_rank);
session.config().stream() << " - " << rang::fg::green << parallel_output.parent_path().string()
<< parallel_output.preferred_separator << rang::style::reset << rang::fgB::green
<< parallel_output.filename().string() << rang::style::reset << '\n';
}
}
}
result = session.run();
MeshDataBaseForTests::destroy();
DiamondDualMeshManager::destroy();
DiamondDualConnectivityManager::destroy();
MeshDataManager::destroy();
SynchronizerManager::destroy();
}
}
Kokkos::finalize();
......
......@@ -3,21 +3,51 @@
#include <Kokkos_Core.hpp>
#include <mesh/DiamondDualConnectivityManager.hpp>
#include <mesh/DiamondDualMeshManager.hpp>
#include <mesh/MeshDataManager.hpp>
#include <mesh/SynchronizerManager.hpp>
#include <utils/Messenger.hpp>
#include <MeshDataBaseForTests.hpp>
int
main(int argc, char* argv[])
{
parallel::Messenger::create(argc, argv);
Kokkos::initialize({4, -1, -1, true});
Catch::Session session;
int result = session.applyCommandLine(argc, argv);
if (result == 0) {
const auto& config = session.config();
if (config.listReporters() or config.listTags() or config.listTestNamesOnly() or config.listTests()) {
result = session.run();
} else {
// Disable outputs from tested classes to the standard output
std::cout.setstate(std::ios::badbit);
SynchronizerManager::create();
MeshDataManager::create();
DiamondDualConnectivityManager::create();
DiamondDualMeshManager::create();
MeshDataBaseForTests::create();
result = session.run();
MeshDataBaseForTests::destroy();
DiamondDualMeshManager::destroy();
DiamondDualConnectivityManager::destroy();
MeshDataManager::destroy();
SynchronizerManager::destroy();
}
}
Kokkos::finalize();
parallel::Messenger::destroy();
return result;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment