Files
MeanField/tests/utils/profiling.cpp
2026-09-04 07:54:10 -04:00

92 lines
3.1 KiB
C++

#include "profile.h"
#include <catch2/catch_test_macros.hpp>
#include <limits>
#include <sstream>
#include <stdexcept>
#include <string>
import test_helpers;
TEST_CASE(
"Profiling Registry Tracks Warmups Timings And Work",
tags::unit &tags::utils
) {
mean_field::profiling::Registry &registry = mean_field::profiling::Registry::Get();
registry.Reset();
registry.Record("deterministic-region", 1.0, 2);
registry.Record("deterministic-region", 2.0, 2);
registry.Record("deterministic-region", 3.0, 2);
registry.AddCount("deterministic-region", 7);
registry.AddCount("deterministic-region", 5);
const auto snapshot = registry.Snapshot();
REQUIRE(snapshot.contains("deterministic-region"));
const mean_field::profiling::Statistics &statistics = snapshot.at("deterministic-region");
CHECK(statistics.observations == 3);
CHECK(statistics.warmups == 2);
CHECK(statistics.samples == 1);
CHECK(statistics.warmup_target == 2);
CHECK(statistics.work_units == 12);
CHECK(statistics.total_seconds == 3.0);
CHECK(statistics.minimum_seconds == 3.0);
CHECK(statistics.maximum_seconds == 3.0);
}
TEST_CASE(
"Profiling Registry Rejects Invalid Inputs Explicitly",
tags::unit &tags::utils
) {
mean_field::profiling::Registry &registry = mean_field::profiling::Registry::Get();
CHECK_THROWS_AS(registry.Record("", 1.0), std::invalid_argument);
CHECK_THROWS_AS(registry.Record("negative-duration", -1.0), std::invalid_argument);
CHECK_THROWS_AS(
registry.Record("infinite-duration", std::numeric_limits<double>::infinity()), std::invalid_argument
);
}
TEST_CASE(
"Profiling Registry Produces Deterministic Human And CSV Reports",
tags::unit &tags::utils
) {
mean_field::profiling::Registry &registry = mean_field::profiling::Registry::Get();
registry.Reset();
registry.Record("report-region", 0.25);
registry.AddCount("report-region", 9);
std::ostringstream human_report;
registry.Print(MPI_COMM_WORLD, human_report);
CHECK(human_report.str().find("report-region") != std::string::npos);
CHECK(human_report.str().find("MPI ranks: 1") != std::string::npos);
std::ostringstream csv_report;
registry.PrintCsv(MPI_COMM_WORLD, csv_report);
CHECK(csv_report.str().find("maximum_rank_total_seconds") != std::string::npos);
CHECK(csv_report.str().find("\"report-region\"") != std::string::npos);
}
#if MEAN_FIELD_ENABLE_PROFILING
TEST_CASE(
"Profiling Scope Macros Preserve Warmup Semantics",
tags::unit &tags::utils
) {
mean_field::profiling::Registry &registry = mean_field::profiling::Registry::Get();
registry.Reset();
for (int observation = 0; observation < 3; ++observation) {
MEAN_FIELD_PROFILE_SCOPE_WARMUP("macro-region", 1);
}
MEAN_FIELD_PROFILE_COUNT("macro-region", 4);
const auto snapshot = registry.Snapshot();
REQUIRE(snapshot.contains("macro-region"));
CHECK(snapshot.at("macro-region").observations == 3);
CHECK(snapshot.at("macro-region").warmups == 1);
CHECK(snapshot.at("macro-region").samples == 2);
CHECK(snapshot.at("macro-region").work_units == 4);
}
#endif