From 808c3b4442ea989cdc1fa6aba16d11ca5811d6ce Mon Sep 17 00:00:00 2001 From: Martijn Govers Date: Mon, 15 Jan 2024 12:18:07 +0100 Subject: [PATCH 01/13] move to lippincott pattern, setup and winddown scenario Signed-off-by: Martijn Govers --- .../include/power_grid_model/main_model.hpp | 116 +++++++++++++----- tests/cpp_unit_tests/test_main_model.cpp | 2 +- 2 files changed, 83 insertions(+), 35 deletions(-) diff --git a/power_grid_model_c/power_grid_model/include/power_grid_model/main_model.hpp b/power_grid_model_c/power_grid_model/include/power_grid_model/main_model.hpp index 5d213a901..96a059313 100644 --- a/power_grid_model_c/power_grid_model/include/power_grid_model/main_model.hpp +++ b/power_grid_model_c/power_grid_model/include/power_grid_model/main_model.hpp @@ -391,6 +391,37 @@ class MainModelImpl, ComponentLis }); } + template + static auto call_with(auto&& run, auto&& setup, auto&& winddown, auto&& handle_exception, auto&& recover_from_bad) + requires std::invocable, Args const&...> && + std::invocable, Args const&...> && + std::invocable, Args const&...> && + std::invocable, Args const&...> && + std::invocable, Args const&...> && + std::same_as, void> && + std::same_as, void> && + std::same_as, void> && + std::same_as, void> && + std::same_as, void> + { + return [setup_ = std::move(setup), run_ = std::move(run), winddown_ = std::move(winddown), + handle_exception_ = std::move(handle_exception), + recover_from_bad_ = std::move(recover_from_bad)](Args const&... args) { + try { + setup_(args...); + run_(args...); + winddown_(args...); + } catch (...) { + handle_exception_(args...); + try { + winddown_(args...); + } catch (...) { + recover_from_bad_(args...); + } + } + }; + } + /* run the calculation function in batch on the provided update data. @@ -451,47 +482,28 @@ class MainModelImpl, ComponentLis is_independent](Idx start, Idx stride) { Timer const t_total(infos[start], 0000, "Total in thread"); - auto model = [&base_model, &infos, start] { - Timer const t_copy_model(infos[start], 1100, "Copy model"); + auto copy_model = [&base_model, &infos](Idx scenario_idx) { + Timer const t_copy_model(infos[scenario_idx], 1100, "Copy model"); return MainModelImpl{base_model}; - }(); + }; + auto model = copy_model(start); SequenceIdx scenario_sequence = is_independent ? model.get_sequence_idx_map(update_data) : SequenceIdx{}; + auto&& [setup, winddown] = + scenario_update_restore(model, update_data, is_independent, scenario_sequence, infos); + + auto calculate_scenario = MainModelImpl::call_with( + [&model, &calculation_fn, &result_data, is_independent, &infos](Idx scenario_idx) { + calculation_fn(model, result_data, scenario_idx); + }, + setup, winddown, scenario_exception_handler(model, exceptions, infos), + [&model, ©_model](Idx scenario_idx) { model = copy_model(scenario_idx); }); + for (Idx batch_number = start; batch_number < n_batch; batch_number += stride) { Timer const t_total_single(infos[batch_number], 0100, "Total single calculation in thread"); - // try to update model and run calculation - try { - { - Timer const t_update_model(infos[batch_number], 1200, "Update model"); - if (!is_independent) { - scenario_sequence = model.get_sequence_idx_map(update_data, batch_number); - } - model.template update_component(update_data, batch_number, scenario_sequence); - } - calculation_fn(model, result_data, batch_number); - { - Timer const t_update_model(infos[batch_number], 1201, "Restore model"); - model.restore_components(scenario_sequence); - if (!is_independent) { - std::ranges::for_each(scenario_sequence, [](auto& comp_seq_idx) { comp_seq_idx.clear(); }); - } - } - } catch (std::exception const& ex) { - exceptions[batch_number] = ex.what(); - model = [&base_model, &infos, start] { - Timer const t_copy_model(infos[start], 1100, "Copy model"); - return MainModelImpl{base_model}; - }(); - } catch (...) { - exceptions[batch_number] = "unknown exception"; - model = [&base_model, &infos, start] { - Timer const t_copy_model(infos[start], 1100, "Copy model"); - return MainModelImpl{base_model}; - }(); - } - infos[batch_number].merge(model.calculation_info_); + calculate_scenario(batch_number); } }; @@ -524,6 +536,42 @@ class MainModelImpl, ComponentLis return BatchParameter{}; } + static auto scenario_update_restore(MainModelImpl& model, ConstDataset const& update_data, + bool const is_independent, SequenceIdx& scenario_sequence, + std::vector& infos) { + return std::make_pair( + [&model, &update_data, &scenario_sequence, is_independent, &infos](Idx scenario_idx) { + Timer const t_update_model(infos[scenario_idx], 1200, "Update model"); + if (!is_independent) { + scenario_sequence = model.get_sequence_idx_map(update_data, scenario_idx); + } + model.template update_component(update_data, scenario_idx, scenario_sequence); + }, + [&model, &scenario_sequence, is_independent, &infos](Idx scenario_idx) { + Timer const t_update_model(infos[scenario_idx], 1201, "Restore model"); + model.restore_components(scenario_sequence); + if (!is_independent) { + std::ranges::for_each(scenario_sequence, [](auto& comp_seq_idx) { comp_seq_idx.clear(); }); + } + }); + } + + // Lippincott pattern + static auto scenario_exception_handler(MainModelImpl& model, std::vector& messages, + std::vector& infos) { + return [&model, &messages, &infos](Idx scenario_idx) { + std::exception_ptr ex_ptr = std::current_exception(); + try { + std::rethrow_exception(ex_ptr); + } catch (std::exception const& ex) { + messages[scenario_idx] = ex.what(); + } catch (...) { + messages[scenario_idx] = "unknown exception"; + } + infos[scenario_idx].merge(model.calculation_info_); + }; + } + static void handle_batch_exceptions(std::vector const& exceptions) { std::string combined_error_message; IdxVector failed_scenarios; diff --git a/tests/cpp_unit_tests/test_main_model.cpp b/tests/cpp_unit_tests/test_main_model.cpp index 18f2392ad..55fb8b58a 100644 --- a/tests/cpp_unit_tests/test_main_model.cpp +++ b/tests/cpp_unit_tests/test_main_model.cpp @@ -1272,7 +1272,7 @@ TEST_CASE("Test main model - incomplete input") { } } -TEST_CASE("Incomplete followed by complete") { +TEST_CASE("Test main model - Incomplete followed by complete") { using CalculationMethod::linear; State state; From cd1f37506d122a5be596239f0b7ad881ff7d9c3f Mon Sep 17 00:00:00 2001 From: Martijn Govers Date: Mon, 15 Jan 2024 12:38:47 +0100 Subject: [PATCH 02/13] also isolate dispatch Signed-off-by: Martijn Govers --- .../include/power_grid_model/main_model.hpp | 51 ++++++++++++------- 1 file changed, 34 insertions(+), 17 deletions(-) diff --git a/power_grid_model_c/power_grid_model/include/power_grid_model/main_model.hpp b/power_grid_model_c/power_grid_model/include/power_grid_model/main_model.hpp index 96a059313..d673f6bc6 100644 --- a/power_grid_model_c/power_grid_model/include/power_grid_model/main_model.hpp +++ b/power_grid_model_c/power_grid_model/include/power_grid_model/main_model.hpp @@ -467,19 +467,36 @@ class MainModelImpl, ComponentLis // missing entries are provided in the update data } + // error messages + std::vector exceptions(n_batch, ""); + std::vector infos(n_batch); + + // lambda for sub batch calculation + auto sub_batch = sub_batch_calculation_(calculation_fn, result_data, update_data, exceptions, infos); + + batch_dispatch(sub_batch, n_batch, threading); + + handle_batch_exceptions(exceptions); + calculation_info_ = main_core::merge_calculation_info(infos); + + return BatchParameter{}; + } + + template + requires std::invocable, MainModelImpl&, Dataset const&, Idx> + auto sub_batch_calculation_(Calculate&& calculation_fn, Dataset const& result_data, ConstDataset const& update_data, + std::vector& exceptions, std::vector& infos) { // const ref of current instance MainModelImpl const& base_model = *this; // cache component update order if possible bool const is_independent = MainModelImpl::is_update_independent(update_data); - // error messages - std::vector exceptions(n_batch, ""); - std::vector infos(n_batch); + return [&base_model, &exceptions, &infos, &calculation_fn, &result_data, &update_data, + is_independent](Idx start, Idx stride, Idx n_batch) { + assert(exceptions.size() >= n_batch); + assert(infos.size() >= n_batch); - // lambda for sub batch calculation - auto sub_batch = [&base_model, &exceptions, &infos, &calculation_fn, &result_data, &update_data, n_batch, - is_independent](Idx start, Idx stride) { Timer const t_total(infos[start], 0000, "Total in thread"); auto copy_model = [&base_model, &infos](Idx scenario_idx) { @@ -506,16 +523,21 @@ class MainModelImpl, ComponentLis calculate_scenario(batch_number); } }; + } + // run sequential if + // specified threading < 0 + // use hardware threads, but it is either unknown (0) or only has one thread (1) + // specified threading = 1 + static void batch_dispatch(auto&& sub_batch, Idx n_batch, Idx threading) + requires std::invocable, Idx /* start */, Idx /* stride */, + Idx /* n_batch */> + { // run batches sequential or parallel auto const hardware_thread = static_cast(std::thread::hardware_concurrency()); - // run sequential if - // specified threading < 0 - // use hardware threads, but it is either unknown (0) or only has one thread (1) - // specified threading = 1 if (threading < 0 || threading == 1 || (threading == 0 && hardware_thread < 2)) { // run all in sequential - sub_batch(0, 1); + sub_batch(0, 1, n_batch); } else { // create parallel threads Idx const n_thread = std::min(threading == 0 ? hardware_thread : threading, n_batch); @@ -523,17 +545,12 @@ class MainModelImpl, ComponentLis threads.reserve(n_thread); for (Idx thread_number = 0; thread_number < n_thread; ++thread_number) { // compute each sub batch with stride - threads.emplace_back(sub_batch, thread_number, n_thread); + threads.emplace_back(sub_batch, thread_number, n_thread, n_batch); } for (auto& thread : threads) { thread.join(); } } - - handle_batch_exceptions(exceptions); - calculation_info_ = main_core::merge_calculation_info(infos); - - return BatchParameter{}; } static auto scenario_update_restore(MainModelImpl& model, ConstDataset const& update_data, From 128e943876c875698b2721339c9ad73d1c818214 Mon Sep 17 00:00:00 2001 From: Martijn Govers Date: Mon, 15 Jan 2024 12:44:21 +0100 Subject: [PATCH 03/13] minor cleanup Signed-off-by: Martijn Govers --- .../include/power_grid_model/main_model.hpp | 62 +++++++++---------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/power_grid_model_c/power_grid_model/include/power_grid_model/main_model.hpp b/power_grid_model_c/power_grid_model/include/power_grid_model/main_model.hpp index d673f6bc6..1d3a85621 100644 --- a/power_grid_model_c/power_grid_model/include/power_grid_model/main_model.hpp +++ b/power_grid_model_c/power_grid_model/include/power_grid_model/main_model.hpp @@ -391,37 +391,6 @@ class MainModelImpl, ComponentLis }); } - template - static auto call_with(auto&& run, auto&& setup, auto&& winddown, auto&& handle_exception, auto&& recover_from_bad) - requires std::invocable, Args const&...> && - std::invocable, Args const&...> && - std::invocable, Args const&...> && - std::invocable, Args const&...> && - std::invocable, Args const&...> && - std::same_as, void> && - std::same_as, void> && - std::same_as, void> && - std::same_as, void> && - std::same_as, void> - { - return [setup_ = std::move(setup), run_ = std::move(run), winddown_ = std::move(winddown), - handle_exception_ = std::move(handle_exception), - recover_from_bad_ = std::move(recover_from_bad)](Args const&... args) { - try { - setup_(args...); - run_(args...); - winddown_(args...); - } catch (...) { - handle_exception_(args...); - try { - winddown_(args...); - } catch (...) { - recover_from_bad_(args...); - } - } - }; - } - /* run the calculation function in batch on the provided update data. @@ -553,6 +522,37 @@ class MainModelImpl, ComponentLis } } + template + static auto call_with(auto&& run, auto&& setup, auto&& winddown, auto&& handle_exception, auto&& recover_from_bad) + requires std::invocable, Args const&...> && + std::invocable, Args const&...> && + std::invocable, Args const&...> && + std::invocable, Args const&...> && + std::invocable, Args const&...> && + std::same_as, void> && + std::same_as, void> && + std::same_as, void> && + std::same_as, void> && + std::same_as, void> + { + return [setup_ = std::move(setup), run_ = std::move(run), winddown_ = std::move(winddown), + handle_exception_ = std::move(handle_exception), + recover_from_bad_ = std::move(recover_from_bad)](Args const&... args) { + try { + setup_(args...); + run_(args...); + winddown_(args...); + } catch (...) { + handle_exception_(args...); + try { + winddown_(args...); + } catch (...) { + recover_from_bad_(args...); + } + } + }; + } + static auto scenario_update_restore(MainModelImpl& model, ConstDataset const& update_data, bool const is_independent, SequenceIdx& scenario_sequence, std::vector& infos) { From 6b6e974161d758d6b5149d00ad7b5ecc4de868ef Mon Sep 17 00:00:00 2001 From: Martijn Govers Date: Mon, 15 Jan 2024 12:53:25 +0100 Subject: [PATCH 04/13] fix Signed-off-by: Martijn Govers --- .../power_grid_model/include/power_grid_model/main_model.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/power_grid_model_c/power_grid_model/include/power_grid_model/main_model.hpp b/power_grid_model_c/power_grid_model/include/power_grid_model/main_model.hpp index 1d3a85621..5c21b0826 100644 --- a/power_grid_model_c/power_grid_model/include/power_grid_model/main_model.hpp +++ b/power_grid_model_c/power_grid_model/include/power_grid_model/main_model.hpp @@ -463,8 +463,8 @@ class MainModelImpl, ComponentLis return [&base_model, &exceptions, &infos, &calculation_fn, &result_data, &update_data, is_independent](Idx start, Idx stride, Idx n_batch) { - assert(exceptions.size() >= n_batch); - assert(infos.size() >= n_batch); + assert(n_batch <= narrow_cast(exceptions.size())); + assert(n_batch <= narrow_cast(infos.size())); Timer const t_total(infos[start], 0000, "Total in thread"); From 84a05dbcb40781c1c46ded53bd1ae6363fe91837 Mon Sep 17 00:00:00 2001 From: Martijn Govers Date: Mon, 15 Jan 2024 14:13:08 +0100 Subject: [PATCH 05/13] fix clang Signed-off-by: Martijn Govers --- .../power_grid_model/include/power_grid_model/main_model.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/power_grid_model_c/power_grid_model/include/power_grid_model/main_model.hpp b/power_grid_model_c/power_grid_model/include/power_grid_model/main_model.hpp index 5c21b0826..2eadd9575 100644 --- a/power_grid_model_c/power_grid_model/include/power_grid_model/main_model.hpp +++ b/power_grid_model_c/power_grid_model/include/power_grid_model/main_model.hpp @@ -480,7 +480,7 @@ class MainModelImpl, ComponentLis scenario_update_restore(model, update_data, is_independent, scenario_sequence, infos); auto calculate_scenario = MainModelImpl::call_with( - [&model, &calculation_fn, &result_data, is_independent, &infos](Idx scenario_idx) { + [&model, &calculation_fn, &result_data, is_independent](Idx scenario_idx) { calculation_fn(model, result_data, scenario_idx); }, setup, winddown, scenario_exception_handler(model, exceptions, infos), From 3f23daaf844d3db77606b740c32deb4e4f02ef6e Mon Sep 17 00:00:00 2001 From: Martijn Govers Date: Mon, 15 Jan 2024 14:19:01 +0100 Subject: [PATCH 06/13] fix clang-tidy Signed-off-by: Martijn Govers --- .../include/power_grid_model/main_model.hpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/power_grid_model_c/power_grid_model/include/power_grid_model/main_model.hpp b/power_grid_model_c/power_grid_model/include/power_grid_model/main_model.hpp index 2eadd9575..4c7b7d307 100644 --- a/power_grid_model_c/power_grid_model/include/power_grid_model/main_model.hpp +++ b/power_grid_model_c/power_grid_model/include/power_grid_model/main_model.hpp @@ -476,14 +476,14 @@ class MainModelImpl, ComponentLis SequenceIdx scenario_sequence = is_independent ? model.get_sequence_idx_map(update_data) : SequenceIdx{}; - auto&& [setup, winddown] = + auto [setup, winddown] = scenario_update_restore(model, update_data, is_independent, scenario_sequence, infos); auto calculate_scenario = MainModelImpl::call_with( [&model, &calculation_fn, &result_data, is_independent](Idx scenario_idx) { calculation_fn(model, result_data, scenario_idx); }, - setup, winddown, scenario_exception_handler(model, exceptions, infos), + std::move(setup), std::move(winddown), scenario_exception_handler(model, exceptions, infos), [&model, ©_model](Idx scenario_idx) { model = copy_model(scenario_idx); }); for (Idx batch_number = start; batch_number < n_batch; batch_number += stride) { @@ -523,7 +523,7 @@ class MainModelImpl, ComponentLis } template - static auto call_with(auto&& run, auto&& setup, auto&& winddown, auto&& handle_exception, auto&& recover_from_bad) + static auto call_with(auto run, auto setup, auto winddown, auto handle_exception, auto recover_from_bad) requires std::invocable, Args const&...> && std::invocable, Args const&...> && std::invocable, Args const&...> && @@ -535,9 +535,10 @@ class MainModelImpl, ComponentLis std::same_as, void> && std::same_as, void> { - return [setup_ = std::move(setup), run_ = std::move(run), winddown_ = std::move(winddown), - handle_exception_ = std::move(handle_exception), - recover_from_bad_ = std::move(recover_from_bad)](Args const&... args) { + return [setup_ = std::forward(setup), run_ = std::forward(run), + winddown_ = std::forward(winddown), + handle_exception_ = std::forward(handle_exception), + recover_from_bad_ = std::forward(recover_from_bad)](Args const&... args) { try { setup_(args...); run_(args...); @@ -577,7 +578,7 @@ class MainModelImpl, ComponentLis static auto scenario_exception_handler(MainModelImpl& model, std::vector& messages, std::vector& infos) { return [&model, &messages, &infos](Idx scenario_idx) { - std::exception_ptr ex_ptr = std::current_exception(); + std::exception_ptr const ex_ptr = std::current_exception(); try { std::rethrow_exception(ex_ptr); } catch (std::exception const& ex) { From 5f4a5a6a78a504d8432b995f366ad77941377635 Mon Sep 17 00:00:00 2001 From: Martijn Govers Date: Mon, 15 Jan 2024 14:23:35 +0100 Subject: [PATCH 07/13] minor Signed-off-by: Martijn Govers --- .../power_grid_model/include/power_grid_model/main_model.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/power_grid_model_c/power_grid_model/include/power_grid_model/main_model.hpp b/power_grid_model_c/power_grid_model/include/power_grid_model/main_model.hpp index 4c7b7d307..19cd426e9 100644 --- a/power_grid_model_c/power_grid_model/include/power_grid_model/main_model.hpp +++ b/power_grid_model_c/power_grid_model/include/power_grid_model/main_model.hpp @@ -480,7 +480,7 @@ class MainModelImpl, ComponentLis scenario_update_restore(model, update_data, is_independent, scenario_sequence, infos); auto calculate_scenario = MainModelImpl::call_with( - [&model, &calculation_fn, &result_data, is_independent](Idx scenario_idx) { + [&model, &calculation_fn, &result_data](Idx scenario_idx) { calculation_fn(model, result_data, scenario_idx); }, std::move(setup), std::move(winddown), scenario_exception_handler(model, exceptions, infos), From 92ea25f3eb37094eba623101cf501ba77338186a Mon Sep 17 00:00:00 2001 From: Martijn Govers Date: Mon, 15 Jan 2024 14:40:20 +0100 Subject: [PATCH 08/13] re-add info after successful run Signed-off-by: Martijn Govers --- .../include/power_grid_model/main_model.hpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/power_grid_model_c/power_grid_model/include/power_grid_model/main_model.hpp b/power_grid_model_c/power_grid_model/include/power_grid_model/main_model.hpp index 19cd426e9..dafacc28c 100644 --- a/power_grid_model_c/power_grid_model/include/power_grid_model/main_model.hpp +++ b/power_grid_model_c/power_grid_model/include/power_grid_model/main_model.hpp @@ -480,8 +480,9 @@ class MainModelImpl, ComponentLis scenario_update_restore(model, update_data, is_independent, scenario_sequence, infos); auto calculate_scenario = MainModelImpl::call_with( - [&model, &calculation_fn, &result_data](Idx scenario_idx) { + [&model, &calculation_fn, &result_data, &infos](Idx scenario_idx) { calculation_fn(model, result_data, scenario_idx); + infos[scenario_idx].merge(model.calculation_info_); }, std::move(setup), std::move(winddown), scenario_exception_handler(model, exceptions, infos), [&model, ©_model](Idx scenario_idx) { model = copy_model(scenario_idx); }); @@ -535,10 +536,9 @@ class MainModelImpl, ComponentLis std::same_as, void> && std::same_as, void> { - return [setup_ = std::forward(setup), run_ = std::forward(run), - winddown_ = std::forward(winddown), - handle_exception_ = std::forward(handle_exception), - recover_from_bad_ = std::forward(recover_from_bad)](Args const&... args) { + return [setup_ = std::move(setup), run_ = std::move(run), winddown_ = std::move(winddown), + handle_exception_ = std::move(handle_exception), + recover_from_bad_ = std::move(recover_from_bad)](Args const&... args) { try { setup_(args...); run_(args...); From e900303f8ec411320c386ad0b3144a9764fafc87 Mon Sep 17 00:00:00 2001 From: Martijn Govers Date: Mon, 15 Jan 2024 15:42:01 +0100 Subject: [PATCH 09/13] more clang tidy Signed-off-by: Martijn Govers --- tests/cpp_unit_tests/test_main_model.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/tests/cpp_unit_tests/test_main_model.cpp b/tests/cpp_unit_tests/test_main_model.cpp index 55fb8b58a..1a464c7a8 100644 --- a/tests/cpp_unit_tests/test_main_model.cpp +++ b/tests/cpp_unit_tests/test_main_model.cpp @@ -1095,11 +1095,10 @@ auto incomplete_input_model(State const& state) -> MainModel { std::vector const incomplete_source_input{{6, 1, 1, nan, nan, 1e12, nan, nan}, {10, 3, 1, nan, nan, 1e12, nan, nan}}; - std::vector incomplete_sym_load_input{{7, 3, 1, LoadGenType::const_y, nan, 0.0}}; - std::vector incomplete_asym_load_input{ + std::vector const incomplete_sym_load_input{{7, 3, 1, LoadGenType::const_y, nan, 0.0}}; + std::vector const incomplete_asym_load_input{ {8, 3, 1, LoadGenType::const_y, RealValue{nan}, RealValue{0.0}}}; - ConstDataset input_data; main_model.add_component(state.node_input); main_model.add_component(state.line_input); main_model.add_component(state.link_input); @@ -1119,7 +1118,7 @@ TEST_CASE("Test main model - incomplete input") { using CalculationMethod::linear_current; using CalculationMethod::newton_raphson; - State state; + State const state; auto main_model = default_model(state); auto test_model = incomplete_input_model(state); @@ -1275,7 +1274,7 @@ TEST_CASE("Test main model - incomplete input") { TEST_CASE("Test main model - Incomplete followed by complete") { using CalculationMethod::linear; - State state; + State const state; auto main_model = default_model(state); auto test_model = incomplete_input_model(state); From 779520e45b1c2eb9d21d191fa1db3515d29bc487 Mon Sep 17 00:00:00 2001 From: Martijn Govers Date: Tue, 16 Jan 2024 09:47:46 +0100 Subject: [PATCH 10/13] fix sonarcloud Signed-off-by: Martijn Govers --- .../include/power_grid_model/main_model.hpp | 28 ++++++++----------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/power_grid_model_c/power_grid_model/include/power_grid_model/main_model.hpp b/power_grid_model_c/power_grid_model/include/power_grid_model/main_model.hpp index dafacc28c..747d39ebf 100644 --- a/power_grid_model_c/power_grid_model/include/power_grid_model/main_model.hpp +++ b/power_grid_model_c/power_grid_model/include/power_grid_model/main_model.hpp @@ -499,10 +499,10 @@ class MainModelImpl, ComponentLis // specified threading < 0 // use hardware threads, but it is either unknown (0) or only has one thread (1) // specified threading = 1 - static void batch_dispatch(auto&& sub_batch, Idx n_batch, Idx threading) - requires std::invocable, Idx /* start */, Idx /* stride */, + template + requires std::invocable, Idx /* start */, Idx /* stride */, Idx /* n_batch */> - { + static void batch_dispatch(RunSubBatchFn sub_batch, Idx n_batch, Idx threading) { // run batches sequential or parallel auto const hardware_thread = static_cast(std::thread::hardware_concurrency()); if (threading < 0 || threading == 1 || (threading == 0 && hardware_thread < 2)) { @@ -523,19 +523,15 @@ class MainModelImpl, ComponentLis } } - template - static auto call_with(auto run, auto setup, auto winddown, auto handle_exception, auto recover_from_bad) - requires std::invocable, Args const&...> && - std::invocable, Args const&...> && - std::invocable, Args const&...> && - std::invocable, Args const&...> && - std::invocable, Args const&...> && - std::same_as, void> && - std::same_as, void> && - std::same_as, void> && - std::same_as, void> && - std::same_as, void> - { + template + requires std::invocable, Args const&...> && + std::invocable, Args const&...> && + std::invocable, Args const&...> && + std::invocable, Args const&...> && + std::invocable, Args const&...> + static auto call_with(RunFn run, SetupFn setup, WinddownFn winddown, HandleExceptionFn handle_exception, + RecoverFromBadFn recover_from_bad) { return [setup_ = std::move(setup), run_ = std::move(run), winddown_ = std::move(winddown), handle_exception_ = std::move(handle_exception), recover_from_bad_ = std::move(recover_from_bad)](Args const&... args) { From 414f7545e6c899f79080fc947b6e4e13ed84c065 Mon Sep 17 00:00:00 2001 From: Martijn Govers Date: Tue, 16 Jan 2024 09:48:45 +0100 Subject: [PATCH 11/13] fix sonarcloud Signed-off-by: Martijn Govers --- .../power_grid_model/include/power_grid_model/main_model.hpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/power_grid_model_c/power_grid_model/include/power_grid_model/main_model.hpp b/power_grid_model_c/power_grid_model/include/power_grid_model/main_model.hpp index 747d39ebf..d6922b430 100644 --- a/power_grid_model_c/power_grid_model/include/power_grid_model/main_model.hpp +++ b/power_grid_model_c/power_grid_model/include/power_grid_model/main_model.hpp @@ -500,8 +500,7 @@ class MainModelImpl, ComponentLis // use hardware threads, but it is either unknown (0) or only has one thread (1) // specified threading = 1 template - requires std::invocable, Idx /* start */, Idx /* stride */, - Idx /* n_batch */> + requires std::invocable, Idx /*start*/, Idx /*stride*/, Idx /*n_batch*/> static void batch_dispatch(RunSubBatchFn sub_batch, Idx n_batch, Idx threading) { // run batches sequential or parallel auto const hardware_thread = static_cast(std::thread::hardware_concurrency()); From 8430ff0c447497fca83a88d11493e129b384e964 Mon Sep 17 00:00:00 2001 From: Martijn Govers Date: Tue, 16 Jan 2024 10:04:08 +0100 Subject: [PATCH 12/13] fix compilation Signed-off-by: Martijn Govers --- .../power_grid_model/include/power_grid_model/main_model.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/power_grid_model_c/power_grid_model/include/power_grid_model/main_model.hpp b/power_grid_model_c/power_grid_model/include/power_grid_model/main_model.hpp index d6922b430..c6f727261 100644 --- a/power_grid_model_c/power_grid_model/include/power_grid_model/main_model.hpp +++ b/power_grid_model_c/power_grid_model/include/power_grid_model/main_model.hpp @@ -522,8 +522,8 @@ class MainModelImpl, ComponentLis } } - template + template requires std::invocable, Args const&...> && std::invocable, Args const&...> && std::invocable, Args const&...> && From 9add3996c9d73b5125037fb612cb9993770e7ca6 Mon Sep 17 00:00:00 2001 From: Martijn Govers Date: Tue, 16 Jan 2024 10:51:42 +0100 Subject: [PATCH 13/13] consistent variable names Signed-off-by: Martijn Govers --- .../include/power_grid_model/main_model.hpp | 39 +++++++++---------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/power_grid_model_c/power_grid_model/include/power_grid_model/main_model.hpp b/power_grid_model_c/power_grid_model/include/power_grid_model/main_model.hpp index c6f727261..c11660037 100644 --- a/power_grid_model_c/power_grid_model/include/power_grid_model/main_model.hpp +++ b/power_grid_model_c/power_grid_model/include/power_grid_model/main_model.hpp @@ -411,21 +411,20 @@ class MainModelImpl, ComponentLis // execute one power flow in the current instance, no batch calculation is needed // NOTE: if the map is not empty but the datasets inside are empty // that will be considered as a zero batch_size - bool const all_empty = update_data.empty(); - if (all_empty) { + if (update_data.empty()) { calculation_fn(*this, result_data, 0); return BatchParameter{}; } - // get number of batches (can't be empty, because then all_empty would have been true) - Idx const n_batch = update_data.cbegin()->second.batch_size(); + // get batch size (can't be empty; see previous check) + Idx const n_scenarios = update_data.cbegin()->second.batch_size(); // assert if all component types have the same number of batches assert(std::all_of(update_data.cbegin(), update_data.cend(), - [n_batch](auto const& x) { return x.second.batch_size() == n_batch; })); + [n_scenarios](auto const& x) { return x.second.batch_size() == n_scenarios; })); // if the batch_size is zero, it is a special case without doing any calculations at all // we consider in this case the batch set is independent and but not topology cachable - if (n_batch == 0) { + if (n_scenarios == 0) { return BatchParameter{}; } @@ -437,13 +436,13 @@ class MainModelImpl, ComponentLis } // error messages - std::vector exceptions(n_batch, ""); - std::vector infos(n_batch); + std::vector exceptions(n_scenarios, ""); + std::vector infos(n_scenarios); // lambda for sub batch calculation auto sub_batch = sub_batch_calculation_(calculation_fn, result_data, update_data, exceptions, infos); - batch_dispatch(sub_batch, n_batch, threading); + batch_dispatch(sub_batch, n_scenarios, threading); handle_batch_exceptions(exceptions); calculation_info_ = main_core::merge_calculation_info(infos); @@ -462,9 +461,9 @@ class MainModelImpl, ComponentLis bool const is_independent = MainModelImpl::is_update_independent(update_data); return [&base_model, &exceptions, &infos, &calculation_fn, &result_data, &update_data, - is_independent](Idx start, Idx stride, Idx n_batch) { - assert(n_batch <= narrow_cast(exceptions.size())); - assert(n_batch <= narrow_cast(infos.size())); + is_independent](Idx start, Idx stride, Idx n_scenarios) { + assert(n_scenarios <= narrow_cast(exceptions.size())); + assert(n_scenarios <= narrow_cast(infos.size())); Timer const t_total(infos[start], 0000, "Total in thread"); @@ -487,10 +486,10 @@ class MainModelImpl, ComponentLis std::move(setup), std::move(winddown), scenario_exception_handler(model, exceptions, infos), [&model, ©_model](Idx scenario_idx) { model = copy_model(scenario_idx); }); - for (Idx batch_number = start; batch_number < n_batch; batch_number += stride) { - Timer const t_total_single(infos[batch_number], 0100, "Total single calculation in thread"); + for (Idx scenario_idx = start; scenario_idx < n_scenarios; scenario_idx += stride) { + Timer const t_total_single(infos[scenario_idx], 0100, "Total single calculation in thread"); - calculate_scenario(batch_number); + calculate_scenario(scenario_idx); } }; } @@ -500,21 +499,21 @@ class MainModelImpl, ComponentLis // use hardware threads, but it is either unknown (0) or only has one thread (1) // specified threading = 1 template - requires std::invocable, Idx /*start*/, Idx /*stride*/, Idx /*n_batch*/> - static void batch_dispatch(RunSubBatchFn sub_batch, Idx n_batch, Idx threading) { + requires std::invocable, Idx /*start*/, Idx /*stride*/, Idx /*n_scenarios*/> + static void batch_dispatch(RunSubBatchFn sub_batch, Idx n_scenarios, Idx threading) { // run batches sequential or parallel auto const hardware_thread = static_cast(std::thread::hardware_concurrency()); if (threading < 0 || threading == 1 || (threading == 0 && hardware_thread < 2)) { // run all in sequential - sub_batch(0, 1, n_batch); + sub_batch(0, 1, n_scenarios); } else { // create parallel threads - Idx const n_thread = std::min(threading == 0 ? hardware_thread : threading, n_batch); + Idx const n_thread = std::min(threading == 0 ? hardware_thread : threading, n_scenarios); std::vector threads; threads.reserve(n_thread); for (Idx thread_number = 0; thread_number < n_thread; ++thread_number) { // compute each sub batch with stride - threads.emplace_back(sub_batch, thread_number, n_thread, n_batch); + threads.emplace_back(sub_batch, thread_number, n_thread, n_scenarios); } for (auto& thread : threads) { thread.join();