Skip to content

Commit 6fd86e4

Browse files
authored
Merge pull request #1093 from PowerGridModel/feature/logger-interface
Clean-up main model: Add logger interface
2 parents 0e8e913 + abe24bf commit 6fd86e4

File tree

18 files changed

+261
-154
lines changed

18 files changed

+261
-154
lines changed

power_grid_model_c/power_grid_model/include/power_grid_model/auxiliary/dataset.hpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,13 @@
66

77
// handle dataset and buffer related stuff
88

9+
#include "dataset_fwd.hpp"
10+
#include "meta_data.hpp"
11+
912
#include "../common/common.hpp"
1013
#include "../common/counting_iterator.hpp"
1114
#include "../common/exception.hpp"
1215
#include "../common/iterator_facade.hpp"
13-
#include "dataset_fwd.hpp"
14-
#include "meta_data.hpp"
1516

1617
#include <span>
1718
#include <string_view>

power_grid_model_c/power_grid_model/include/power_grid_model/common/calculation_info.hpp

Lines changed: 79 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,89 @@
44

55
#pragma once
66

7-
#include "logging.hpp"
7+
#include "logging_impl.hpp"
88

9-
#include <cstddef>
10-
#include <functional>
119
#include <map>
12-
#include <string>
1310

1411
namespace power_grid_model {
12+
namespace common::logging {
13+
class CalculationInfo final : public Logger {
14+
using Data = std::map<LogEvent, double>;
1515

16-
using CalculationInfo = std::map<LogEvent, double>;
16+
public:
17+
using Report = std::add_lvalue_reference_t<std::add_const_t<Data>>;
18+
static_assert(std::same_as<Report, Data const&>);
1719

20+
CalculationInfo() = default;
21+
CalculationInfo(CalculationInfo const&) = default;
22+
CalculationInfo(CalculationInfo&&) noexcept = default;
23+
CalculationInfo& operator=(CalculationInfo const&) = default;
24+
CalculationInfo& operator=(CalculationInfo&&) noexcept = default;
25+
~CalculationInfo() override = default;
26+
27+
void log(LogEvent /*tag*/) override {
28+
// ignore all such events for now
29+
}
30+
void log(LogEvent /*tag*/, std::string_view /*message*/) override {
31+
// ignore all such events for now
32+
}
33+
void log(LogEvent tag, double value) override { log_impl(tag, value); }
34+
void log(LogEvent tag, Idx value) override { log_impl(tag, static_cast<double>(value)); }
35+
36+
private:
37+
Data data_;
38+
39+
void log_impl(LogEvent tag, double value) {
40+
using enum LogEvent;
41+
42+
switch (tag) {
43+
case total:
44+
case build_model:
45+
case total_single_calculation_in_thread:
46+
case total_batch_calculation_in_thread:
47+
case copy_model:
48+
case update_model:
49+
case restore_model:
50+
case scenario_exception:
51+
case recover_from_bad:
52+
case prepare:
53+
case create_math_solver:
54+
case math_calculation:
55+
case math_solver:
56+
case initialize_calculation:
57+
case preprocess_measured_value:
58+
case prepare_matrix:
59+
case prepare_matrix_including_prefactorization:
60+
case prepare_matrices:
61+
case initialize_voltages:
62+
case calculate_rhs:
63+
case prepare_lhs_rhs:
64+
case solve_sparse_linear_equation:
65+
case solve_sparse_linear_equation_prefactorized:
66+
case iterate_unknown:
67+
case calculate_math_result:
68+
case produce_output:
69+
accumulate_log(tag, value);
70+
return;
71+
case iterative_pf_solver_max_num_iter:
72+
case max_num_iter:
73+
maximize_log(tag, value);
74+
return;
75+
default:
76+
return;
77+
}
78+
}
79+
void accumulate_log(LogEvent tag, double value) { data_[tag] += value; }
80+
void maximize_log(LogEvent tag, double value) {
81+
auto& stored_value = data_[tag];
82+
stored_value = std::max(value, stored_value);
83+
}
84+
85+
public:
86+
Report report() const { return data_; }
87+
void clear() { data_.clear(); }
88+
};
89+
} // namespace common::logging
90+
91+
using common::logging::CalculationInfo;
1892
} // namespace power_grid_model

power_grid_model_c/power_grid_model/include/power_grid_model/common/logging.hpp

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@
66

77
#include "common.hpp"
88

9+
#include <memory>
910
#include <string_view>
1011

1112
namespace power_grid_model {
1213
namespace common::logging {
13-
1414
enum class LogEvent : int16_t {
1515
unknown = -1,
1616
total = 0000, // TODO(mgovers): find other error code?
@@ -43,8 +43,26 @@ enum class LogEvent : int16_t {
4343
max_num_iter = 2248, // TODO(mgovers): find other error code
4444
};
4545

46+
class Logger {
47+
public:
48+
virtual void log(LogEvent tag) = 0;
49+
virtual void log(LogEvent tag, std::string_view message) = 0;
50+
virtual void log(LogEvent tag, double value) = 0;
51+
virtual void log(LogEvent tag, Idx value) = 0;
52+
53+
Logger(Logger&&) noexcept = default;
54+
Logger& operator=(Logger&&) noexcept = default;
55+
virtual ~Logger() = default;
56+
57+
protected:
58+
Logger() = default;
59+
Logger(Logger const&) = default;
60+
Logger& operator=(Logger const&) = default;
61+
};
62+
4663
} // namespace common::logging
4764

4865
using common::logging::LogEvent;
66+
using common::logging::Logger;
4967

5068
} // namespace power_grid_model
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// SPDX-FileCopyrightText: Contributors to the Power Grid Model project <[email protected]>
2+
//
3+
// SPDX-License-Identifier: MPL-2.0
4+
5+
#pragma once
6+
7+
#include "logging.hpp"
8+
9+
#include <string_view>
10+
#include <vector>
11+
12+
namespace power_grid_model::common::logging {
13+
class NoLogger : public Logger {
14+
public:
15+
void log(LogEvent /*tag*/) override {
16+
// no logging
17+
}
18+
void log(LogEvent /*tag*/, std::string_view /*message*/) override {
19+
// no logging
20+
}
21+
void log(LogEvent /*tag*/, double /*value*/) override {
22+
// no logging
23+
}
24+
void log(LogEvent /*tag*/, Idx /*value*/) override {
25+
// no logging
26+
}
27+
};
28+
29+
} // namespace power_grid_model::common::logging

power_grid_model_c/power_grid_model/include/power_grid_model/common/timer.hpp

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,10 @@
44

55
#pragma once
66

7-
#include "calculation_info.hpp"
87
#include "common.hpp"
98
#include "logging.hpp"
109

1110
#include <chrono>
12-
#include <iomanip>
1311
#include <sstream>
1412

1513
namespace power_grid_model {
@@ -19,13 +17,13 @@ using Duration = std::chrono::duration<double>;
1917

2018
class Timer {
2119
private:
22-
CalculationInfo* info_;
20+
Logger* info_;
2321
LogEvent code_;
2422
Clock::time_point start_;
2523

2624
public:
27-
Timer() : info_(nullptr), code_{LogEvent::unknown} {};
28-
Timer(CalculationInfo& info, LogEvent code) : info_{&info}, code_{code}, start_{Clock::now()} {}
25+
Timer() : info_{nullptr}, code_{LogEvent::unknown} {};
26+
Timer(Logger& info, LogEvent code) : info_{&info}, code_{code}, start_{Clock::now()} {}
2927

3028
Timer(Timer const&) = delete;
3129
Timer(Timer&&) = default;
@@ -57,7 +55,7 @@ class Timer {
5755
if (info_ != nullptr) {
5856
auto const now = Clock::now();
5957
auto const duration = Duration(now - start_);
60-
info_->operator[](code_) += static_cast<double>(duration.count());
58+
info_->log(code_, duration.count());
6159
info_ = nullptr;
6260
}
6361
}

power_grid_model_c/power_grid_model/include/power_grid_model/component/asym_line.hpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,8 @@
44

55
#pragma once
66

7-
#include <numeric>
8-
97
#include "branch.hpp"
10-
#include <iostream>
8+
#include "line_utils.hpp"
119

1210
#include "../auxiliary/input.hpp"
1311
#include "../auxiliary/output.hpp"
@@ -16,7 +14,9 @@
1614
#include "../common/common.hpp"
1715
#include "../common/matrix_utils.hpp"
1816
#include "../common/three_phase_tensor.hpp"
19-
#include "line_utils.hpp"
17+
18+
#include <iostream>
19+
#include <numeric>
2020

2121
namespace power_grid_model {
2222

power_grid_model_c/power_grid_model/include/power_grid_model/job_dispatch.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ class JobDispatch {
181181
} catch (...) {
182182
messages[scenario_idx] = "unknown exception";
183183
}
184-
info.merge(adapter.get_calculation_info());
184+
main_core::merge_into(info, adapter.get_calculation_info());
185185
};
186186
}
187187

power_grid_model_c/power_grid_model/include/power_grid_model/main_core/calculation_info.hpp

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,9 @@
1010

1111
namespace power_grid_model::main_core {
1212

13-
inline CalculationInfo& merge_into(CalculationInfo& destination, CalculationInfo const& source) {
14-
static constexpr auto key =
15-
LogEvent::iterative_pf_solver_max_num_iter; // TODO(mgovers) also add LogEvent::max_num_iter; this is a bug
16-
// in main
17-
for (auto const& [k, v] : source) {
18-
if (k == key) {
19-
destination[k] = std::max(destination[k], v);
20-
} else {
21-
destination[k] += v;
22-
}
13+
inline Logger& merge_into(Logger& destination, CalculationInfo const& source) {
14+
for (const auto& [tag, value] : source.report()) {
15+
destination.log(tag, value);
2316
}
2417
return destination;
2518
}

power_grid_model_c/power_grid_model/include/power_grid_model/math_solver/iterative_linear_se_solver.hpp

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ template <symmetry_tag sym_type> class IterativeLinearSESolver {
8484
perm_(y_bus.size()) {}
8585

8686
SolverOutput<sym> run_state_estimation(YBus<sym> const& y_bus, StateEstimationInput<sym> const& input,
87-
double err_tol, Idx max_iter, CalculationInfo& calculation_info) {
87+
double err_tol, Idx max_iter, Logger& log) {
8888
// prepare
8989
Timer main_timer;
9090
Timer sub_timer;
@@ -93,22 +93,22 @@ template <symmetry_tag sym_type> class IterativeLinearSESolver {
9393
output.bus_injection.resize(n_bus_);
9494
double max_dev = std::numeric_limits<double>::max();
9595

96-
main_timer = Timer{calculation_info, LogEvent::math_solver};
96+
main_timer = Timer{log, LogEvent::math_solver};
9797

9898
// preprocess measured value
99-
sub_timer = Timer{calculation_info, LogEvent::preprocess_measured_value};
99+
sub_timer = Timer{log, LogEvent::preprocess_measured_value};
100100
MeasuredValues<sym> const measured_values{y_bus.shared_topology(), input};
101101
auto const observability_result =
102102
observability_check(measured_values, y_bus.math_topology(), y_bus.y_bus_structure());
103103

104104
// prepare matrix
105-
sub_timer = Timer{calculation_info, LogEvent::prepare_matrix_including_prefactorization};
105+
sub_timer = Timer{log, LogEvent::prepare_matrix_including_prefactorization};
106106
prepare_matrix(y_bus, measured_values);
107107
// prefactorize
108108
sparse_solver_.prefactorize(data_gain_, perm_, observability_result.use_perturbation());
109109

110110
// initialize voltage with initial angle
111-
sub_timer = Timer{calculation_info, LogEvent::initialize_voltages}; // TODO(mgovers): make scoped subtimers
111+
sub_timer = Timer{log, LogEvent::initialize_voltages}; // TODO(mgovers): make scoped subtimers
112112
RealValue<sym> const mean_angle_shift = measured_values.mean_angle_shift();
113113
for (Idx bus = 0; bus != n_bus_; ++bus) {
114114
output.u[bus] = exp(1.0i * (mean_angle_shift + math_topo_->phase_shift[bus]));
@@ -120,25 +120,24 @@ template <symmetry_tag sym_type> class IterativeLinearSESolver {
120120
if (num_iter++ == max_iter) {
121121
throw IterationDiverge{max_iter, max_dev, err_tol};
122122
}
123-
sub_timer = Timer{calculation_info, LogEvent::calculate_rhs};
123+
sub_timer = Timer{log, LogEvent::calculate_rhs};
124124
prepare_rhs(y_bus, measured_values, output.u);
125125
// solve with prefactorization
126-
sub_timer = Timer{calculation_info, LogEvent::solve_sparse_linear_equation_prefactorized};
126+
sub_timer = Timer{log, LogEvent::solve_sparse_linear_equation_prefactorized};
127127
sparse_solver_.solve_with_prefactorized_matrix(data_gain_, perm_, x_rhs_, x_rhs_);
128-
sub_timer = Timer{calculation_info, LogEvent::iterate_unknown};
128+
sub_timer = Timer{log, LogEvent::iterate_unknown};
129129
max_dev = iterate_unknown(output.u, measured_values.has_angle());
130130
};
131131

132132
// calculate math result
133-
sub_timer = Timer{calculation_info, LogEvent::calculate_math_result};
133+
sub_timer = Timer{log, LogEvent::calculate_math_result};
134134
detail::calculate_se_result<sym>(y_bus, measured_values, output);
135135

136136
// Manually stop timers to avoid "Max number of iterations" to be included in the timing.
137137
sub_timer.stop();
138138
main_timer.stop();
139139

140-
calculation_info[LogEvent::max_num_iter] =
141-
std::max(calculation_info[LogEvent::max_num_iter], static_cast<double>(num_iter));
140+
log.log(LogEvent::max_num_iter, num_iter);
142141

143142
return output;
144143
}

power_grid_model_c/power_grid_model/include/power_grid_model/math_solver/iterative_pf_solver.hpp

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ template <symmetry_tag sym, typename DerivedSolver> class IterativePFSolver {
2525
public:
2626
friend DerivedSolver;
2727
SolverOutput<sym> run_power_flow(YBus<sym> const& y_bus, PowerFlowInput<sym> const& input, double err_tol,
28-
Idx max_iter, CalculationInfo& calculation_info) {
28+
Idx max_iter, Logger& log) {
2929
// get derived reference for derived solver class
3030
auto derived_solver = static_cast<DerivedSolver&>(*this);
3131

@@ -34,11 +34,11 @@ template <symmetry_tag sym, typename DerivedSolver> class IterativePFSolver {
3434
output.u.resize(n_bus_);
3535
double max_dev = std::numeric_limits<double>::infinity();
3636

37-
Timer main_timer{calculation_info, LogEvent::math_solver};
37+
Timer main_timer{log, LogEvent::math_solver};
3838

3939
// initialize
4040
{
41-
Timer const sub_timer{calculation_info, LogEvent::initialize_calculation};
41+
Timer const sub_timer{log, LogEvent::initialize_calculation};
4242
// Further initialization specific to the derived solver
4343
derived_solver.initialize_derived_solver(y_bus, input, output);
4444
}
@@ -52,31 +52,30 @@ template <symmetry_tag sym, typename DerivedSolver> class IterativePFSolver {
5252
}
5353
{
5454
// Prepare the matrices of linear equations to be solved
55-
Timer const sub_timer{calculation_info, LogEvent::prepare_matrices};
55+
Timer const sub_timer{log, LogEvent::prepare_matrices};
5656
derived_solver.prepare_matrix_and_rhs(y_bus, input, output.u);
5757
}
5858
{
5959
// Solve the linear equations
60-
Timer const sub_timer{calculation_info, LogEvent::solve_sparse_linear_equation};
60+
Timer const sub_timer{log, LogEvent::solve_sparse_linear_equation};
6161
derived_solver.solve_matrix();
6262
}
6363
{
6464
// Calculate maximum deviation of voltage at any bus
65-
Timer const sub_timer{calculation_info, LogEvent::iterate_unknown};
65+
Timer const sub_timer{log, LogEvent::iterate_unknown};
6666
max_dev = derived_solver.iterate_unknown(output.u);
6767
}
6868
}
6969

7070
// calculate math result
7171
{
72-
Timer const sub_timer{calculation_info, LogEvent::calculate_math_result};
72+
Timer const sub_timer{log, LogEvent::calculate_math_result};
7373
calculate_result(y_bus, input, output);
7474
}
7575
// Manually stop timers to avoid "Max number of iterations" to be included in the timing.
7676
main_timer.stop();
7777

78-
calculation_info[LogEvent::iterative_pf_solver_max_num_iter] =
79-
std::max(calculation_info[LogEvent::iterative_pf_solver_max_num_iter], static_cast<double>(num_iter));
78+
log.log(LogEvent::iterative_pf_solver_max_num_iter, num_iter);
8079

8180
return output;
8281
}

0 commit comments

Comments
 (0)