Skip to content

Commit 3f20602

Browse files
authored
Merge pull request #1107 from PowerGridModel/feature/dependency-inversion-main-model-impl-info
Cleanup main model: dependency inversion main model impl info
2 parents 1c737b9 + e684a03 commit 3f20602

File tree

18 files changed

+320
-170
lines changed

18 files changed

+320
-170
lines changed

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

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@
44

55
#pragma once
66

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

99
#include <map>
1010

1111
namespace power_grid_model {
1212
namespace common::logging {
13-
class CalculationInfo final : public Logger {
13+
class CalculationInfo : public Logger {
1414
using Data = std::map<LogEvent, double>;
1515

1616
public:
@@ -85,8 +85,28 @@ class CalculationInfo final : public Logger {
8585
public:
8686
Report report() const { return data_; }
8787
void clear() { data_.clear(); }
88+
89+
template <std::derived_from<Logger> T> T& merge_into(T& destination) const {
90+
if (&destination == this) {
91+
return destination; // nothing to do
92+
}
93+
for (const auto& [tag, value] : report()) {
94+
destination.log(tag, value);
95+
}
96+
return destination;
97+
}
98+
};
99+
100+
class MultiThreadedCalculationInfo : public MultiThreadedLoggerImpl<CalculationInfo> {
101+
public:
102+
using MultiThreadedLoggerImpl<CalculationInfo>::MultiThreadedLoggerImpl;
103+
using Report = CalculationInfo::Report;
104+
105+
Report report() const { return get().report(); }
106+
void clear() { get().clear(); }
88107
};
89108
} // namespace common::logging
90109

91110
using common::logging::CalculationInfo;
111+
using common::logging::MultiThreadedCalculationInfo;
92112
} // namespace power_grid_model

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
#include <cmath>
88
#include <complex>
9+
#include <concepts>
910
#include <cstddef>
1011
#include <cstdint>
1112
#include <limits>

power_grid_model_c/power_grid_model/include/power_grid_model/common/logging_impl.hpp renamed to power_grid_model_c/power_grid_model/include/power_grid_model/common/dummy_logging.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ class NoLogger : public Logger {
2424
void log(LogEvent /*tag*/, Idx /*value*/) override {
2525
// no logging
2626
}
27+
28+
template <std::derived_from<Logger> T> T& merge_into(T& destination) const { return destination; }
2729
};
2830

2931
} // namespace power_grid_model::common::logging

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,10 @@ class Logger {
6060
Logger& operator=(Logger const&) = default;
6161
};
6262

63+
struct MultiThreadedLogger : public Logger {
64+
virtual std::unique_ptr<Logger> create_child() = 0;
65+
};
66+
6367
} // namespace common::logging
6468

6569
using common::logging::LogEvent;
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// SPDX-FileCopyrightText: Contributors to the Power Grid Model project <powergridmodel@lfenergy.org>
2+
//
3+
// SPDX-License-Identifier: MPL-2.0
4+
5+
#pragma once
6+
7+
#include "dummy_logging.hpp"
8+
9+
#include <cassert>
10+
#include <mutex>
11+
12+
namespace power_grid_model::common::logging {
13+
14+
template <std::derived_from<Logger> LoggerType>
15+
requires requires(LoggerType& destination, LoggerType const& source) {
16+
{ source.merge_into(destination) };
17+
}
18+
class MultiThreadedLoggerImpl : public MultiThreadedLogger {
19+
public:
20+
class ThreadLogger : public LoggerType {
21+
public:
22+
ThreadLogger(MultiThreadedLoggerImpl& parent) : parent_{&parent} {}
23+
ThreadLogger(ThreadLogger const&) = default;
24+
ThreadLogger& operator=(ThreadLogger const&) = default;
25+
ThreadLogger(ThreadLogger&&) noexcept = default;
26+
ThreadLogger& operator=(ThreadLogger&&) noexcept = default;
27+
~ThreadLogger() override { sync(); }
28+
void sync() const { parent_->sync(*this); }
29+
30+
private:
31+
MultiThreadedLoggerImpl* parent_;
32+
};
33+
34+
std::unique_ptr<Logger> create_child() override { return std::make_unique<ThreadLogger>(*this); }
35+
LoggerType& get() { return log_; }
36+
LoggerType const& get() const { return log_; }
37+
38+
void log(LogEvent tag) override { log_.log(tag); }
39+
void log(LogEvent tag, std::string_view message) override { log_.log(tag, message); }
40+
void log(LogEvent tag, double value) override { log_.log(tag, value); }
41+
void log(LogEvent tag, Idx value) override { log_.log(tag, value); }
42+
43+
private:
44+
friend class ThreadLogger;
45+
46+
LoggerType log_;
47+
std::mutex mutex_;
48+
49+
void sync(ThreadLogger const& logger) {
50+
assert(&logger != &log_);
51+
52+
std::lock_guard const lock{mutex_};
53+
logger.merge_into(log_);
54+
}
55+
};
56+
57+
using NoMultiThreadedLogger = MultiThreadedLoggerImpl<NoLogger>;
58+
59+
} // namespace power_grid_model::common::logging

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

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,13 @@ using Duration = std::chrono::duration<double>;
1717

1818
class Timer {
1919
private:
20-
Logger* info_;
20+
Logger* log_;
2121
LogEvent code_;
2222
Clock::time_point start_;
2323

2424
public:
25-
Timer() : info_{nullptr}, code_{LogEvent::unknown} {};
26-
Timer(Logger& info, LogEvent code) : info_{&info}, code_{code}, start_{Clock::now()} {}
25+
Timer() : log_{nullptr}, code_{LogEvent::unknown} {};
26+
Timer(Logger& log, LogEvent code) : log_{&log}, code_{code}, start_{Clock::now()} {}
2727

2828
Timer(Timer const&) = delete;
2929
Timer(Timer&&) = default;
@@ -34,29 +34,29 @@ class Timer {
3434
stop();
3535

3636
// Copy/move members
37-
info_ = timer.info_;
37+
log_ = timer.log_;
3838
code_ = timer.code_;
3939
start_ = timer.start_;
4040

4141
// Disable original timer
42-
timer.info_ = nullptr;
42+
timer.log_ = nullptr;
4343

4444
// Return reference
4545
return *this;
4646
}
4747

4848
~Timer() {
49-
if (info_ != nullptr) {
49+
if (log_ != nullptr) {
5050
stop();
5151
}
5252
}
5353

5454
void stop() {
55-
if (info_ != nullptr) {
55+
if (log_ != nullptr) {
5656
auto const now = Clock::now();
5757
auto const duration = Duration(now - start_);
58-
info_->log(code_, duration.count());
59-
info_ = nullptr;
58+
log_->log(code_, duration.count());
59+
log_ = nullptr;
6060
}
6161
}
6262
};

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
#include "../common/matrix_utils.hpp"
1616
#include "../common/three_phase_tensor.hpp"
1717

18-
#include <iostream>
1918
#include <numeric>
2019

2120
namespace power_grid_model {

power_grid_model_c/power_grid_model/include/power_grid_model/job_adapter.hpp

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
#include "job_interface.hpp"
1111
#include "main_model_fwd.hpp"
1212

13-
#include "main_core/calculation_info.hpp"
1413
#include "main_core/update.hpp"
1514

1615
namespace power_grid_model {
@@ -23,15 +22,19 @@ class JobAdapter<MainModel, ComponentList<ComponentType...>>
2322
public:
2423
JobAdapter(std::reference_wrapper<MainModel> model_reference,
2524
std::reference_wrapper<MainModelOptions const> options)
26-
: model_reference_{model_reference}, options_{options} {}
25+
: model_reference_{model_reference}, options_{options} {
26+
reset_logger_impl();
27+
}
2728
JobAdapter(JobAdapter const& other)
2829
: model_copy_{std::make_unique<MainModel>(other.model_reference_.get())},
2930
model_reference_{std::ref(*model_copy_)},
3031
options_{std::ref(other.options_)},
3132
components_to_update_{other.components_to_update_},
3233
update_independence_{other.update_independence_},
3334
independence_flags_{other.independence_flags_},
34-
all_scenarios_sequence_{other.all_scenarios_sequence_} {}
35+
all_scenarios_sequence_{other.all_scenarios_sequence_} {
36+
reset_logger_impl();
37+
}
3538
JobAdapter& operator=(JobAdapter const& other) {
3639
if (this != &other) {
3740
model_copy_ = std::make_unique<MainModel>(other.model_reference_.get());
@@ -41,6 +44,8 @@ class JobAdapter<MainModel, ComponentList<ComponentType...>>
4144
update_independence_ = other.update_independence_;
4245
independence_flags_ = other.independence_flags_;
4346
all_scenarios_sequence_ = other.all_scenarios_sequence_;
47+
48+
reset_logger_impl();
4449
}
4550
return *this;
4651
}
@@ -51,7 +56,9 @@ class JobAdapter<MainModel, ComponentList<ComponentType...>>
5156
components_to_update_{std::move(other.components_to_update_)},
5257
update_independence_{std::move(other.update_independence_)},
5358
independence_flags_{std::move(other.independence_flags_)},
54-
all_scenarios_sequence_{std::move(other.all_scenarios_sequence_)} {}
59+
all_scenarios_sequence_{std::move(other.all_scenarios_sequence_)} {
60+
reset_logger_impl();
61+
}
5562
JobAdapter& operator=(JobAdapter&& other) noexcept {
5663
if (this != &other) {
5764
model_copy_ = std::move(other.model_copy_);
@@ -61,10 +68,15 @@ class JobAdapter<MainModel, ComponentList<ComponentType...>>
6168
update_independence_ = std::move(other.update_independence_);
6269
independence_flags_ = std::move(other.independence_flags_);
6370
all_scenarios_sequence_ = std::move(other.all_scenarios_sequence_);
71+
72+
reset_logger_impl();
6473
}
6574
return *this;
6675
}
67-
~JobAdapter() { model_copy_.reset(); }
76+
~JobAdapter() {
77+
reset_logger_impl();
78+
model_copy_.reset();
79+
}
6880

6981
private:
7082
// Grant the CRTP base (JobInterface<JobAdapter>) access to
@@ -83,7 +95,7 @@ class JobAdapter<MainModel, ComponentList<ComponentType...>>
8395
// current_scenario_sequence_cache_ is calculated per scenario, so it is excluded from the constructors.
8496
main_core::utils::SequenceIdx<ComponentType...> current_scenario_sequence_cache_{};
8597

86-
std::mutex calculation_info_mutex_;
98+
Logger* log_{nullptr};
8799

88100
void calculate_impl(MutableDataset const& result_data, Idx scenario_idx) const {
89101
MainModel::calculator(options_.get(), model_reference_.get(), result_data.get_individual_scenario(scenario_idx),
@@ -135,14 +147,6 @@ class JobAdapter<MainModel, ComponentList<ComponentType...>>
135147
std::ranges::for_each(current_scenario_sequence_cache_, [](auto& comp_seq_idx) { comp_seq_idx.clear(); });
136148
}
137149

138-
CalculationInfo get_calculation_info_impl() const { return model_reference_.get().calculation_info(); }
139-
void reset_calculation_info_impl() { model_reference_.get().reset_calculation_info(); }
140-
141-
void thread_safe_add_calculation_info_impl(CalculationInfo const& info) {
142-
std::lock_guard const lock{calculation_info_mutex_};
143-
model_reference_.get().merge_calculation_info(info);
144-
}
145-
146150
auto get_current_scenario_sequence_view_() const {
147151
return main_core::utils::run_functor_with_all_types_return_array<ComponentType...>([this]<typename CT>() {
148152
constexpr auto comp_idx = main_core::utils::index_of_component<CT, ComponentType...>;
@@ -152,5 +156,14 @@ class JobAdapter<MainModel, ComponentList<ComponentType...>>
152156
return std::span<Idx2D const>{std::get<comp_idx>(current_scenario_sequence_cache_)};
153157
});
154158
}
159+
160+
void reset_logger_impl() {
161+
log_ = nullptr;
162+
model_reference_.get().reset_logger();
163+
}
164+
void set_logger_impl(Logger& log) {
165+
log_ = &log;
166+
model_reference_.get().set_logger(*log_);
167+
}
155168
};
156169
} // namespace power_grid_model

0 commit comments

Comments
 (0)