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

Add simple tests for ExecutionStatManager

parent 17c94219
No related branches found
No related tags found
1 merge request!199Integrate checkpointing
...@@ -44,7 +44,7 @@ ExecutionStatManager::_prettyPrintTime(double time_in_seconds) const ...@@ -44,7 +44,7 @@ ExecutionStatManager::_prettyPrintTime(double time_in_seconds) const
} }
void void
ExecutionStatManager::_printMaxResidentMemory() const ExecutionStatManager::_printMaxResidentMemory(std::ostream& os) const
{ {
class Memory class Memory
{ {
...@@ -85,42 +85,39 @@ ExecutionStatManager::_printMaxResidentMemory() const ...@@ -85,42 +85,39 @@ ExecutionStatManager::_printMaxResidentMemory() const
}; };
Memory memory; Memory memory;
std::cout << "Memory: " << rang::style::bold << Memory{parallel::allReduceSum(memory.value())}.prettyPrint() os << "Memory: " << rang::style::bold << Memory{parallel::allReduceSum(memory.value())}.prettyPrint()
<< rang::style::reset; << rang::style::reset;
if (parallel::size() > 1) { os << " (over " << parallel::size() << " processes)";
std::cout << " (over " << parallel::size() << " processes)"; os << " Avg: " << rang::style::bold << Memory{parallel::allReduceSum(memory.value()) / parallel::size()}.prettyPrint()
std::cout << " Avg: " << rang::style::bold
<< Memory{parallel::allReduceSum(memory.value()) / parallel::size()}.prettyPrint() << rang::style::reset;
std::cout << " Min: " << rang::style::bold << Memory{parallel::allReduceMin(memory.value())}.prettyPrint()
<< rang::style::reset; << rang::style::reset;
std::cout << " Max: " << rang::style::bold << Memory{parallel::allReduceMax(memory.value())}.prettyPrint() os << " Min: " << rang::style::bold << Memory{parallel::allReduceMin(memory.value())}.prettyPrint()
<< rang::style::reset; << rang::style::reset;
} os << " Max: " << rang::style::bold << Memory{parallel::allReduceMax(memory.value())}.prettyPrint()
std::cout << '\n'; << rang::style::reset;
os << '\n';
} }
void void
ExecutionStatManager::_printElapseTime() const ExecutionStatManager::_printElapseTime(std::ostream& os) const
{ {
const double elapse_time = m_instance->m_elapse_time.seconds(); const double elapse_time = m_instance->m_elapse_time.seconds();
std::cout << "Execution: " << rang::style::bold << elapse_time << 's' << rang::style::reset; os << "Execution: " << rang::style::bold << elapse_time << 's' << rang::style::reset;
if (elapse_time > 60) { if (elapse_time > 60) {
std::cout << " [" << rang::style::bold << this->_prettyPrintTime(elapse_time) << rang::style::reset << ']'; os << " [" << rang::style::bold << this->_prettyPrintTime(elapse_time) << rang::style::reset << ']';
} }
if (m_run_number > 1) { if (m_run_number > 1) {
const double cumulative_elapse_time = elapse_time + m_previous_cumulative_elapse_time; const double cumulative_elapse_time = elapse_time + m_previous_cumulative_elapse_time;
std::cout << " (Run number " << m_run_number << ").\n - Cumulative execution time: " << rang::style::bold os << " (Run number " << m_run_number << ").\n - Cumulative execution time: " << rang::style::bold
<< cumulative_elapse_time << 's' << rang::style::reset; << cumulative_elapse_time << 's' << rang::style::reset;
if (cumulative_elapse_time > 60) { if (cumulative_elapse_time > 60) {
std::cout << " [" << rang::style::bold << this->_prettyPrintTime(cumulative_elapse_time) << rang::style::reset os << " [" << rang::style::bold << this->_prettyPrintTime(cumulative_elapse_time) << rang::style::reset << ']';
<< ']';
} }
} }
std::cout << '\n'; os << '\n';
} }
void void
ExecutionStatManager::_printTotalCPUTime() const ExecutionStatManager::_printTotalCPUTime(std::ostream& os) const
{ {
rusage u; rusage u;
getrusage(RUSAGE_SELF, &u); getrusage(RUSAGE_SELF, &u);
...@@ -128,36 +125,33 @@ ExecutionStatManager::_printTotalCPUTime() const ...@@ -128,36 +125,33 @@ ExecutionStatManager::_printTotalCPUTime() const
const double total_cpu_time = const double total_cpu_time =
parallel::allReduceSum(u.ru_utime.tv_sec + u.ru_stime.tv_sec + (u.ru_utime.tv_usec + u.ru_stime.tv_usec) * 1E-6); parallel::allReduceSum(u.ru_utime.tv_sec + u.ru_stime.tv_sec + (u.ru_utime.tv_usec + u.ru_stime.tv_usec) * 1E-6);
std::cout << "Total CPU: " << rang::style::bold << total_cpu_time << 's' << rang::style::reset; os << "Total CPU: " << rang::style::bold << total_cpu_time << 's' << rang::style::reset;
std::cout << " (" << parallel::allReduceSum(Kokkos::DefaultHostExecutionSpace::concurrency()) << " threads over " os << " (" << parallel::allReduceSum(Kokkos::DefaultHostExecutionSpace::concurrency()) << " threads over "
<< parallel::size() << " processes)"; << parallel::size() << " processes)";
if (total_cpu_time > 60) { if (total_cpu_time > 60) {
std::cout << " [" << _prettyPrintTime(total_cpu_time) << ']'; os << " [" << _prettyPrintTime(total_cpu_time) << ']';
} }
if (m_run_number > 1) { if (m_run_number > 1) {
const double cumulative_total_cpu_time = total_cpu_time + m_previous_cumulative_total_cpu_time; const double cumulative_total_cpu_time = total_cpu_time + m_previous_cumulative_total_cpu_time;
std::cout << "\n - Cumulative total CPU: " << rang::style::bold << cumulative_total_cpu_time << 's' os << "\n - Cumulative total CPU: " << rang::style::bold << cumulative_total_cpu_time << 's' << rang::style::reset;
<< rang::style::reset;
if (cumulative_total_cpu_time > 60) { if (cumulative_total_cpu_time > 60) {
std::cout << " [" << rang::style::bold << this->_prettyPrintTime(cumulative_total_cpu_time) << rang::style::reset os << " [" << rang::style::bold << this->_prettyPrintTime(cumulative_total_cpu_time) << rang::style::reset << ']';
<< ']';
} }
} }
std::cout << '\n'; os << '\n';
} }
void void
ExecutionStatManager::printInfo() ExecutionStatManager::printInfo(std::ostream& os)
{ {
if (ExecutionStatManager::getInstance().doPrint()) { if (ExecutionStatManager::getInstance().doPrint()) {
std::cout << "----------------- " << rang::fg::green << "pugs exec stats" << rang::fg::reset os << "----------------- " << rang::fg::green << "pugs exec stats" << rang::fg::reset << " ---------------------\n";
<< " ---------------------\n";
ExecutionStatManager::getInstance()._printElapseTime(); ExecutionStatManager::getInstance()._printElapseTime(os);
ExecutionStatManager::getInstance()._printTotalCPUTime(); ExecutionStatManager::getInstance()._printTotalCPUTime(os);
ExecutionStatManager::getInstance()._printMaxResidentMemory(); ExecutionStatManager::getInstance()._printMaxResidentMemory(os);
} }
} }
......
...@@ -4,9 +4,14 @@ ...@@ -4,9 +4,14 @@
#include <utils/PugsAssert.hpp> #include <utils/PugsAssert.hpp>
#include <utils/Timer.hpp> #include <utils/Timer.hpp>
#include <iostream>
class ExecutionStatManager class ExecutionStatManager
{ {
private: private:
// For unit tests only
friend class ExecutionStatManagerTester;
static ExecutionStatManager* m_instance; static ExecutionStatManager* m_instance;
Timer m_elapse_time; Timer m_elapse_time;
...@@ -19,9 +24,9 @@ class ExecutionStatManager ...@@ -19,9 +24,9 @@ class ExecutionStatManager
std::string _prettyPrintTime(double seconds) const; std::string _prettyPrintTime(double seconds) const;
void _printMaxResidentMemory() const; void _printMaxResidentMemory(std::ostream& os) const;
void _printElapseTime() const; void _printElapseTime(std::ostream& os) const;
void _printTotalCPUTime() const; void _printTotalCPUTime(std::ostream& os) const;
explicit ExecutionStatManager() = default; explicit ExecutionStatManager() = default;
ExecutionStatManager(ExecutionStatManager&&) = delete; ExecutionStatManager(ExecutionStatManager&&) = delete;
...@@ -99,7 +104,7 @@ class ExecutionStatManager ...@@ -99,7 +104,7 @@ class ExecutionStatManager
return *m_instance; return *m_instance;
} }
static void printInfo(); static void printInfo(std::ostream& os = std::cout);
static void create(); static void create();
static void destroy(); static void destroy();
}; };
......
...@@ -224,6 +224,7 @@ add_executable (mpi_unit_tests ...@@ -224,6 +224,7 @@ add_executable (mpi_unit_tests
test_EmbeddedDiscreteFunctionOperators1D.cpp test_EmbeddedDiscreteFunctionOperators1D.cpp
test_EmbeddedDiscreteFunctionOperators2D.cpp test_EmbeddedDiscreteFunctionOperators2D.cpp
test_EmbeddedDiscreteFunctionOperators3D.cpp test_EmbeddedDiscreteFunctionOperators3D.cpp
test_ExecutionStatManager.cpp
test_InterpolateItemArray.cpp test_InterpolateItemArray.cpp
test_InterpolateItemValue.cpp test_InterpolateItemValue.cpp
test_ItemArray.cpp test_ItemArray.cpp
......
#include <catch2/catch_test_macros.hpp>
#include <catch2/matchers/catch_matchers_all.hpp>
#include <utils/ExecutionStatManager.hpp>
#include <utils/Stringify.hpp>
#include <utils/pugs_config.hpp>
#include <sstream>
class ExecutionStatManagerTester
{
public:
double
getPreviousCumulativeElapseTime() const
{
return ExecutionStatManager::getInstance().m_previous_cumulative_elapse_time;
}
double
getPreviousCumulativeTotalCpuTime() const
{
return ExecutionStatManager::getInstance().m_previous_cumulative_total_cpu_time;
}
void
setElapseTime(const Timer& timer) const
{
ExecutionStatManager::getInstance().m_elapse_time = timer;
}
Timer&
getElapseTime() const
{
return ExecutionStatManager::getInstance().m_elapse_time;
}
ExecutionStatManagerTester() = default;
~ExecutionStatManagerTester() = default;
};
// clazy:excludeall=non-pod-global-static
TEST_CASE("ExecutionStatManager", "[utils]")
{
REQUIRE_NOTHROW(ExecutionStatManager::create());
REQUIRE_THROWS_WITH(ExecutionStatManager::create(), "unexpected error: ExecutionStatManager already created");
ExecutionStatManagerTester esm_tester;
REQUIRE(ExecutionStatManager::getInstance().runNumber() == 1);
REQUIRE(ExecutionStatManager::getInstance().doPrint() == true);
REQUIRE(ExecutionStatManager::getInstance().exitCode() == 0);
REQUIRE(esm_tester.getPreviousCumulativeElapseTime() == 0);
REQUIRE(esm_tester.getPreviousCumulativeTotalCpuTime() == 0);
REQUIRE_NOTHROW(ExecutionStatManager::getInstance().setRunNumber(2));
REQUIRE(ExecutionStatManager::getInstance().runNumber() == 2);
REQUIRE_NOTHROW(ExecutionStatManager::getInstance().setPreviousCumulativeElapseTime(100));
REQUIRE_NOTHROW(ExecutionStatManager::getInstance().setPreviousCumulativeTotalCPUTime(200));
REQUIRE(esm_tester.getPreviousCumulativeElapseTime() == 100);
REQUIRE(esm_tester.getPreviousCumulativeTotalCpuTime() == 200);
using namespace std::chrono_literals;
Timer t{std::chrono::high_resolution_clock::now() - (2 * 21h + 267s)};
t.pause();
esm_tester.setElapseTime(t);
REQUIRE(ExecutionStatManager::getInstance().getElapseTime() == t.seconds());
REQUIRE(ExecutionStatManager::getInstance().getCumulativeElapseTime() == 100 + t.seconds());
REQUIRE(ExecutionStatManager::getInstance().getCumulativeTotalCPUTime() >= 200);
std::ostringstream os;
// One just call the function not test is performed. It is quite
// boring to check the result and not that useful.
ExecutionStatManager::getInstance().printInfo(os);
ExecutionStatManager::getInstance().setPrint(false);
REQUIRE(ExecutionStatManager::getInstance().doPrint() == false);
ExecutionStatManager::getInstance().setExitCode(1);
REQUIRE(ExecutionStatManager::getInstance().exitCode() == 1);
REQUIRE_NOTHROW(ExecutionStatManager::destroy());
// One allows multiple destruction to handle unexpected code exit
REQUIRE_NOTHROW(ExecutionStatManager::destroy());
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment