Skip to content

Conversation

mgovers
Copy link
Member

@mgovers mgovers commented Sep 1, 2025

  • Make calculation info a proper logger
  • Give main model impl and job adapter the logger
  • Multithreaded logging is a specialized class and no longer is scattered throughout the job dispatch and adapter
  • NOTE: the destructors are responsible for syncing and unregistering the child classes

relates to #1093

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]>
@mgovers mgovers self-assigned this Sep 1, 2025
@mgovers mgovers added the do-not-merge This should not be merged label Sep 1, 2025
Copy link

@Copilot Copilot AI left a 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 with Logger* 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.

mgovers and others added 4 commits September 2, 2025 08:09
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]>
Comment on lines +607 to +610
Logger& logger() const {
static common::logging::NoLogger no_log{};
return log_ != nullptr ? *log_ : no_log;
}
Copy link
Member Author

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.

Copy link
Contributor

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?

mgovers and others added 3 commits September 2, 2025 08:53
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]>
@mgovers mgovers marked this pull request as ready for review September 2, 2025 07:56
@mgovers mgovers added feature New feature or request and removed do-not-merge This should not be merged labels Sep 2, 2025
@mgovers
Copy link
Member Author

mgovers commented Sep 2, 2025

do-not-merge label removed because i think the PR is in a good state for a first iteration

mgovers and others added 5 commits September 2, 2025 10:29
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};
Copy link
Member

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?

Copy link
Member Author

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?

Copy link
Member Author

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> {
Copy link
Member

@nitbharambe nitbharambe Sep 2, 2025

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?

Copy link
Member Author

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

Copy link
Member Author

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)

Comment on lines 62 to 75
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);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice.

Copy link
Member Author

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

Copy link
Contributor

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.

Copy link
Contributor

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.

mgovers and others added 7 commits September 2, 2025 14:17
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]>
Signed-off-by: Martijn Govers <[email protected]>
Comment on lines +25 to +26
UpdateDataset const& update_data, Idx threading,
common::logging::MultiThreadedLogger& log) {
Copy link
Contributor

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 {
Copy link
Contributor

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.

Copy link
Contributor

@figueroa1395 figueroa1395 left a 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants