-
Notifications
You must be signed in to change notification settings - Fork 43
Cleanup main model: dependency inversion main model impl info #1107
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Signed-off-by: Martijn Govers <[email protected]>
Signed-off-by: Martijn Govers <[email protected]>
Signed-off-by: Martijn Govers <[email protected]>
…version-main-model-impl-info Signed-off-by: Martijn Govers <[email protected]>
Signed-off-by: Martijn Govers <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR refactors the calculation info system to use dependency inversion by replacing direct CalculationInfo usage with a proper Logger interface. The key changes include replacing CalculationInfo with Logger in the main model implementation and introducing multi-threaded logging capabilities.
- Replaces
CalculationInfo
member withLogger*
in main model implementation - Introduces
MultiThreadedLogger
interface and implementation for thread-safe logging - Updates job adapter and dispatch logic to use logger pattern instead of direct calculation info management
Reviewed Changes
Copilot reviewed 13 out of 13 changed files in this pull request and generated 3 comments.
Show a summary per file
File | Description |
---|---|
tests/native_api_tests/test_api_model_update.cpp | Removes unused iostream include |
tests/cpp_unit_tests/test_job_dispatch.cpp | Updates mock job adapter to use logger pattern and adds test logger implementations |
power_grid_model_c/power_grid_model/include/power_grid_model/main_model_impl.hpp | Replaces calculation_info_ with log_ pointer and updates logger usage |
power_grid_model_c/power_grid_model/include/power_grid_model/main_model.hpp | Adds MultiThreadedCalculationInfo member and updates batch calculation |
power_grid_model_c/power_grid_model/include/power_grid_model/job_interface.hpp | Replaces calculation info methods with logger methods |
power_grid_model_c/power_grid_model/include/power_grid_model/job_dispatch.hpp | Updates job dispatch to use multi-threaded logger pattern |
power_grid_model_c/power_grid_model/include/power_grid_model/job_adapter.hpp | Implements logger interface methods and removes calculation info logic |
power_grid_model_c/power_grid_model/include/power_grid_model/component/asym_line.hpp | Removes unused iostream include |
power_grid_model_c/power_grid_model/include/power_grid_model/common/multi_threaded_logging.hpp | New file implementing multi-threaded logger template |
power_grid_model_c/power_grid_model/include/power_grid_model/common/logging_impl.hpp | Adds merge_into function for NoLogger |
power_grid_model_c/power_grid_model/include/power_grid_model/common/logging.hpp | Adds MultiThreadedLogger interface |
power_grid_model_c/power_grid_model/include/power_grid_model/common/common.hpp | Adds concepts include |
power_grid_model_c/power_grid_model/include/power_grid_model/common/calculation_info.hpp | Adds MultiThreadedCalculationInfo class |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
power_grid_model_c/power_grid_model/include/power_grid_model/common/multi_threaded_logging.hpp
Outdated
Show resolved
Hide resolved
power_grid_model_c/power_grid_model/include/power_grid_model/job_dispatch.hpp
Outdated
Show resolved
Hide resolved
Signed-off-by: Martijn Govers <[email protected]> Co-authored-by: Copilot <[email protected]> Signed-off-by: Martijn Govers <[email protected]>
…ommon/multi_threaded_logging.hpp Signed-off-by: Martijn Govers <[email protected]> Co-authored-by: Copilot <[email protected]> Signed-off-by: Martijn Govers <[email protected]>
…ob_dispatch.hpp Signed-off-by: Martijn Govers <[email protected]> Co-authored-by: Copilot <[email protected]> Signed-off-by: Martijn Govers <[email protected]>
Signed-off-by: Martijn Govers <[email protected]>
Logger& logger() const { | ||
static common::logging::NoLogger no_log{}; | ||
return log_ != nullptr ? *log_ : no_log; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
one future improvement could be to pass the logger not by reference but by pass-by-value view that does this same thing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you mean with pass-by-value view in this context?
Signed-off-by: Martijn Govers <[email protected]> Signed-off-by: Martijn Govers <[email protected]>
Signed-off-by: Martijn Govers <[email protected]>
Signed-off-by: Martijn Govers <[email protected]>
do-not-merge label removed because i think the PR is in a good state for a first iteration |
Signed-off-by: Martijn Govers <[email protected]>
…-info Signed-off-by: Martijn Govers <[email protected]>
Signed-off-by: Martijn Govers <[email protected]>
Signed-off-by: Martijn Govers <[email protected]>
Signed-off-by: Martijn Govers <[email protected]>
Signed-off-by: Martijn Govers <[email protected]>
@@ -83,7 +95,7 @@ class JobAdapter<MainModel, ComponentList<ComponentType...>> | |||
// current_scenario_sequence_cache_ is calculated per scenario, so it is excluded from the constructors. | |||
main_core::utils::SequenceIdx<ComponentType...> current_scenario_sequence_cache_{}; | |||
|
|||
std::mutex calculation_info_mutex_; | |||
Logger* log_{nullptr}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why does job adapter also need to store it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i've thought about his for a bit and this relates to the registering/unregistering discussion from elsewhere in this PR (specifically the one in #1107)
i've described the fact that the registering/unregistering is quite tricky in itself. an alternative could be to use model.calculate(..., log_)
. Now we can also do a hybrid situation here: the adapter could be the boundary between registering/unregistering (to the job adapter). The model itself could be model.calculate(..., log_)
. Then, the adapter still contains a logger, but the model no longer does.
thoughts?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Experiment in #1115
return destination; | ||
} | ||
|
||
class MultiThreadedCalculationInfo : public MultiThreadedLoggerImpl<CalculationInfo> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The SubThreadLogger being CalculationInfo was kind of confusing to me before review.
It is now a SubThreadLogger which is a "map".
Lets throw all notions of earlier CalculationInfo out? Or atleast rename te calculation_info in places like MathSolver.
We do that in a later PR or now?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
math solver was already completely made agnostic of the calculation info
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the only locations that IMO should know of calculation info are the objects/functions that manage a calculation info in their own scope, that is: the benchmark and the C API (main_model.hpp
for now)
power_grid_model_c/power_grid_model/include/power_grid_model/common/multi_threaded_logging.hpp
Outdated
Show resolved
Hide resolved
power_grid_model_c/power_grid_model/include/power_grid_model/common/multi_threaded_logging.hpp
Outdated
Show resolved
Hide resolved
power_grid_model_c/power_grid_model/include/power_grid_model/common/logging_impl.hpp
Show resolved
Hide resolved
power_grid_model_c/power_grid_model/include/power_grid_model/common/multi_threaded_logging.hpp
Outdated
Show resolved
Hide resolved
power_grid_model_c/power_grid_model/include/power_grid_model/common/multi_threaded_logging.hpp
Outdated
Show resolved
Hide resolved
template <typename Adapter, typename ResultDataset, typename UpdateDataset> | ||
requires std::is_base_of_v<JobInterface<Adapter>, Adapter> | ||
static BatchParameter batch_calculation(Adapter& adapter, ResultDataset const& result_data, | ||
UpdateDataset const& update_data, Idx threading) { | ||
common::logging::NoMultiThreadedLogger no_log{}; | ||
return batch_calculation(adapter, result_data, update_data, threading, | ||
static_cast<common::logging::MultiThreadedLogger&>(no_log)); | ||
} | ||
template <typename Adapter, typename ResultDataset, typename UpdateDataset> | ||
requires std::is_base_of_v<JobInterface<Adapter>, Adapter> | ||
static BatchParameter batch_calculation(Adapter& adapter, ResultDataset const& result_data, | ||
UpdateDataset const& update_data) { | ||
return batch_calculation(adapter, result_data, update_data, sequential); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMO we should move to one single line for these. i can clean up in this PR if you prefer, or wait a little bit.
I also think, e.g., that MainModelImpl
should only have one constructor
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can do these changes in a follow up PR. Let's keep this one self contained with the dependency injection via the new logger stuff.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Leaving this one open as a reminder for a follow up. Feel free to resolve.
power_grid_model_c/power_grid_model/include/power_grid_model/job_dispatch.hpp
Show resolved
Hide resolved
power_grid_model_c/power_grid_model/include/power_grid_model/main_model.hpp
Show resolved
Hide resolved
power_grid_model_c/power_grid_model/include/power_grid_model/main_model_impl.hpp
Show resolved
Hide resolved
power_grid_model_c/power_grid_model/include/power_grid_model/main_model.hpp
Show resolved
Hide resolved
Signed-off-by: Martijn Govers <[email protected]>
Signed-off-by: Martijn Govers <[email protected]>
Signed-off-by: Martijn Govers <[email protected]>
Signed-off-by: Martijn Govers <[email protected]>
Signed-off-by: Martijn Govers <[email protected]>
…-info Signed-off-by: Martijn Govers <[email protected]>
Signed-off-by: Martijn Govers <[email protected]>
UpdateDataset const& update_data, Idx threading, | ||
common::logging::MultiThreadedLogger& log) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Side note, but it may be a good idea to update our internal UML around job_dispatch
with this logger dependency (and include the logger stuff into it). I mean a simple version, just to show progress there.
}; | ||
|
||
class SomeTestException : public std::runtime_error { | ||
public: | ||
using std::runtime_error::runtime_error; | ||
}; | ||
|
||
class TestLogger : public common::logging::Logger { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe this is a next step, but I don't think TestLogger
belongs here. I'd say we put it at the same level as NoLogger
(or something similar), and then use it here but latter on also to unit test the logger stuff... As in our own loggers should be directly tested, but the multithreaded ones and the interface (as we expect users to make their own loggers - theoretically) should be tested through something like this. Just food for thought.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Gave it another review and LGTM. Remaining comments can either be addressed in #1115 or are minor questions. Feel free to resolve them.
relates to #1093