Skip to content

Clean-up main model: job dispatch interface and adapter #1036

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

Merged
merged 45 commits into from
Aug 11, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
8459a9e
[skip ci] broken - just tinkering
figueroa1395 Jun 25, 2025
3f41101
working poc
figueroa1395 Jul 11, 2025
884e122
cache works
figueroa1395 Jul 11, 2025
04fe5d2
moved adapter to separate file
figueroa1395 Jul 14, 2025
7dbd3de
[skip ci] copy constructor introduces memory issue
figueroa1395 Jul 14, 2025
a5f097c
fix infinite recursion during copying
mgovers Jul 14, 2025
c3b2155
Merge branch 'feature/cleanup-main-model-batch-dispatch' into virtual…
figueroa1395 Jul 15, 2025
c8cc106
wip - still broken, but getting there
figueroa1395 Jul 21, 2025
ce332ac
[skip ci] line with apparent issue
figueroa1395 Jul 21, 2025
30277c3
wip - still broken, but getting there
figueroa1395 Jul 21, 2025
47396fb
[skip ci] line with apparent issue
figueroa1395 Jul 21, 2025
e19aec6
[skip ci] finished solving branch issues, wip, almost there
figueroa1395 Jul 22, 2025
baa56b7
Merge branch 'feature/cleanup-main-model-batch-dispatch' into virtual…
figueroa1395 Jul 22, 2025
7735898
[skip ci] minor
figueroa1395 Jul 22, 2025
a21cb9a
fix stupid variadic stuff
mgovers Jul 22, 2025
426af73
[skip ci] resolved some comments - tests still broken
figueroa1395 Jul 23, 2025
cfc1e93
[skip ci] resolved some more comments
figueroa1395 Jul 23, 2025
8ff37f4
[skip ci] minor
figueroa1395 Jul 24, 2025
febcdb9
tests pass locally - still an issue
figueroa1395 Jul 24, 2025
0031bb2
move assignment operator
figueroa1395 Jul 25, 2025
e167bf4
Merge remote-tracking branch 'origin/main' into virtual-adapter-proto…
mgovers Aug 1, 2025
628b2b7
Merge remote-tracking branch 'origin/bugfix/calculation-info-memory-c…
mgovers Aug 1, 2025
9ae78a4
fix missing merge conflicts
mgovers Aug 1, 2025
021fc82
fix clang
mgovers Aug 1, 2025
4156633
fix
figueroa1395 Aug 1, 2025
b8b95ab
constructors and improvement
figueroa1395 Aug 1, 2025
f01dc28
cleanup
figueroa1395 Aug 1, 2025
1a7a572
revert accidental checkin of experimental file
mgovers Aug 4, 2025
08544f2
Merge branch 'main' into virtual-adapter-prototipe
mgovers Aug 4, 2025
6c7182e
Update power_grid_model_c/power_grid_model/include/power_grid_model/j…
mgovers Aug 4, 2025
1769f1c
-sm destructor
figueroa1395 Aug 4, 2025
7a9eea8
Merge remote-tracking branch 'origin/main' into virtual-adapter-proto…
mgovers Aug 5, 2025
e562043
Merge branch 'main' into virtual-adapter-prototipe
mgovers Aug 5, 2025
d54440d
Merge branch 'virtual-adapter-prototipe' of https://github.com/PowerG…
mgovers Aug 5, 2025
82a7a3b
Update power_grid_model_c/power_grid_model/include/power_grid_model/j…
mgovers Aug 7, 2025
ffe2ba1
Merge branch 'virtual-adapter-prototipe' of https://github.com/PowerG…
mgovers Aug 7, 2025
01435d2
Merge remote-tracking branch 'origin/main' into virtual-adapter-proto…
mgovers Aug 7, 2025
1eb1164
address comments
figueroa1395 Aug 8, 2025
f1f4a25
remove extra Idx
nitbharambe Aug 8, 2025
6a95434
remove repeatition
nitbharambe Aug 8, 2025
b998a2a
Revert "remove repeatition"
nitbharambe Aug 8, 2025
e0fb664
Merge branch 'main' into virtual-adapter-prototipe
figueroa1395 Aug 8, 2025
7f1409b
resolve comments
figueroa1395 Aug 11, 2025
158c9d1
minor
figueroa1395 Aug 11, 2025
8cec312
Merge branch 'main' into virtual-adapter-prototipe
figueroa1395 Aug 11, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
// SPDX-FileCopyrightText: Contributors to the Power Grid Model project <[email protected]>
//
// SPDX-License-Identifier: MPL-2.0

#pragma once

// Adapter that connects the JobDispatch to the MainModelImpl

#include "auxiliary/dataset.hpp"
#include "job_interface.hpp"
#include "main_model_fwd.hpp"

#include "main_core/calculation_info.hpp"
#include "main_core/update.hpp"

namespace power_grid_model {

template <class MainModel, class... ComponentType>
class JobDispatchAdapter : public JobDispatchInterface<JobDispatchAdapter<MainModel, ComponentType...>> {
public:
JobDispatchAdapter(std::reference_wrapper<MainModel> model) : model_{std::move(model)} {}
JobDispatchAdapter(JobDispatchAdapter const& other)
: model_copy_{std::make_unique<MainModel>(other.model_.get())},
model_{std::ref(*model_copy_)},
components_to_update_{other.components_to_update_},
update_independence_{other.update_independence_},
independence_flags_{other.independence_flags_},
all_scenarios_sequence_{other.all_scenarios_sequence_} {}
JobDispatchAdapter& operator=(JobDispatchAdapter const& other) {
if (this != &other) {
model_copy_ = std::make_unique<MainModel>(other.model_.get());
model_ = std::ref(*model_copy_);
components_to_update_ = other.components_to_update_;
update_independence_ = other.update_independence_;
independence_flags_ = other.independence_flags_;
all_scenarios_sequence_ = other.all_scenarios_sequence_;
}
return *this;
}
JobDispatchAdapter(JobDispatchAdapter&& other) noexcept
: model_copy_{std::move(other.model_copy_)},
model_{model_copy_ ? std::ref(*model_copy_) : std::move(other.model_)},
components_to_update_{std::move(other.components_to_update_)},
update_independence_{std::move(other.update_independence_)},
independence_flags_{std::move(other.independence_flags_)},
all_scenarios_sequence_{std::move(other.all_scenarios_sequence_)} {}
JobDispatchAdapter& operator=(JobDispatchAdapter&& other) noexcept {
if (this != &other) {
model_copy_ = std::move(other.model_copy_);
model_ = model_copy_ ? std::ref(*model_copy_) : std::move(other.model_);
components_to_update_ = std::move(other.components_to_update_);
update_independence_ = std::move(other.update_independence_);
independence_flags_ = std::move(other.independence_flags_);
all_scenarios_sequence_ = std::move(other.all_scenarios_sequence_);
}
return *this;
}
~JobDispatchAdapter() { model_copy_.reset(); }

private:
// Grant the CRTP base (JobDispatchInterface<JobDispatchAdapter>) access to
// JobDispatchAdapter's private members. This allows the base class template
// to call derived-class implementation details as part of the CRTP pattern.
friend class JobDispatchInterface<JobDispatchAdapter>;

static constexpr Idx ignore_output{-1};

std::unique_ptr<MainModel> model_copy_;
std::reference_wrapper<MainModel> model_;

main_core::utils::ComponentFlags<ComponentType...> components_to_update_{};
main_core::update::independence::UpdateIndependence<ComponentType...> update_independence_{};
main_core::utils::ComponentFlags<ComponentType...> independence_flags_{};
std::shared_ptr<main_core::utils::SequenceIdx<ComponentType...>> all_scenarios_sequence_;
// 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_;

// TODO(figueroa1395): Keep calculation_fn at the adapter level only
template <typename Calculate>
requires std::invocable<std::remove_cvref_t<Calculate>, MainModel&, MutableDataset const&, Idx>
void calculate_impl(Calculate&& calculation_fn, MutableDataset const& result_data, Idx scenario_idx) const {
std::forward<Calculate>(calculation_fn)(model_.get(), result_data, scenario_idx);
}

template <typename Calculate>
requires std::invocable<std::remove_cvref_t<Calculate>, MainModel&, MutableDataset const&, Idx>
void cache_calculate_impl(Calculate&& calculation_fn) const {
// calculate once to cache topology, ignore results, all math solvers are initialized
try {
std::forward<Calculate>(calculation_fn)(model_.get(),
{
false,
1,
"sym_output",
model_.get().meta_data(),
},
ignore_output);
} catch (SparseMatrixError const&) { // NOLINT(bugprone-empty-catch) // NOSONAR
// missing entries are provided in the update data
} catch (NotObservableError const&) { // NOLINT(bugprone-empty-catch) // NOSONAR
// missing entries are provided in the update data
}
}

void prepare_job_dispatch_impl(ConstDataset const& update_data) {
// cache component update order where possible.
// the order for a cacheable (independent) component by definition is the same across all scenarios
components_to_update_ = model_.get().get_components_to_update(update_data);
update_independence_ = main_core::update::independence::check_update_independence<ComponentType...>(
model_.get().state(), update_data);
std::ranges::transform(update_independence_, independence_flags_.begin(),
[](auto const& comp) { return comp.is_independent(); });
all_scenarios_sequence_ = std::make_shared<main_core::utils::SequenceIdx<ComponentType...>>(
main_core::update::get_all_sequence_idx_map<ComponentType...>(
model_.get().state(), update_data, 0, components_to_update_, update_independence_, false));
}

void setup_impl(ConstDataset const& update_data, Idx scenario_idx) {
current_scenario_sequence_cache_ = main_core::update::get_all_sequence_idx_map<ComponentType...>(
model_.get().state(), update_data, scenario_idx, components_to_update_, update_independence_, true);
auto const current_scenario_sequence = get_current_scenario_sequence_view_();
model_.get().template update_components<cached_update_t>(update_data, scenario_idx, current_scenario_sequence);
}

void winddown_impl() {
model_.get().restore_components(get_current_scenario_sequence_view_());
std::ranges::for_each(current_scenario_sequence_cache_, [](auto& comp_seq_idx) { comp_seq_idx.clear(); });
}

CalculationInfo get_calculation_info_impl() const { return model_.get().calculation_info(); }

void thread_safe_add_calculation_info_impl(CalculationInfo const& info) {
std::lock_guard const lock{calculation_info_mutex_};
model_.get().merge_calculation_info(info);
}

auto get_current_scenario_sequence_view_() const {
return main_core::utils::run_functor_with_all_types_return_array<ComponentType...>([this]<typename CT>() {
constexpr auto comp_idx = main_core::utils::index_of_component<CT, ComponentType...>;
if (std::get<comp_idx>(independence_flags_)) {
return std::span<Idx2D const>{std::get<comp_idx>(*all_scenarios_sequence_)};
}
return std::span<Idx2D const>{std::get<comp_idx>(current_scenario_sequence_cache_)};
});
}
};
} // namespace power_grid_model
Loading
Loading