feat(preconditioner): major work on preconditioner system

first preconditioner MVP
This commit is contained in:
2026-09-04 07:54:10 -04:00
parent 25510008dd
commit 71423d543f
61 changed files with 15920 additions and 422 deletions

View File

@@ -4,6 +4,7 @@
#include <catch2/reporters/catch_reporter_registrars.hpp>
#include <catch2/reporters/catch_reporter_streaming_base.hpp>
#include <chrono>
#include <cstdint>
#include <fstream>
#include <iomanip>
#include <iostream>
@@ -235,6 +236,23 @@ class CheckReporter : public Catch::StreamingReporterBase {
std::vector<TestCaseData> m_testRunData;
std::chrono::time_point<std::chrono::steady_clock> m_testStartTime;
static bool isRootProcess() {
int initialized = 0;
int finalized = 0;
MPI_Initialized(&initialized);
if (initialized == 0) {
return true;
}
MPI_Finalized(&finalized);
if (finalized != 0) {
return true;
}
int rank = 0;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
return rank == 0;
}
void captureInfoMessages(Catch::AssertionStats const &assertionStats) {
for (auto const &message : assertionStats.infoMessages) {
if (m_currentInfoSequences.insert(message.sequence).second) {
@@ -263,6 +281,10 @@ public:
void testRunStarting(Catch::TestRunInfo const &_testRunInfo) override {
StreamingReporterBase::testRunStarting(_testRunInfo);
if (!isRootProcess()) {
return;
}
std::cout << '\n';
std::cout << std::left << std::setw(85) << "Test Case Name"
<< "Status " << std::right << std::setw(8) << "Passed" << std::setw(8) << "Failed" << std::setw(12)
@@ -273,7 +295,11 @@ public:
void testCaseStarting(Catch::TestCaseInfo const &testInfo) override {
StreamingReporterBase::testCaseStarting(testInfo);
m_testStartTime = std::chrono::steady_clock::now();
m_testStartTime = std::chrono::steady_clock::now();
if (!isRootProcess()) {
return;
}
std::string name = testInfo.name;
auto wrappedName = wrapText(name, 83);
@@ -324,31 +350,36 @@ public:
std::string name = stats.testInfo->name;
auto wrappedName = wrapText(name, 83);
// Overwrite the loading line with the actual result
std::cout << "\r\033[K" << std::left << std::setw(85) << wrappedName[0] << mark << " " << std::right
<< std::setw(8) << stats.totals.assertions.passed << std::setw(8) << stats.totals.assertions.failed
<< std::setw(11) << std::fixed << std::setprecision(3) << duration_s << "s\n";
if (isRootProcess()) {
// Overwrite the loading line with the actual result
std::cout << "\r\033[K" << std::left << std::setw(85) << wrappedName[0] << mark << " " << std::right
<< std::setw(8) << stats.totals.assertions.passed << std::setw(8)
<< stats.totals.assertions.failed << std::setw(11) << std::fixed << std::setprecision(3)
<< duration_s << "s\n";
for (size_t i = 1; i < wrappedName.size(); ++i) {
std::cout << " \033[90m↳ \033[0m" // Dim indent arrow
<< std::left << std::setw(81) << wrappedName[i] << '\n';
for (size_t i = 1; i < wrappedName.size(); ++i) {
std::cout << " \033[90m↳ \033[0m" // Dim indent arrow
<< std::left << std::setw(81) << wrappedName[i] << '\n';
}
std::string tagsStr = stats.testInfo->tagsAsString();
if (!tagsStr.empty()) {
auto wrappedTags = wrapText("Tags: " + tagsStr, 83);
for (const auto &line : wrappedTags) {
std::cout << " \033[36m" << line << "\033[0m\n"; // Cyan
}
}
if (!m_currentFailures.empty()) {
std::cout << '\n';
for (auto const &failure : m_currentFailures) {
std::cout << failure << '\n';
}
std::cout << std::string(133, '-') << '\n';
}
}
std::string tagsStr = stats.testInfo->tagsAsString();
if (!tagsStr.empty()) {
auto wrappedTags = wrapText("Tags: " + tagsStr, 83);
for (const auto &line : wrappedTags) {
std::cout << " \033[36m" << line << "\033[0m\n"; // Cyan
}
}
if (!m_currentFailures.empty()) {
std::cout << '\n';
for (auto const &failure : m_currentFailures) {
std::cout << failure << '\n';
}
std::cout << std::string(133, '-') << '\n';
}
m_testRunData.push_back(
{name, tagsStr, passed, stats.totals.assertions.passed, stats.totals.assertions.failed, duration_s,
@@ -363,6 +394,10 @@ public:
void testRunEnded(Catch::TestRunStats const &_testRunStats) override {
StreamingReporterBase::testRunEnded(_testRunStats);
if (!isRootProcess()) {
return;
}
std::cout << std::string(133, '=') << '\n';
auto const &tc = _testRunStats.totals.testCases;
@@ -587,12 +622,18 @@ int main(
mfem::Mpi::Init(argc, argv);
std::uint32_t synchronized_seed = session.configData().rngSeed;
MPI_Bcast(&synchronized_seed, 1, MPI_UINT32_T, 0, MPI_COMM_WORLD);
session.configData().rngSeed = synchronized_seed;
constexpr std::string device_config = "cpu";
mfem::Device device(device_config);
const int hdiv_max_q1d = mfem::DeviceDofQuadLimits::Get().HDIV_MAX_Q1D;
std::cout << "H(div) maximum Q1D = " << hdiv_max_q1d << '\n';
std::cout << "Approximate maximum safe integration order = " << 2 * hdiv_max_q1d - 1 << '\n';
if (mfem::Mpi::Root()) {
std::cout << "H(div) maximum Q1D = " << hdiv_max_q1d << '\n';
std::cout << "Approximate maximum safe integration order = " << 2 * hdiv_max_q1d - 1 << '\n';
}
mean_field::utils::Args test_args = cfg.main();
@@ -611,4 +652,4 @@ int main(
test_utils::set_args(std::move(test_args));
return session.run();
}
}