From 457db220fbceff108a4cddacd325f8610f09a721 Mon Sep 17 00:00:00 2001 From: Jerry Guo Date: Tue, 3 Sep 2024 17:04:10 +0200 Subject: [PATCH 01/18] added attribute functions for `const` and `mutable` Signed-off-by: Jerry Guo --- .../include/power_grid_model_c/dataset.h | 24 +++++++++++++++++++ .../power_grid_model_c/src/dataset.cpp | 14 +++++++++++ .../include/power_grid_model_cpp/dataset.hpp | 18 ++++++++++++++ 3 files changed, 56 insertions(+) diff --git a/power_grid_model_c/power_grid_model_c/include/power_grid_model_c/dataset.h b/power_grid_model_c/power_grid_model_c/include/power_grid_model_c/dataset.h index 98c0e463e..5b4cb904f 100644 --- a/power_grid_model_c/power_grid_model_c/include/power_grid_model_c/dataset.h +++ b/power_grid_model_c/power_grid_model_c/include/power_grid_model_c/dataset.h @@ -147,6 +147,18 @@ PGM_API void PGM_dataset_const_add_buffer(PGM_Handle* handle, PGM_ConstDataset* PGM_Idx elements_per_scenario, PGM_Idx total_elements, PGM_Idx const* indptr, void const* data); +/** + * @brief Add a attribute buffer to an instance of PGM_ConstDataset/component. + * @param handle + * @param dataset The pointer to the PGM_ConstDataset. + * @param component The name of the component. + * @param attribute The name of the attribute. + * @param data A void pointer to the buffer data. + * @return + */ +PGM_API void PGM_dataset_const_add_attribute_buffer(PGM_Handle* handle, PGM_ConstDataset* dataset, + char const* component, char const* attribute, void const* data); + /** * @brief Get the dataset info of the instance PGM_ConstDataset. * @param handle @@ -220,6 +232,18 @@ PGM_API void PGM_dataset_mutable_add_buffer(PGM_Handle* handle, PGM_MutableDatas PGM_Idx elements_per_scenario, PGM_Idx total_elements, PGM_Idx const* indptr, void* data); +/** + * @brief Add a attribute buffer to an instance of PGM_MutableDataset/component. + * @param handle + * @param dataset The pointer to the PGM_MutableDataset. + * @param component The name of the component. + * @param attribute The name of the attribute. + * @param data A void pointer to the buffer data. + * @return + */ +PGM_API void PGM_dataset_mutable_add_attribute_buffer(PGM_Handle* handle, PGM_MutableDataset* dataset, + char const* component, char const* attribute, void* data); + /** * @brief Get the dataset info of the instance PGM_MutableDataset. * @param handle diff --git a/power_grid_model_c/power_grid_model_c/src/dataset.cpp b/power_grid_model_c/power_grid_model_c/src/dataset.cpp index 8af04f0b6..7cd483c09 100644 --- a/power_grid_model_c/power_grid_model_c/src/dataset.cpp +++ b/power_grid_model_c/power_grid_model_c/src/dataset.cpp @@ -79,6 +79,13 @@ void PGM_dataset_const_add_buffer(PGM_Handle* handle, PGM_ConstDataset* dataset, PGM_regular_error); } +void PGM_dataset_const_add_attribute_buffer(PGM_Handle* handle, PGM_ConstDataset* dataset, char const* component, + char const* attribute, void const* data) { + call_with_catch( + handle, [dataset, component, attribute, data]() { dataset->add_attribute_buffer(component, attribute, data); }, + PGM_regular_error); +} + PGM_DatasetInfo const* PGM_dataset_const_get_info(PGM_Handle* /*unused*/, PGM_ConstDataset const* dataset) { return &dataset->get_description(); } @@ -121,6 +128,13 @@ void PGM_dataset_mutable_add_buffer(PGM_Handle* handle, PGM_MutableDataset* data PGM_regular_error); } +void PGM_dataset_mutable_add_attribute_buffer(PGM_Handle* handle, PGM_MutableDataset* dataset, char const* component, + char const* attribute, void* data) { + call_with_catch( + handle, [dataset, component, attribute, data]() { dataset->add_attribute_buffer(component, attribute, data); }, + PGM_regular_error); +} + PGM_DatasetInfo const* PGM_dataset_mutable_get_info(PGM_Handle* /*unused*/, PGM_MutableDataset const* dataset) { return &dataset->get_description(); } diff --git a/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/dataset.hpp b/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/dataset.hpp index bc9291755..75ea5496f 100644 --- a/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/dataset.hpp +++ b/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/dataset.hpp @@ -129,6 +129,24 @@ class DatasetMutable { add_buffer(*this, component, elements_per_scenario, total_elements, indptr, data); } + static void add_attribute_buffer(DatasetMutable const& dataset, std::string const& component, + std::string const& attribute, RawDataPtr data) { + dataset.handle_.call_with(PGM_dataset_mutable_add_attribute_buffer, dataset.dataset_.get(), component.c_str(), + attribute.c_str(), data); + } + void add_attribute_buffer(std::string const& component, std::string const& attribute, RawDataPtr data) const { + add_attribute_buffer(*this, component.c_str(), attribute.c_str(), data); + } + + static void add_attribute_buffer(DatasetMutable const& dataset, std::string const& component, + std::string const& attribute, Buffer const& data) { + dataset.handle_.call_with(PGM_dataset_mutable_add_attribute_buffer, dataset.dataset_.get(), component.c_str(), + attribute.c_str(), data.get()); + } + void add_attribute_buffer(std::string const& component, std::string const& attribute, Buffer const& data) const { + add_attribute_buffer(*this, component, attribute, data); + } + static DatasetInfo const& get_info(DatasetMutable const& dataset) { return dataset.info_; } DatasetInfo const& get_info() const { return get_info(*this); } From 1b763bcf421dea569a9a1bb60e0d76edc95f0619 Mon Sep 17 00:00:00 2001 From: Jerry Guo Date: Wed, 4 Sep 2024 11:27:19 +0200 Subject: [PATCH 02/18] added for const and few minor fixes Signed-off-by: Jerry Guo --- .../power_grid_model/auxiliary/dataset.hpp | 2 +- .../power_grid_model/sparse_ordering.hpp | 7 ++---- .../include/power_grid_model_cpp/dataset.hpp | 22 +++++++++++++++++-- .../include/power_grid_model_cpp/handle.hpp | 6 ++--- tests/c_api_tests/test_cpp_api_model.cpp | 3 +-- .../test_cpp_api_serialization.cpp | 4 ++-- tests/cpp_unit_tests/test_observability.cpp | 2 +- .../test_transformer_tap_regulator.cpp | 8 +++---- 8 files changed, 34 insertions(+), 20 deletions(-) diff --git a/power_grid_model_c/power_grid_model/include/power_grid_model/auxiliary/dataset.hpp b/power_grid_model_c/power_grid_model/include/power_grid_model/auxiliary/dataset.hpp index cf9ca8cd8..0896d96bd 100644 --- a/power_grid_model_c/power_grid_model/include/power_grid_model/auxiliary/dataset.hpp +++ b/power_grid_model_c/power_grid_model/include/power_grid_model/auxiliary/dataset.hpp @@ -298,7 +298,7 @@ template class Dataset { }) != buffer.attributes.end()) { throw DatasetError{"Cannot have duplicated attribute buffers!\n"}; } - AttributeBuffer attribute_buffer{ + AttributeBuffer const attribute_buffer{ .data = data, .meta_attribute = &dataset_info_.component_info[idx].component->get_attribute(attribute)}; buffer.attributes.emplace_back(attribute_buffer); } diff --git a/power_grid_model_c/power_grid_model/include/power_grid_model/sparse_ordering.hpp b/power_grid_model_c/power_grid_model/include/power_grid_model/sparse_ordering.hpp index 41c9622fd..43a59cff6 100644 --- a/power_grid_model_c/power_grid_model/include/power_grid_model/sparse_ordering.hpp +++ b/power_grid_model_c/power_grid_model/include/power_grid_model/sparse_ordering.hpp @@ -120,11 +120,8 @@ inline std::vector> check_indistguishable(Idx co } inline bool in_graph(std::pair const& e, std::map const& d) { - if (auto edges_it = d.find(e.first); - edges_it != d.cend() && std::ranges::find(edges_it->second, e.second) != edges_it->second.cend()) { - return true; - } - return false; + auto edges_it = d.find(e.first); + return edges_it != d.cend() && std::ranges::find(edges_it->second, e.second) != edges_it->second.cend(); } inline IdxVector remove_vertices_update_degrees(Idx const u, std::map& d, DegreeLookup& dgd, diff --git a/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/dataset.hpp b/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/dataset.hpp index 75ea5496f..adcfb0b8e 100644 --- a/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/dataset.hpp +++ b/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/dataset.hpp @@ -116,7 +116,7 @@ class DatasetMutable { } void add_buffer(std::string const& component, Idx elements_per_scenario, Idx total_elements, Idx const* indptr, RawDataPtr data) const { - add_buffer(*this, component.c_str(), elements_per_scenario, total_elements, indptr, data); + add_buffer(*this, component, elements_per_scenario, total_elements, indptr, data); } static void add_buffer(DatasetMutable const& dataset, std::string const& component, Idx elements_per_scenario, @@ -135,7 +135,7 @@ class DatasetMutable { attribute.c_str(), data); } void add_attribute_buffer(std::string const& component, std::string const& attribute, RawDataPtr data) const { - add_attribute_buffer(*this, component.c_str(), attribute.c_str(), data); + add_attribute_buffer(*this, component, attribute, data); } static void add_attribute_buffer(DatasetMutable const& dataset, std::string const& component, @@ -190,6 +190,24 @@ class DatasetConst { add_buffer(*this, component, elements_per_scenario, total_elements, indptr, data); } + static void add_attribute_buffer(DatasetConst const& dataset, std::string const& component, + std::string const& attribute, RawDataConstPtr data) { + dataset.handle_.call_with(PGM_dataset_const_add_attribute_buffer, dataset.dataset_.get(), component.c_str(), + attribute.c_str(), data); + } + void add_attribute_buffer(std::string const& component, std::string const& attribute, RawDataConstPtr data) const { + add_attribute_buffer(*this, component, attribute, data); + } + + static void add_attribute_buffer(DatasetConst const& dataset, std::string const& component, + std::string const& attribute, Buffer const& data) { + dataset.handle_.call_with(PGM_dataset_const_add_attribute_buffer, dataset.dataset_.get(), component.c_str(), + attribute.c_str(), data.get()); + } + void add_attribute_buffer(std::string const& component, std::string const& attribute, Buffer const& data) const { + add_attribute_buffer(*this, component, attribute, data); + } + static DatasetInfo const& get_info(DatasetConst const& dataset) { return dataset.info_; } DatasetInfo const& get_info() const { return get_info(*this); } diff --git a/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/handle.hpp b/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/handle.hpp index 6111f0cc8..8ead96848 100644 --- a/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/handle.hpp +++ b/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/handle.hpp @@ -13,7 +13,7 @@ namespace power_grid_model_cpp { class PowerGridError : public std::exception { public: - PowerGridError(const std::string& message) : message_(message) {} + PowerGridError(std::string message) : message_(std::move(message)) {} const char* what() const noexcept override { return message_.c_str(); } virtual Idx error_code() const noexcept { return PGM_regular_error; }; @@ -69,8 +69,8 @@ class Handle { case PGM_batch_error: { Idx const n_failed_scenarios = PGM_n_failed_scenarios(handle_ptr); std::vector failed_scenarios(n_failed_scenarios); - auto const failed_scenario_seqs = PGM_failed_scenarios(handle_ptr); - auto const failed_scenario_messages = PGM_batch_errors(handle_ptr); + const auto* const failed_scenario_seqs = PGM_failed_scenarios(handle_ptr); + const auto* const failed_scenario_messages = PGM_batch_errors(handle_ptr); for (Idx i = 0; i < n_failed_scenarios; ++i) { failed_scenarios[i] = PowerGridBatchError::FailedScenario{failed_scenario_seqs[i], failed_scenario_messages[i]}; diff --git a/tests/c_api_tests/test_cpp_api_model.cpp b/tests/c_api_tests/test_cpp_api_model.cpp index 1018e7627..c4a068f26 100644 --- a/tests/c_api_tests/test_cpp_api_model.cpp +++ b/tests/c_api_tests/test_cpp_api_model.cpp @@ -134,7 +134,6 @@ TEST_CASE("C++ API Model") { load_updates_buffer.set_value(PGM_def_update_sym_load_id, load_updates_id.data(), -1); load_updates_buffer.set_value(PGM_def_update_sym_load_q_specified, load_updates_q_specified.data(), 0, -1); load_updates_buffer.set_value(PGM_def_update_sym_load_q_specified, load_updates_q_specified.data(), 1, -1); - // dataset DatasetConst single_update_dataset{"update", 0, 1}; single_update_dataset.add_buffer("source", 1, 1, nullptr, source_update_buffer); @@ -180,7 +179,7 @@ TEST_CASE("C++ API Model") { } SUBCASE("Copy model") { - Model model_copy{model}; + Model const& model_copy{model}; model_copy.calculate(options, single_output_dataset); node_output.get_value(PGM_def_sym_output_node_id, node_result_id.data(), -1); node_output.get_value(PGM_def_sym_output_node_energized, node_result_energized.data(), 0, -1); diff --git a/tests/c_api_tests/test_cpp_api_serialization.cpp b/tests/c_api_tests/test_cpp_api_serialization.cpp index 0c1753b88..45e442937 100644 --- a/tests/c_api_tests/test_cpp_api_serialization.cpp +++ b/tests/c_api_tests/test_cpp_api_serialization.cpp @@ -130,7 +130,7 @@ TEST_CASE("C++ API Serialization and Deserialization") { auto check_deserializer = [&](Deserializer& deserializer) { // get dataset auto& dataset = deserializer.get_dataset(); - auto& info = dataset.get_info(); + auto const& info = dataset.get_info(); // check meta data check_metadata(info); // set buffer @@ -160,7 +160,7 @@ TEST_CASE("C++ API Serialization and Deserialization") { // get dataset auto& dataset = deserializer_json.get_dataset(); - auto& info = dataset.get_info(); + auto const& info = dataset.get_info(); // check meta data CHECK(info.name() == "input"s); CHECK(info.is_batch() == is_batch); diff --git a/tests/cpp_unit_tests/test_observability.cpp b/tests/cpp_unit_tests/test_observability.cpp index 7892ec983..21006a09e 100644 --- a/tests/cpp_unit_tests/test_observability.cpp +++ b/tests/cpp_unit_tests/test_observability.cpp @@ -11,7 +11,7 @@ namespace power_grid_model { namespace { -void check_not_observable(MathModelTopology const& topo, MathModelParam param, +void check_not_observable(MathModelTopology const& topo, MathModelParam const& param, StateEstimationInput const& se_input) { auto topo_ptr = std::make_shared(topo); auto param_ptr = std::make_shared const>(param); diff --git a/tests/cpp_unit_tests/test_transformer_tap_regulator.cpp b/tests/cpp_unit_tests/test_transformer_tap_regulator.cpp index cd5e423d5..a16aba9b0 100644 --- a/tests/cpp_unit_tests/test_transformer_tap_regulator.cpp +++ b/tests/cpp_unit_tests/test_transformer_tap_regulator.cpp @@ -20,7 +20,7 @@ void check_nan_preserving_equality(std::floating_point auto actual, std::floatin TEST_CASE("Test transformer tap regulator") { TransformerTapRegulatorInput const input{.id = 1, .regulated_object = 2, - .status = true, + .status = 1, .control_side = ControlSide::from, .u_set = 10.0e3, .u_band = 1.0e3, @@ -63,7 +63,7 @@ TEST_CASE("Test transformer tap regulator") { SUBCASE("Test update") { SUBCASE("Set all values") { TransformerTapRegulatorUpdate const update{.id = 1, - .status = false, + .status = 0, .u_set = 11.0e3, .u_band = 2.0e3, .line_drop_compensation_r = 2.0, @@ -144,7 +144,7 @@ TEST_CASE("Test transformer tap regulator") { SUBCASE("multiple") { update.id = 1; - update.status = false; + update.status = 0; update.u_set = 11.0e3; update.u_band = 2.0e3; update.line_drop_compensation_r = 2.0; @@ -201,7 +201,7 @@ TEST_CASE("Test transformer tap regulator") { SUBCASE("Test default line drop compensation") { TransformerTapRegulator regulator{{.id = 1, .regulated_object = 2, - .status = true, + .status = 1, .control_side = ControlSide::from, .u_set = 10.0e3, .u_band = 1.0e3}, From db9189e09aae77a5e4205ae4fd7b45e6fdbe54ae Mon Sep 17 00:00:00 2001 From: Jerry Guo Date: Wed, 4 Sep 2024 11:43:51 +0200 Subject: [PATCH 03/18] clang-tidy Signed-off-by: Jerry Guo --- .../include/power_grid_model_cpp/handle.hpp | 4 +-- .../power_grid_model_cpp/meta_data.hpp | 34 +++++++++---------- tests/c_api_tests/test_cpp_api_model.cpp | 16 ++++----- .../test_cpp_api_serialization.cpp | 12 +++---- 4 files changed, 33 insertions(+), 33 deletions(-) diff --git a/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/handle.hpp b/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/handle.hpp index 8ead96848..3451f1816 100644 --- a/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/handle.hpp +++ b/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/handle.hpp @@ -58,8 +58,8 @@ class Handle { static void check_error(Handle const& handle) { RawHandle const* handle_ptr = handle.get(); - Idx error_code = PGM_error_code(handle_ptr); - std::string error_message = error_code == PGM_no_error ? "" : PGM_error_message(handle_ptr); + Idx const error_code = PGM_error_code(handle_ptr); + std::string const error_message = error_code == PGM_no_error ? "" : PGM_error_message(handle_ptr); switch (error_code) { case PGM_no_error: return; diff --git a/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/meta_data.hpp b/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/meta_data.hpp index 2f6d89eff..4736bdb82 100644 --- a/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/meta_data.hpp +++ b/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/meta_data.hpp @@ -15,88 +15,88 @@ namespace power_grid_model_cpp { class MetaData { public: static Idx n_datasets() { - Handle handle{}; + Handle const handle{}; return handle.call_with(PGM_meta_n_datasets); } static MetaDataset const* get_dataset_by_idx(Idx idx) { - Handle handle{}; + Handle const handle{}; return handle.call_with(PGM_meta_get_dataset_by_idx, idx); } static MetaDataset const* get_dataset_by_name(std::string const& dataset) { - Handle handle{}; + Handle const handle{}; return handle.call_with(PGM_meta_get_dataset_by_name, dataset.c_str()); } static std::string dataset_name(MetaDataset const* dataset) { - Handle handle{}; + Handle const handle{}; return std::string{handle.call_with(PGM_meta_dataset_name, dataset)}; } static Idx n_components(MetaDataset const* dataset) { - Handle handle{}; + Handle const handle{}; return handle.call_with(PGM_meta_n_components, dataset); } static MetaComponent const* get_component_by_idx(MetaDataset const* dataset, Idx idx) { - Handle handle{}; + Handle const handle{}; return handle.call_with(PGM_meta_get_component_by_idx, dataset, idx); } static MetaComponent const* get_component_by_name(std::string const& dataset, std::string const& component) { - Handle handle{}; + Handle const handle{}; return handle.call_with(PGM_meta_get_component_by_name, dataset.c_str(), component.c_str()); } static std::string component_name(MetaComponent const* component) { - Handle handle{}; + Handle const handle{}; return std::string{handle.call_with(PGM_meta_component_name, component)}; } static size_t component_size(MetaComponent const* component) { - Handle handle{}; + Handle const handle{}; return handle.call_with(PGM_meta_component_size, component); } static size_t component_alignment(MetaComponent const* component) { - Handle handle{}; + Handle const handle{}; return handle.call_with(PGM_meta_component_alignment, component); } static Idx n_attributes(MetaComponent const* component) { - Handle handle{}; + Handle const handle{}; return handle.call_with(PGM_meta_n_attributes, component); } static MetaAttribute const* get_attribute_by_idx(MetaComponent const* component, Idx idx) { - Handle handle{}; + Handle const handle{}; return handle.call_with(PGM_meta_get_attribute_by_idx, component, idx); } static MetaAttribute const* get_attribute_by_name(std::string const& dataset, std::string const& component, std::string const& attribute) { - Handle handle{}; + Handle const handle{}; return handle.call_with(PGM_meta_get_attribute_by_name, dataset.c_str(), component.c_str(), attribute.c_str()); } static std::string attribute_name(MetaAttribute const* attribute) { - Handle handle{}; + Handle const handle{}; return std::string{handle.call_with(PGM_meta_attribute_name, attribute)}; } static Idx attribute_ctype(MetaAttribute const* attribute) { - Handle handle{}; + Handle const handle{}; return handle.call_with(PGM_meta_attribute_ctype, attribute); } static size_t attribute_offset(MetaAttribute const* attribute) { - Handle handle{}; + Handle const handle{}; return handle.call_with(PGM_meta_attribute_offset, attribute); } static int is_little_endian() { - Handle handle{}; + Handle const handle{}; return handle.call_with(PGM_is_little_endian); } }; diff --git a/tests/c_api_tests/test_cpp_api_model.cpp b/tests/c_api_tests/test_cpp_api_model.cpp index c4a068f26..e15d00428 100644 --- a/tests/c_api_tests/test_cpp_api_model.cpp +++ b/tests/c_api_tests/test_cpp_api_model.cpp @@ -46,10 +46,10 @@ void check_exception(PowerGridError const& e, PGM_ErrorCode const& reference_err TEST_CASE("C++ API Model") { using namespace std::string_literals; - Options options{}; + Options const options{}; // input data - DatasetConst input_dataset{"input", 0, 1}; + DatasetConst const input_dataset{"input", 0, 1}; // node buffer ID node_id = 0; @@ -83,7 +83,7 @@ TEST_CASE("C++ API Model") { int8_t load_type = 2; double load_p_specified = 0.0; double load_q_specified = 500.0; - Buffer load_buffer{PGM_def_input_sym_load, 1}; + Buffer const load_buffer{PGM_def_input_sym_load, 1}; load_buffer.set_value(PGM_def_input_sym_load_id, &load_id, -1); load_buffer.set_value(PGM_def_input_sym_load_node, &load_node, -1); load_buffer.set_value(PGM_def_input_sym_load_status, &load_status, -1); @@ -99,11 +99,11 @@ TEST_CASE("C++ API Model") { // output data Buffer node_output{PGM_def_sym_output_node, 1}; node_output.set_nan(); - DatasetMutable single_output_dataset{"sym_output", 0, 1}; + DatasetMutable const single_output_dataset{"sym_output", 0, 1}; single_output_dataset.add_buffer("node", 1, 1, nullptr, node_output); Buffer node_batch_output{PGM_def_sym_output_node, 2}; node_batch_output.set_nan(); - DatasetMutable batch_output_dataset{"sym_output", 1, 2}; + DatasetMutable const batch_output_dataset{"sym_output", 1, 2}; batch_output_dataset.add_buffer("node", 1, 2, nullptr, node_batch_output); std::vector node_result_id(2); @@ -135,10 +135,10 @@ TEST_CASE("C++ API Model") { load_updates_buffer.set_value(PGM_def_update_sym_load_q_specified, load_updates_q_specified.data(), 0, -1); load_updates_buffer.set_value(PGM_def_update_sym_load_q_specified, load_updates_q_specified.data(), 1, -1); // dataset - DatasetConst single_update_dataset{"update", 0, 1}; + DatasetConst const single_update_dataset{"update", 0, 1}; single_update_dataset.add_buffer("source", 1, 1, nullptr, source_update_buffer); single_update_dataset.add_buffer("sym_load", 1, 1, nullptr, load_updates_buffer.get()); - DatasetConst batch_update_dataset{"update", 1, 2}; + DatasetConst const batch_update_dataset{"update", 1, 2}; batch_update_dataset.add_buffer("source", -1, 1, source_update_indptr.data(), source_update_buffer.get()); batch_update_dataset.add_buffer("sym_load", 1, 2, nullptr, load_updates_buffer); @@ -226,7 +226,7 @@ TEST_CASE("C++ API Model") { SUBCASE("Construction error") { load_id = 0; try { - Model wrong_model{50.0, input_dataset}; + Model const wrong_model{50.0, input_dataset}; } catch (PowerGridRegularError const& e) { check_exception(e, PGM_regular_error, "Conflicting id detected:"s); } diff --git a/tests/c_api_tests/test_cpp_api_serialization.cpp b/tests/c_api_tests/test_cpp_api_serialization.cpp index 45e442937..d1bdc8d6f 100644 --- a/tests/c_api_tests/test_cpp_api_serialization.cpp +++ b/tests/c_api_tests/test_cpp_api_serialization.cpp @@ -54,12 +54,12 @@ TEST_CASE("C++ API Serialization and Deserialization") { std::vector const total_elements = {1, 2}; SUBCASE("Serializer") { - DatasetConst dataset{"input", is_batch, batch_size}; + DatasetConst const dataset{"input", is_batch, batch_size}; dataset.add_buffer("node", elements_per_scenario[0], total_elements[0], nullptr, node_buffer); dataset.add_buffer("source", elements_per_scenario[1], total_elements[1], nullptr, source_buffer); SUBCASE("JSON") { - Serializer json_serializer{dataset, 0}; + Serializer const json_serializer{dataset, 0}; SUBCASE("To zero-terminated string") { std::string json_result = json_serializer.get_to_zero_terminated_string(0, -1); @@ -77,7 +77,7 @@ TEST_CASE("C++ API Serialization and Deserialization") { } SUBCASE("MessagePack") { - Serializer msgpack_serializer{dataset, 1}; + Serializer const msgpack_serializer{dataset, 1}; SUBCASE("Round trip") { std::vector msgpack_data{}; @@ -94,7 +94,7 @@ TEST_CASE("C++ API Serialization and Deserialization") { SUBCASE("Invalid serialization format") { try { - Serializer unknown_serializer{dataset, -1}; + Serializer const unknown_serializer{dataset, -1}; } catch (PowerGridSerializationError const& e) { CHECK(e.error_code() == PGM_serialization_error); } @@ -174,8 +174,8 @@ TEST_CASE("C++ API Serialization and Deserialization") { // parse deserializer_json.parse_to_buffer(); // create model from deserialized dataset - DatasetConst input_dataset{dataset}; - Model model{50.0, input_dataset}; + DatasetConst const input_dataset{dataset}; + Model const model{50.0, input_dataset}; } } From 0c3e73018c464b69c3f538f79eaef0df444b1bdf Mon Sep 17 00:00:00 2001 From: Jerry Guo Date: Wed, 4 Sep 2024 17:20:17 +0200 Subject: [PATCH 04/18] [skip ci] initial test added to add attribute buffer to the input dataset. `main_model_impl` still lacks functionality to accommodate columnar data input Signed-off-by: Jerry Guo --- tests/c_api_tests/test_cpp_api_model.cpp | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/tests/c_api_tests/test_cpp_api_model.cpp b/tests/c_api_tests/test_cpp_api_model.cpp index e15d00428..9583404b0 100644 --- a/tests/c_api_tests/test_cpp_api_model.cpp +++ b/tests/c_api_tests/test_cpp_api_model.cpp @@ -91,10 +91,20 @@ TEST_CASE("C++ API Model") { load_buffer.set_value(PGM_def_input_sym_load_p_specified, &load_p_specified, -1); load_buffer.set_value(PGM_def_input_sym_load_q_specified, &load_q_specified, -1); - // add buffers + // gen buffer (columnar) + std::vector gen_id = {3, 4}; + std::vector gen_node = {0, 0}; + std::vector gen_status = {0, 0}; + + // add buffers - row input_dataset.add_buffer("node", 1, 1, nullptr, node_buffer); input_dataset.add_buffer("sym_load", 1, 1, nullptr, load_buffer); input_dataset.add_buffer("source", 1, 1, nullptr, source_buffer); + // add buffers - columnar + input_dataset.add_buffer("sym_gen", 2, 2, nullptr, nullptr); + input_dataset.add_attribute_buffer("sym_gen", "id", &gen_id); + input_dataset.add_attribute_buffer("sym_gen", "node", &gen_node); + input_dataset.add_attribute_buffer("sym_gen", "status", &gen_status); // output data Buffer node_output{PGM_def_sym_output_node, 1}; @@ -138,11 +148,16 @@ TEST_CASE("C++ API Model") { DatasetConst const single_update_dataset{"update", 0, 1}; single_update_dataset.add_buffer("source", 1, 1, nullptr, source_update_buffer); single_update_dataset.add_buffer("sym_load", 1, 1, nullptr, load_updates_buffer.get()); + single_update_dataset.add_buffer("sym_gen", 2, 2, nullptr, nullptr); + single_update_dataset.add_attribute_buffer("sym_gen", "status", &gen_status); DatasetConst const batch_update_dataset{"update", 1, 2}; batch_update_dataset.add_buffer("source", -1, 1, source_update_indptr.data(), source_update_buffer.get()); batch_update_dataset.add_buffer("sym_load", 1, 2, nullptr, load_updates_buffer); + batch_update_dataset.add_buffer("sym_gen", 1, 2, nullptr, nullptr); + batch_update_dataset.add_attribute_buffer("sym_gen", "status", &gen_status); // create model + //FAIL("This test will fail here due to columnar data input."); Model model{50.0, input_dataset}; // test move-ability From 0d7444fefc8e6558fbfb81717ba5895afae86e26 Mon Sep 17 00:00:00 2001 From: Jerry Guo Date: Thu, 5 Sep 2024 16:00:38 +0200 Subject: [PATCH 05/18] added set for writable data Signed-off-by: Jerry Guo --- .../include/power_grid_model_c/dataset.h | 12 ++++++++++++ .../power_grid_model_c/src/dataset.cpp | 7 +++++++ tests/c_api_tests/test_cpp_api_model.cpp | 4 ++-- 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/power_grid_model_c/power_grid_model_c/include/power_grid_model_c/dataset.h b/power_grid_model_c/power_grid_model_c/include/power_grid_model_c/dataset.h index 5b4cb904f..c6aab7766 100644 --- a/power_grid_model_c/power_grid_model_c/include/power_grid_model_c/dataset.h +++ b/power_grid_model_c/power_grid_model_c/include/power_grid_model_c/dataset.h @@ -191,6 +191,18 @@ PGM_API PGM_DatasetInfo const* PGM_dataset_writable_get_info(PGM_Handle* handle, PGM_API void PGM_dataset_writable_set_buffer(PGM_Handle* handle, PGM_WritableDataset* dataset, char const* component, PGM_Idx* indptr, void* data); +/** + * @brief Set buffer into the instance PGM_WritableDataset. + * @param handle + * @param dataset A pointer to the PGM_WritableDataset. + * @param component The name of the component. + * @param component The name of the attribute. + * @param data A void pointer to the buffer data. + * @return + */ +PGM_API void PGM_dataset_writable_set_attribute_buffer(PGM_Handle* handle, PGM_WritableDataset* dataset, + char const* component, char const* attribute, void* data); + /** * @brief Create an instance of PGM_MutableDataset. * @param handle diff --git a/power_grid_model_c/power_grid_model_c/src/dataset.cpp b/power_grid_model_c/power_grid_model_c/src/dataset.cpp index 7cd483c09..37d3631ff 100644 --- a/power_grid_model_c/power_grid_model_c/src/dataset.cpp +++ b/power_grid_model_c/power_grid_model_c/src/dataset.cpp @@ -103,6 +103,13 @@ void PGM_dataset_writable_set_buffer(PGM_Handle* handle, PGM_WritableDataset* da PGM_regular_error); } +void PGM_dataset_writable_set_attribute_buffer(PGM_Handle* handle, PGM_WritableDataset* dataset, char const* component, + char const* attribute, void* data) { + call_with_catch( + handle, [dataset, component, attribute, data]() { dataset->add_attribute_buffer(component, attribute, data); }, + PGM_regular_error); +} + // mutable dataset PGM_MutableDataset* PGM_create_dataset_mutable(PGM_Handle* handle, char const* dataset, PGM_Idx is_batch, diff --git a/tests/c_api_tests/test_cpp_api_model.cpp b/tests/c_api_tests/test_cpp_api_model.cpp index 9583404b0..9b26f6876 100644 --- a/tests/c_api_tests/test_cpp_api_model.cpp +++ b/tests/c_api_tests/test_cpp_api_model.cpp @@ -100,7 +100,7 @@ TEST_CASE("C++ API Model") { input_dataset.add_buffer("node", 1, 1, nullptr, node_buffer); input_dataset.add_buffer("sym_load", 1, 1, nullptr, load_buffer); input_dataset.add_buffer("source", 1, 1, nullptr, source_buffer); - // add buffers - columnar + // add buffers - columnar input_dataset.add_buffer("sym_gen", 2, 2, nullptr, nullptr); input_dataset.add_attribute_buffer("sym_gen", "id", &gen_id); input_dataset.add_attribute_buffer("sym_gen", "node", &gen_node); @@ -157,7 +157,7 @@ TEST_CASE("C++ API Model") { batch_update_dataset.add_attribute_buffer("sym_gen", "status", &gen_status); // create model - //FAIL("This test will fail here due to columnar data input."); + // FAIL("This test will fail here due to columnar data input."); Model model{50.0, input_dataset}; // test move-ability From bd522d1433e526bd193b632ad1e05eca0f2e9a46 Mon Sep 17 00:00:00 2001 From: Jerry Guo Date: Thu, 5 Sep 2024 18:52:04 +0200 Subject: [PATCH 06/18] [skip ci] added `set_attribute_buffer` functionality for `WritableDataset`, updated relevant api calls Signed-off-by: Jerry Guo --- .../power_grid_model/auxiliary/dataset.hpp | 17 +++++++++++++++++ .../power_grid_model_c/src/dataset.cpp | 2 +- .../include/power_grid_model_cpp/dataset.hpp | 18 ++++++++++++++++++ 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/power_grid_model_c/power_grid_model/include/power_grid_model/auxiliary/dataset.hpp b/power_grid_model_c/power_grid_model/include/power_grid_model/auxiliary/dataset.hpp index 0896d96bd..655f7c27c 100644 --- a/power_grid_model_c/power_grid_model/include/power_grid_model/auxiliary/dataset.hpp +++ b/power_grid_model_c/power_grid_model/include/power_grid_model/auxiliary/dataset.hpp @@ -303,6 +303,23 @@ template class Dataset { buffer.attributes.emplace_back(attribute_buffer); } + void set_attribute_buffer(std::string_view component, std::string_view attribute, Data* data) + requires is_data_mutable_v + { + Idx const idx = find_component(component, true); + Buffer const& buffer = buffers_[idx]; + if (!is_columnar(buffer)) { + throw DatasetError{"Cannot set attribute buffers for row-based dataset!\n"}; + } + auto it = std::ranges::find_if(buffer.attributes, [&attribute](auto const& buffer_attribute) { + return buffer_attribute.meta_attribute->name == attribute; + }); + if (it == buffer.attributes.end()) { + throw DatasetError{"Attribute buffer not found!\n"}; + } + it->data = data; + } + // get buffer by component type template >> diff --git a/power_grid_model_c/power_grid_model_c/src/dataset.cpp b/power_grid_model_c/power_grid_model_c/src/dataset.cpp index 37d3631ff..3b19492b7 100644 --- a/power_grid_model_c/power_grid_model_c/src/dataset.cpp +++ b/power_grid_model_c/power_grid_model_c/src/dataset.cpp @@ -106,7 +106,7 @@ void PGM_dataset_writable_set_buffer(PGM_Handle* handle, PGM_WritableDataset* da void PGM_dataset_writable_set_attribute_buffer(PGM_Handle* handle, PGM_WritableDataset* dataset, char const* component, char const* attribute, void* data) { call_with_catch( - handle, [dataset, component, attribute, data]() { dataset->add_attribute_buffer(component, attribute, data); }, + handle, [dataset, component, attribute, data]() { dataset->set_attribute_buffer(component, attribute, data); }, PGM_regular_error); } diff --git a/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/dataset.hpp b/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/dataset.hpp index adcfb0b8e..daf04c0af 100644 --- a/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/dataset.hpp +++ b/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/dataset.hpp @@ -95,6 +95,24 @@ class DatasetWritable { set_buffer(*this, component, indptr, data); } + static void set_attribute_buffer(DatasetWritable& dataset, std::string const& component, + std::string const& attribute, RawDataPtr data) { + dataset.handle_.call_with(PGM_dataset_writable_set_attribute_buffer, dataset.dataset_, component.c_str(), + attribute.c_str(), data); + } + void set_attribute_buffer(std::string const& component, std::string const& attribute, RawDataPtr data) { + set_attribute_buffer(*this, component, attribute, data); + } + + static void set_attribute_buffer(DatasetWritable& dataset, std::string const& component, + std::string const& attribute, Buffer const& data) { + dataset.handle_.call_with(PGM_dataset_writable_set_attribute_buffer, dataset.dataset_, component.c_str(), + attribute.c_str(), data.get()); + } + void set_attribute_buffer(std::string const& component, std::string const& attribute, Buffer const& data) { + set_attribute_buffer(*this, component, attribute, data); + } + private: Handle handle_{}; RawWritableDataset* dataset_; From fdf1539ec33da8c7eae2c8696ecb04f8e92a81f4 Mon Sep 17 00:00:00 2001 From: Jerry Guo Date: Thu, 5 Sep 2024 20:16:25 +0200 Subject: [PATCH 07/18] [skip ci] minor Signed-off-by: Jerry Guo --- .../include/power_grid_model/auxiliary/dataset.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/power_grid_model_c/power_grid_model/include/power_grid_model/auxiliary/dataset.hpp b/power_grid_model_c/power_grid_model/include/power_grid_model/auxiliary/dataset.hpp index 655f7c27c..8ed8f438a 100644 --- a/power_grid_model_c/power_grid_model/include/power_grid_model/auxiliary/dataset.hpp +++ b/power_grid_model_c/power_grid_model/include/power_grid_model/auxiliary/dataset.hpp @@ -307,7 +307,7 @@ template class Dataset { requires is_data_mutable_v { Idx const idx = find_component(component, true); - Buffer const& buffer = buffers_[idx]; + Buffer& buffer = buffers_[idx]; if (!is_columnar(buffer)) { throw DatasetError{"Cannot set attribute buffers for row-based dataset!\n"}; } From 7b03cc34b653824e5fb0b8c018a0694f44dde757 Mon Sep 17 00:00:00 2001 From: Martijn Govers Date: Tue, 10 Sep 2024 08:16:15 +0200 Subject: [PATCH 08/18] add set attribute for writable dataset Signed-off-by: Martijn Govers --- .../power_grid_model/auxiliary/dataset.hpp | 40 +++++++++++------ tests/cpp_unit_tests/test_dataset.cpp | 8 +++- tests/cpp_unit_tests/test_deserializer.cpp | 44 +++++++++---------- 3 files changed, 55 insertions(+), 37 deletions(-) diff --git a/power_grid_model_c/power_grid_model/include/power_grid_model/auxiliary/dataset.hpp b/power_grid_model_c/power_grid_model/include/power_grid_model/auxiliary/dataset.hpp index 7ac46541e..468074544 100644 --- a/power_grid_model_c/power_grid_model/include/power_grid_model/auxiliary/dataset.hpp +++ b/power_grid_model_c/power_grid_model/include/power_grid_model/auxiliary/dataset.hpp @@ -302,20 +302,16 @@ template class Dataset { } } - void add_attribute_buffer(std::string_view component, std::string_view attribute, Data* data) { - Idx const idx = find_component(component, true); - Buffer& buffer = buffers_[idx]; - if (!is_columnar(buffer)) { - throw DatasetError{"Cannot add attribute buffers to row-based dataset!\n"}; - } - if (std::ranges::find_if(buffer.attributes, [&attribute](auto const& buffer_attribute) { - return buffer_attribute.meta_attribute->name == attribute; - }) != buffer.attributes.end()) { - throw DatasetError{"Cannot have duplicated attribute buffers!\n"}; - } - AttributeBuffer attribute_buffer{ - .data = data, .meta_attribute = &dataset_info_.component_info[idx].component->get_attribute(attribute)}; - buffer.attributes.emplace_back(attribute_buffer); + void add_attribute_buffer(std::string_view component, std::string_view attribute, Data* data) + requires(!is_indptr_mutable_v) + { + add_attribute_buffer_impl(component, attribute, data); + } + + void set_attribute_buffer(std::string_view component, std::string_view attribute, Data* data) + requires is_indptr_mutable_v + { + add_attribute_buffer_impl(component, attribute, data); } // get buffer by component type @@ -442,6 +438,22 @@ template class Dataset { buffers_.push_back(Buffer{}); } + void add_attribute_buffer_impl(std::string_view component, std::string_view attribute, Data* data) { + Idx const idx = find_component(component, true); + Buffer& buffer = buffers_[idx]; + if (!is_columnar(buffer)) { + throw DatasetError{"Cannot add attribute buffers to row-based dataset!\n"}; + } + if (std::ranges::find_if(buffer.attributes, [&attribute](auto const& buffer_attribute) { + return buffer_attribute.meta_attribute->name == attribute; + }) != buffer.attributes.end()) { + throw DatasetError{"Cannot have duplicated attribute buffers!\n"}; + } + AttributeBuffer attribute_buffer{ + .data = data, .meta_attribute = &dataset_info_.component_info[idx].component->get_attribute(attribute)}; + buffer.attributes.emplace_back(attribute_buffer); + } + template RangeType get_span_impl(RangeType const& total_range, Idx scenario, Buffer const& buffer, ComponentInfo const& info) const { diff --git a/tests/cpp_unit_tests/test_dataset.cpp b/tests/cpp_unit_tests/test_dataset.cpp index 94caafb61..02cb844dc 100644 --- a/tests/cpp_unit_tests/test_dataset.cpp +++ b/tests/cpp_unit_tests/test_dataset.cpp @@ -331,7 +331,13 @@ TEST_CASE_TEMPLATE("Test dataset (common)", DatasetType, ConstDataset, MutableDa } }; auto const add_attribute_buffer = [](DatasetType& dataset, std::string_view name, std::string_view attribute, - auto* data) { dataset.add_attribute_buffer(name, attribute, data); }; + auto* data) { + if constexpr (std::same_as) { + dataset.set_attribute_buffer(name, attribute, data); + } else { + dataset.add_attribute_buffer(name, attribute, data); + } + }; auto const add_homogeneous_buffer = [&add_buffer](DatasetType& dataset, std::string_view name, Idx elements_per_scenario, void* data) { add_buffer(dataset, name, elements_per_scenario, elements_per_scenario * dataset.batch_size(), nullptr, data); diff --git a/tests/cpp_unit_tests/test_deserializer.cpp b/tests/cpp_unit_tests/test_deserializer.cpp index 1eb4d7650..ea0563234 100644 --- a/tests/cpp_unit_tests/test_deserializer.cpp +++ b/tests/cpp_unit_tests/test_deserializer.cpp @@ -358,23 +358,23 @@ TEST_CASE("Deserializer") { auto& info = deserializer.get_dataset_info(); info.set_buffer("node", nullptr, nullptr); - info.add_attribute_buffer("node", "id", node_id.data()); - info.add_attribute_buffer("node", "u_rated", node_u_rated.data()); + info.set_attribute_buffer("node", "id", node_id.data()); + info.set_attribute_buffer("node", "u_rated", node_u_rated.data()); info.set_buffer("line", nullptr, nullptr); - info.add_attribute_buffer("line", "id", line_id.data()); - info.add_attribute_buffer("line", "r1", line_r1.data()); - info.add_attribute_buffer("line", "r0", line_r0.data()); - info.add_attribute_buffer("line", "x1", line_x1.data()); - info.add_attribute_buffer("line", "x0", line_x0.data()); + info.set_attribute_buffer("line", "id", line_id.data()); + info.set_attribute_buffer("line", "r1", line_r1.data()); + info.set_attribute_buffer("line", "r0", line_r0.data()); + info.set_attribute_buffer("line", "x1", line_x1.data()); + info.set_attribute_buffer("line", "x0", line_x0.data()); info.set_buffer("source", nullptr, nullptr); - info.add_attribute_buffer("source", "id", source_id.data()); - info.add_attribute_buffer("source", "u_ref", source_u_ref.data()); - info.add_attribute_buffer("source", "sk", source_sk.data()); - info.add_attribute_buffer("source", "rx_ratio", source_rx_ratio.data()); + info.set_attribute_buffer("source", "id", source_id.data()); + info.set_attribute_buffer("source", "u_ref", source_u_ref.data()); + info.set_attribute_buffer("source", "sk", source_sk.data()); + info.set_attribute_buffer("source", "rx_ratio", source_rx_ratio.data()); info.set_buffer("sym_load", nullptr, nullptr); - info.add_attribute_buffer("sym_load", "id", sym_load_id.data()); - info.add_attribute_buffer("sym_load", "p_specified", sym_load_p_specified.data()); - info.add_attribute_buffer("sym_load", "q_specified", sym_load_q_specified.data()); + info.set_attribute_buffer("sym_load", "id", sym_load_id.data()); + info.set_attribute_buffer("sym_load", "p_specified", sym_load_p_specified.data()); + info.set_attribute_buffer("sym_load", "q_specified", sym_load_q_specified.data()); deserializer.parse(); // check node @@ -498,15 +498,15 @@ TEST_CASE("Deserializer") { auto& info = deserializer.get_dataset_info(); info.set_buffer("sym_load", sym_load_indptr.data(), nullptr); - info.add_attribute_buffer("sym_load", "id", sym_load_id.data()); - info.add_attribute_buffer("sym_load", "status", sym_load_status.data()); - info.add_attribute_buffer("sym_load", "p_specified", sym_load_p_specified.data()); - info.add_attribute_buffer("sym_load", "q_specified", sym_load_q_specified.data()); + info.set_attribute_buffer("sym_load", "id", sym_load_id.data()); + info.set_attribute_buffer("sym_load", "status", sym_load_status.data()); + info.set_attribute_buffer("sym_load", "p_specified", sym_load_p_specified.data()); + info.set_attribute_buffer("sym_load", "q_specified", sym_load_q_specified.data()); info.set_buffer("asym_load", nullptr, nullptr); - info.add_attribute_buffer("asym_load", "id", asym_load_id.data()); - info.add_attribute_buffer("asym_load", "status", asym_load_status.data()); - info.add_attribute_buffer("asym_load", "p_specified", asym_load_p_specified.data()); - info.add_attribute_buffer("asym_load", "q_specified", asym_load_q_specified.data()); + info.set_attribute_buffer("asym_load", "id", asym_load_id.data()); + info.set_attribute_buffer("asym_load", "status", asym_load_status.data()); + info.set_attribute_buffer("asym_load", "p_specified", asym_load_p_specified.data()); + info.set_attribute_buffer("asym_load", "q_specified", asym_load_q_specified.data()); deserializer.parse(); From 354dbecd3e638c572a95d17fab23c331f139a59b Mon Sep 17 00:00:00 2001 From: Martijn Govers Date: Tue, 10 Sep 2024 09:19:23 +0200 Subject: [PATCH 09/18] clang-tidy Signed-off-by: Martijn Govers --- .../include/power_grid_model/auxiliary/dataset.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/power_grid_model_c/power_grid_model/include/power_grid_model/auxiliary/dataset.hpp b/power_grid_model_c/power_grid_model/include/power_grid_model/auxiliary/dataset.hpp index ad3aea54e..02df0fcbd 100644 --- a/power_grid_model_c/power_grid_model/include/power_grid_model/auxiliary/dataset.hpp +++ b/power_grid_model_c/power_grid_model/include/power_grid_model/auxiliary/dataset.hpp @@ -449,7 +449,7 @@ template class Dataset { }) != buffer.attributes.end()) { throw DatasetError{"Cannot have duplicated attribute buffers!\n"}; } - AttributeBuffer attribute_buffer{ + AttributeBuffer const attribute_buffer{ .data = data, .meta_attribute = &dataset_info_.component_info[idx].component->get_attribute(attribute)}; buffer.attributes.emplace_back(attribute_buffer); } From ab9a41d002e47888388d2d482c45b23d19240699 Mon Sep 17 00:00:00 2001 From: Martijn Govers Date: Tue, 10 Sep 2024 09:33:50 +0200 Subject: [PATCH 10/18] minor fixes Signed-off-by: Martijn Govers --- .../power_grid_model_c/include/power_grid_model_c/dataset.h | 2 +- .../include/power_grid_model_cpp/handle.hpp | 4 ++-- tests/c_api_tests/test_cpp_api_model.cpp | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/power_grid_model_c/power_grid_model_c/include/power_grid_model_c/dataset.h b/power_grid_model_c/power_grid_model_c/include/power_grid_model_c/dataset.h index c6aab7766..0a4b2b378 100644 --- a/power_grid_model_c/power_grid_model_c/include/power_grid_model_c/dataset.h +++ b/power_grid_model_c/power_grid_model_c/include/power_grid_model_c/dataset.h @@ -196,7 +196,7 @@ PGM_API void PGM_dataset_writable_set_buffer(PGM_Handle* handle, PGM_WritableDat * @param handle * @param dataset A pointer to the PGM_WritableDataset. * @param component The name of the component. - * @param component The name of the attribute. + * @param attribute The name of the attribute. * @param data A void pointer to the buffer data. * @return */ diff --git a/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/handle.hpp b/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/handle.hpp index 3451f1816..84ec8283b 100644 --- a/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/handle.hpp +++ b/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/handle.hpp @@ -69,8 +69,8 @@ class Handle { case PGM_batch_error: { Idx const n_failed_scenarios = PGM_n_failed_scenarios(handle_ptr); std::vector failed_scenarios(n_failed_scenarios); - const auto* const failed_scenario_seqs = PGM_failed_scenarios(handle_ptr); - const auto* const failed_scenario_messages = PGM_batch_errors(handle_ptr); + auto const* const failed_scenario_seqs = PGM_failed_scenarios(handle_ptr); + auto const* const failed_scenario_messages = PGM_batch_errors(handle_ptr); for (Idx i = 0; i < n_failed_scenarios; ++i) { failed_scenarios[i] = PowerGridBatchError::FailedScenario{failed_scenario_seqs[i], failed_scenario_messages[i]}; diff --git a/tests/c_api_tests/test_cpp_api_model.cpp b/tests/c_api_tests/test_cpp_api_model.cpp index 9b26f6876..492609f91 100644 --- a/tests/c_api_tests/test_cpp_api_model.cpp +++ b/tests/c_api_tests/test_cpp_api_model.cpp @@ -194,7 +194,7 @@ TEST_CASE("C++ API Model") { } SUBCASE("Copy model") { - Model const& model_copy{model}; + Model model_copy{model}; model_copy.calculate(options, single_output_dataset); node_output.get_value(PGM_def_sym_output_node_id, node_result_id.data(), -1); node_output.get_value(PGM_def_sym_output_node_energized, node_result_energized.data(), 0, -1); From 405fd945cb1cbf390bd6d069de3ec6511445d912 Mon Sep 17 00:00:00 2001 From: Martijn Govers Date: Tue, 10 Sep 2024 09:37:07 +0200 Subject: [PATCH 11/18] fail to fixme Signed-off-by: Martijn Govers --- tests/c_api_tests/test_cpp_api_model.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/c_api_tests/test_cpp_api_model.cpp b/tests/c_api_tests/test_cpp_api_model.cpp index 492609f91..cc0433937 100644 --- a/tests/c_api_tests/test_cpp_api_model.cpp +++ b/tests/c_api_tests/test_cpp_api_model.cpp @@ -157,7 +157,7 @@ TEST_CASE("C++ API Model") { batch_update_dataset.add_attribute_buffer("sym_gen", "status", &gen_status); // create model - // FAIL("This test will fail here due to columnar data input."); + // FIXME(mgovers): This test will fail here due to columnar data input; Model model{50.0, input_dataset}; // test move-ability From a1505f959e3270025273bb1e27a4848a65bfbfd0 Mon Sep 17 00:00:00 2001 From: Jerry Guo Date: Fri, 13 Sep 2024 15:09:47 +0200 Subject: [PATCH 12/18] [skip ci] batch fixed; vector destruction fixed. update still fails. Signed-off-by: Jerry Guo --- .../power_grid_model/main_core/input.hpp | 5 +- .../power_grid_model/main_core/update.hpp | 3 +- tests/c_api_tests/test_cpp_api_model.cpp | 151 ++++++++++++------ 3 files changed, 107 insertions(+), 52 deletions(-) diff --git a/power_grid_model_c/power_grid_model/include/power_grid_model/main_core/input.hpp b/power_grid_model_c/power_grid_model/include/power_grid_model/main_core/input.hpp index 67a2124fb..409a27f39 100644 --- a/power_grid_model_c/power_grid_model/include/power_grid_model/main_core/input.hpp +++ b/power_grid_model_c/power_grid_model/include/power_grid_model/main_core/input.hpp @@ -28,7 +28,10 @@ inline void add_component(MainModelState& state, ForwardIter using ComponentView = std::conditional_t, typename Component::InputType const&, typename Component::InputType>; - reserve_component(state, std::distance(begin, end)); + // DEBUG + auto dist = std::distance(begin, end); + // DEBUG + reserve_component(state, /*std::distance(begin, end)*/ dist); // do sanity check on the transformer tap regulator std::vector regulated_objects; // loop to add component diff --git a/power_grid_model_c/power_grid_model/include/power_grid_model/main_core/update.hpp b/power_grid_model_c/power_grid_model/include/power_grid_model/main_core/update.hpp index 71ee3f7c4..bfa1206ac 100644 --- a/power_grid_model_c/power_grid_model/include/power_grid_model/main_core/update.hpp +++ b/power_grid_model_c/power_grid_model/include/power_grid_model/main_core/update.hpp @@ -46,7 +46,8 @@ template get_component_sequence(MainModelState const& state, ForwardIterator begin, ForwardIterator end) { std::vector result; - result.reserve(std::distance(begin, end)); + auto const dist = std::distance(begin, end); + result.reserve(/*std::distance(begin, end)*/ dist); get_component_sequence(state, begin, end, std::back_inserter(result)); return result; } diff --git a/tests/c_api_tests/test_cpp_api_model.cpp b/tests/c_api_tests/test_cpp_api_model.cpp index cc0433937..47d216cd6 100644 --- a/tests/c_api_tests/test_cpp_api_model.cpp +++ b/tests/c_api_tests/test_cpp_api_model.cpp @@ -52,13 +52,18 @@ TEST_CASE("C++ API Model") { DatasetConst const input_dataset{"input", 0, 1}; // node buffer - ID node_id = 0; - double node_u_rated = 100.0; - Buffer node_buffer{PGM_def_input_node, 1}; - // set nan from offset to size + std::vector node_id{0, 4}; + std::vector node_u_rated{100.0, 100.0}; + Buffer node_buffer{PGM_def_input_node, 2}; node_buffer.set_nan(0, node_buffer.size()); - node_buffer.set_value(PGM_def_input_node_id, &node_id, -1); - node_buffer.set_value(PGM_def_input_node_u_rated, &node_u_rated, -1); + node_buffer.set_value(PGM_def_input_node_id, node_id.data(), -1); + node_buffer.set_value(PGM_def_input_node_u_rated, node_u_rated.data(), -1); + + std::vector line_id{5, 6}; + std::vector line_from_node{0, 4}; + std::vector line_to_node{4, 0}; + std::vector line_from_status{0, 1}; + std::vector line_to_status{1, 0}; // source buffer ID source_id = 1; @@ -91,36 +96,41 @@ TEST_CASE("C++ API Model") { load_buffer.set_value(PGM_def_input_sym_load_p_specified, &load_p_specified, -1); load_buffer.set_value(PGM_def_input_sym_load_q_specified, &load_q_specified, -1); - // gen buffer (columnar) - std::vector gen_id = {3, 4}; - std::vector gen_node = {0, 0}; - std::vector gen_status = {0, 0}; - // add buffers - row - input_dataset.add_buffer("node", 1, 1, nullptr, node_buffer); input_dataset.add_buffer("sym_load", 1, 1, nullptr, load_buffer); input_dataset.add_buffer("source", 1, 1, nullptr, source_buffer); + // add buffers - columnar - input_dataset.add_buffer("sym_gen", 2, 2, nullptr, nullptr); - input_dataset.add_attribute_buffer("sym_gen", "id", &gen_id); - input_dataset.add_attribute_buffer("sym_gen", "node", &gen_node); - input_dataset.add_attribute_buffer("sym_gen", "status", &gen_status); + input_dataset.add_buffer("node", 2, 2, nullptr, nullptr); + input_dataset.add_attribute_buffer("node", "id", node_id.data()); + input_dataset.add_attribute_buffer("node", "u_rated", node_u_rated.data()); + input_dataset.add_buffer("line", 2, 2, nullptr, nullptr); + input_dataset.add_attribute_buffer("line", "id", line_id.data()); + input_dataset.add_attribute_buffer("line", "from_node", line_from_node.data()); + input_dataset.add_attribute_buffer("line", "to_node", line_to_node.data()); + input_dataset.add_attribute_buffer("line", "from_status", line_from_status.data()); + input_dataset.add_attribute_buffer("line", "to_status", line_to_status.data()); // output data - Buffer node_output{PGM_def_sym_output_node, 1}; + Buffer node_output{PGM_def_sym_output_node, 2}; node_output.set_nan(); DatasetMutable const single_output_dataset{"sym_output", 0, 1}; - single_output_dataset.add_buffer("node", 1, 1, nullptr, node_output); - Buffer node_batch_output{PGM_def_sym_output_node, 2}; + single_output_dataset.add_buffer("node", 2, 2, nullptr, node_output); + Buffer node_batch_output{PGM_def_sym_output_node, 4}; node_batch_output.set_nan(); DatasetMutable const batch_output_dataset{"sym_output", 1, 2}; - batch_output_dataset.add_buffer("node", 1, 2, nullptr, node_batch_output); + batch_output_dataset.add_buffer("node", 2, 4, nullptr, node_batch_output); std::vector node_result_id(2); std::vector node_result_energized(2); std::vector node_result_u(2); std::vector node_result_u_pu(2); std::vector node_result_u_angle(2); + std::vector batch_node_result_id(4); + std::vector batch_node_result_energized(4); + std::vector batch_node_result_u(4); + std::vector batch_node_result_u_pu(4); + std::vector batch_node_result_u_angle(4); // update data ID source_update_id = 1; @@ -148,16 +158,17 @@ TEST_CASE("C++ API Model") { DatasetConst const single_update_dataset{"update", 0, 1}; single_update_dataset.add_buffer("source", 1, 1, nullptr, source_update_buffer); single_update_dataset.add_buffer("sym_load", 1, 1, nullptr, load_updates_buffer.get()); - single_update_dataset.add_buffer("sym_gen", 2, 2, nullptr, nullptr); - single_update_dataset.add_attribute_buffer("sym_gen", "status", &gen_status); + // update containing columnar data still fail + // single_update_dataset.add_buffer("line", 2, 2, nullptr, nullptr); + // single_update_dataset.add_attribute_buffer("line", "from_status", line_from_status.data()); + // single_update_dataset.add_attribute_buffer("line", "to_status", line_to_status.data()); DatasetConst const batch_update_dataset{"update", 1, 2}; batch_update_dataset.add_buffer("source", -1, 1, source_update_indptr.data(), source_update_buffer.get()); batch_update_dataset.add_buffer("sym_load", 1, 2, nullptr, load_updates_buffer); - batch_update_dataset.add_buffer("sym_gen", 1, 2, nullptr, nullptr); - batch_update_dataset.add_attribute_buffer("sym_gen", "status", &gen_status); + // batch_update_dataset.add_buffer("sym_gen", 1, 2, nullptr, nullptr); + // batch_update_dataset.add_attribute_buffer("sym_gen", "status", &gen_status); // create model - // FIXME(mgovers): This test will fail here due to columnar data input; Model model{50.0, input_dataset}; // test move-ability @@ -176,6 +187,11 @@ TEST_CASE("C++ API Model") { CHECK(node_result_u[0] == doctest::Approx(50.0)); CHECK(node_result_u_pu[0] == doctest::Approx(0.5)); CHECK(node_result_u_angle[0] == doctest::Approx(0.0)); + CHECK(node_result_id[1] == 4); + CHECK(node_result_energized[1] == 0); + CHECK(node_result_u[1] == doctest::Approx(0.0)); + CHECK(node_result_u_pu[1] == doctest::Approx(0.0)); + CHECK(node_result_u_angle[1] == doctest::Approx(0.0)); } SUBCASE("Simple update") { @@ -191,6 +207,11 @@ TEST_CASE("C++ API Model") { CHECK(node_result_u[0] == doctest::Approx(40.0)); CHECK(node_result_u_pu[0] == doctest::Approx(0.4)); CHECK(node_result_u_angle[0] == doctest::Approx(0.0)); + CHECK(node_result_id[1] == 4); + CHECK(node_result_energized[1] == 0); + CHECK(node_result_u[1] == doctest::Approx(0.0)); + CHECK(node_result_u_pu[1] == doctest::Approx(0.0)); + CHECK(node_result_u_angle[1] == doctest::Approx(0.0)); } SUBCASE("Copy model") { @@ -206,6 +227,11 @@ TEST_CASE("C++ API Model") { CHECK(node_result_u[0] == doctest::Approx(50.0)); CHECK(node_result_u_pu[0] == doctest::Approx(0.5)); CHECK(node_result_u_angle[0] == doctest::Approx(0.0)); + CHECK(node_result_id[1] == 4); + CHECK(node_result_energized[1] == 0); + CHECK(node_result_u[1] == doctest::Approx(0.0)); + CHECK(node_result_u_pu[1] == doctest::Approx(0.0)); + CHECK(node_result_u_angle[1] == doctest::Approx(0.0)); } SUBCASE("Get indexer") { @@ -220,21 +246,31 @@ TEST_CASE("C++ API Model") { SUBCASE("Batch power flow") { model.calculate(options, batch_output_dataset, batch_update_dataset); - node_batch_output.get_value(PGM_def_sym_output_node_id, node_result_id.data(), -1); - node_batch_output.get_value(PGM_def_sym_output_node_energized, node_result_energized.data(), -1); - node_batch_output.get_value(PGM_def_sym_output_node_u, node_result_u.data(), -1); - node_batch_output.get_value(PGM_def_sym_output_node_u_pu, node_result_u_pu.data(), -1); - node_batch_output.get_value(PGM_def_sym_output_node_u_angle, node_result_u_angle.data(), -1); - CHECK(node_result_id[0] == 0); - CHECK(node_result_energized[0] == 1); - CHECK(node_result_u[0] == doctest::Approx(40.0)); - CHECK(node_result_u_pu[0] == doctest::Approx(0.4)); - CHECK(node_result_u_angle[0] == doctest::Approx(0.0)); - CHECK(node_result_id[1] == 0); - CHECK(node_result_energized[1] == 1); - CHECK(node_result_u[1] == doctest::Approx(70.0)); - CHECK(node_result_u_pu[1] == doctest::Approx(0.7)); - CHECK(node_result_u_angle[1] == doctest::Approx(0.0)); + node_batch_output.get_value(PGM_def_sym_output_node_id, batch_node_result_id.data(), -1); + node_batch_output.get_value(PGM_def_sym_output_node_energized, batch_node_result_energized.data(), -1); + node_batch_output.get_value(PGM_def_sym_output_node_u, batch_node_result_u.data(), -1); + node_batch_output.get_value(PGM_def_sym_output_node_u_pu, batch_node_result_u_pu.data(), -1); + node_batch_output.get_value(PGM_def_sym_output_node_u_angle, batch_node_result_u_angle.data(), -1); + CHECK(batch_node_result_id[0] == 0); + CHECK(batch_node_result_energized[0] == 1); + CHECK(batch_node_result_u[0] == doctest::Approx(40.0)); + CHECK(batch_node_result_u_pu[0] == doctest::Approx(0.4)); + CHECK(batch_node_result_u_angle[0] == doctest::Approx(0.0)); + CHECK(batch_node_result_id[1] == 4); + CHECK(batch_node_result_energized[1] == 0); + CHECK(batch_node_result_u[1] == doctest::Approx(0.0)); + CHECK(batch_node_result_u_pu[1] == doctest::Approx(0.0)); + CHECK(batch_node_result_u_angle[1] == doctest::Approx(0.0)); + CHECK(batch_node_result_id[2] == 0); + CHECK(batch_node_result_energized[2] == 1); + CHECK(batch_node_result_u[2] == doctest::Approx(70.0)); + CHECK(batch_node_result_u_pu[2] == doctest::Approx(0.7)); + CHECK(batch_node_result_u_angle[2] == doctest::Approx(0.0)); + CHECK(batch_node_result_id[3] == 4); + CHECK(batch_node_result_energized[3] == 0); + CHECK(batch_node_result_u[3] == doctest::Approx(0.0)); + CHECK(batch_node_result_u_pu[3] == doctest::Approx(0.0)); + CHECK(batch_node_result_u_angle[3] == doctest::Approx(0.0)); } SUBCASE("Input error handling") { @@ -316,16 +352,31 @@ TEST_CASE("C++ API Model") { CHECK(err_msg.find("The id cannot be found:"s) != std::string::npos); } // valid results for batch 0 - node_batch_output.get_value(PGM_def_sym_output_node_id, node_result_id.data(), -1); - node_batch_output.get_value(PGM_def_sym_output_node_energized, node_result_energized.data(), -1); - node_batch_output.get_value(PGM_def_sym_output_node_u, node_result_u.data(), -1); - node_batch_output.get_value(PGM_def_sym_output_node_u_pu, node_result_u_pu.data(), -1); - node_batch_output.get_value(PGM_def_sym_output_node_u_angle, node_result_u_angle.data(), -1); - CHECK(node_result_id[0] == 0); - CHECK(node_result_energized[0] == 1); - CHECK(node_result_u[0] == doctest::Approx(40.0)); - CHECK(node_result_u_pu[0] == doctest::Approx(0.4)); - CHECK(node_result_u_angle[0] == doctest::Approx(0.0)); + node_batch_output.get_value(PGM_def_sym_output_node_id, batch_node_result_id.data(), -1); + node_batch_output.get_value(PGM_def_sym_output_node_energized, batch_node_result_energized.data(), -1); + node_batch_output.get_value(PGM_def_sym_output_node_u, batch_node_result_u.data(), -1); + node_batch_output.get_value(PGM_def_sym_output_node_u_pu, batch_node_result_u_pu.data(), -1); + node_batch_output.get_value(PGM_def_sym_output_node_u_angle, batch_node_result_u_angle.data(), -1); + CHECK(batch_node_result_id[0] == 0); + CHECK(batch_node_result_energized[0] == 1); + CHECK(batch_node_result_u[0] == doctest::Approx(40.0)); + CHECK(batch_node_result_u_pu[0] == doctest::Approx(0.4)); + CHECK(batch_node_result_u_angle[0] == doctest::Approx(0.0)); + CHECK(batch_node_result_id[1] == 4); + CHECK(batch_node_result_energized[1] == 0); + CHECK(batch_node_result_u[1] == doctest::Approx(0.0)); + CHECK(batch_node_result_u_pu[1] == doctest::Approx(0.0)); + CHECK(batch_node_result_u_angle[1] == doctest::Approx(0.0)); + CHECK(batch_node_result_id[2] == 0); + CHECK(batch_node_result_energized[2] == 1); + CHECK(batch_node_result_u[2] == doctest::Approx(70.0)); + CHECK(batch_node_result_u_pu[2] == doctest::Approx(0.7)); + CHECK(batch_node_result_u_angle[2] == doctest::Approx(0.0)); + CHECK(batch_node_result_id[3] == 4); + CHECK(batch_node_result_energized[3] == 0); + CHECK(batch_node_result_u[3] == doctest::Approx(0.0)); + CHECK(batch_node_result_u_pu[3] == doctest::Approx(0.0)); + CHECK(batch_node_result_u_angle[3] == doctest::Approx(0.0)); } } } From 4aae1e7e698c84b6b5fdc3b4890ec13d0fb90323 Mon Sep 17 00:00:00 2001 From: Jerry Guo Date: Fri, 13 Sep 2024 16:42:04 +0200 Subject: [PATCH 13/18] Fixed update in main_model_impl.hpp Signed-off-by: Jerry Guo --- .../power_grid_model/main_core/input.hpp | 5 +---- .../power_grid_model/main_core/update.hpp | 3 +-- .../power_grid_model/main_model_impl.hpp | 14 +++++++++++--- tests/c_api_tests/test_cpp_api_model.cpp | 18 +++++++++++++----- 4 files changed, 26 insertions(+), 14 deletions(-) diff --git a/power_grid_model_c/power_grid_model/include/power_grid_model/main_core/input.hpp b/power_grid_model_c/power_grid_model/include/power_grid_model/main_core/input.hpp index 409a27f39..67a2124fb 100644 --- a/power_grid_model_c/power_grid_model/include/power_grid_model/main_core/input.hpp +++ b/power_grid_model_c/power_grid_model/include/power_grid_model/main_core/input.hpp @@ -28,10 +28,7 @@ inline void add_component(MainModelState& state, ForwardIter using ComponentView = std::conditional_t, typename Component::InputType const&, typename Component::InputType>; - // DEBUG - auto dist = std::distance(begin, end); - // DEBUG - reserve_component(state, /*std::distance(begin, end)*/ dist); + reserve_component(state, std::distance(begin, end)); // do sanity check on the transformer tap regulator std::vector regulated_objects; // loop to add component diff --git a/power_grid_model_c/power_grid_model/include/power_grid_model/main_core/update.hpp b/power_grid_model_c/power_grid_model/include/power_grid_model/main_core/update.hpp index bfa1206ac..71ee3f7c4 100644 --- a/power_grid_model_c/power_grid_model/include/power_grid_model/main_core/update.hpp +++ b/power_grid_model_c/power_grid_model/include/power_grid_model/main_core/update.hpp @@ -46,8 +46,7 @@ template get_component_sequence(MainModelState const& state, ForwardIterator begin, ForwardIterator end) { std::vector result; - auto const dist = std::distance(begin, end); - result.reserve(/*std::distance(begin, end)*/ dist); + result.reserve(std::distance(begin, end)); get_component_sequence(state, begin, end, std::back_inserter(result)); return result; } diff --git a/power_grid_model_c/power_grid_model/include/power_grid_model/main_model_impl.hpp b/power_grid_model_c/power_grid_model/include/power_grid_model/main_model_impl.hpp index c1705a8ef..cf64a7d80 100644 --- a/power_grid_model_c/power_grid_model/include/power_grid_model/main_model_impl.hpp +++ b/power_grid_model_c/power_grid_model/include/power_grid_model/main_model_impl.hpp @@ -720,9 +720,7 @@ class MainModelImpl, ComponentLis return true; } - auto const is_component_update_independent = [&update_data]() -> bool { - // get span of all the update data - auto const all_spans = update_data.get_buffer_span_all_scenarios(); + auto const process_span = [](auto const& all_spans) -> bool { // Remember the first batch size, then loop over the remaining batches and check if they are of the same // length auto const elements_per_scenario = static_cast(all_spans.front().size()); @@ -747,6 +745,16 @@ class MainModelImpl, ComponentLis }); }; + auto const is_component_update_independent = [&update_data, &process_span]() -> bool { + // get span of all the update data + if (update_data.is_columnar(CT::name)) { + return process_span.template operator()( + update_data.get_columnar_buffer_span_all_scenarios()); + } + return process_span.template operator()( + update_data.get_buffer_span_all_scenarios()); + }; + // check all components auto const update_independent = run_functor_with_all_types_return_array(is_component_update_independent); return std::ranges::all_of(update_independent, [](bool const is_independent) { return is_independent; }); diff --git a/tests/c_api_tests/test_cpp_api_model.cpp b/tests/c_api_tests/test_cpp_api_model.cpp index 47d216cd6..8f9007325 100644 --- a/tests/c_api_tests/test_cpp_api_model.cpp +++ b/tests/c_api_tests/test_cpp_api_model.cpp @@ -64,6 +64,11 @@ TEST_CASE("C++ API Model") { std::vector line_to_node{4, 0}; std::vector line_from_status{0, 1}; std::vector line_to_status{1, 0}; + std::vector batch_line_id{5, 6, 5, 6}; + std::vector batch_line_from_node{0, 4, 0, 4}; + std::vector batch_line_to_node{4, 0, 4, 0}; + std::vector batch_line_from_status{0, 1, 0, 1}; + std::vector batch_line_to_status{1, 0, 1, 0}; // source buffer ID source_id = 1; @@ -159,14 +164,17 @@ TEST_CASE("C++ API Model") { single_update_dataset.add_buffer("source", 1, 1, nullptr, source_update_buffer); single_update_dataset.add_buffer("sym_load", 1, 1, nullptr, load_updates_buffer.get()); // update containing columnar data still fail - // single_update_dataset.add_buffer("line", 2, 2, nullptr, nullptr); - // single_update_dataset.add_attribute_buffer("line", "from_status", line_from_status.data()); - // single_update_dataset.add_attribute_buffer("line", "to_status", line_to_status.data()); + single_update_dataset.add_buffer("line", 2, 2, nullptr, nullptr); + single_update_dataset.add_attribute_buffer("line", "id", line_id.data()); + single_update_dataset.add_attribute_buffer("line", "from_status", line_from_status.data()); + single_update_dataset.add_attribute_buffer("line", "to_status", line_to_status.data()); DatasetConst const batch_update_dataset{"update", 1, 2}; batch_update_dataset.add_buffer("source", -1, 1, source_update_indptr.data(), source_update_buffer.get()); batch_update_dataset.add_buffer("sym_load", 1, 2, nullptr, load_updates_buffer); - // batch_update_dataset.add_buffer("sym_gen", 1, 2, nullptr, nullptr); - // batch_update_dataset.add_attribute_buffer("sym_gen", "status", &gen_status); + batch_update_dataset.add_buffer("line", 2, 4, nullptr, nullptr); + batch_update_dataset.add_attribute_buffer("line", "id", batch_line_id.data()); + batch_update_dataset.add_attribute_buffer("line", "from_status", batch_line_from_status.data()); + batch_update_dataset.add_attribute_buffer("line", "to_status", batch_line_to_status.data()); // create model Model model{50.0, input_dataset}; From 056926aa6e96ee94e07596d267efe7ec5e312348 Mon Sep 17 00:00:00 2001 From: Jerry Guo Date: Mon, 16 Sep 2024 12:11:18 +0200 Subject: [PATCH 14/18] process review comments; todo: test serialization Signed-off-by: Jerry Guo --- .../power_grid_model/auxiliary/dataset.hpp | 18 ++++++++++++++++++ .../power_grid_model/main_model_impl.hpp | 14 +++++++------- .../include/power_grid_model_c/dataset.h | 6 +++--- tests/c_api_tests/test_cpp_api_model.cpp | 1 - 4 files changed, 28 insertions(+), 11 deletions(-) diff --git a/power_grid_model_c/power_grid_model/include/power_grid_model/auxiliary/dataset.hpp b/power_grid_model_c/power_grid_model/include/power_grid_model/auxiliary/dataset.hpp index 02df0fcbd..c91aa13ea 100644 --- a/power_grid_model_c/power_grid_model/include/power_grid_model/auxiliary/dataset.hpp +++ b/power_grid_model_c/power_grid_model/include/power_grid_model/auxiliary/dataset.hpp @@ -308,6 +308,24 @@ template class Dataset { add_attribute_buffer_impl(component, attribute, data); } + /* + we decided to go with the same behavior between `add_attribute_buffer` and `set_attribute_buffer` (but different + entrypoints). The behavior of `set_attribute_buffer` therefore differs from the one of `set_buffer`. The reasoning + is as follows: + + For components: + - the deserializer tells the user via the dataset info that a certain component is present in the serialized + data. + - It is possible to efficiently determine whether that is the case. + - The user can then only call `set_buffer` for those components that are already present + For attributes: + - the deserializer would need to go over the entire dataset to look for components with the map serialization + representation to determine whether an attribute is present. + - this is expensive. + - the deserializer therefore cannot let the user know beforehand which attributes are present. + - `set_attribute_buffer` therefore should only be called if it has not been set yet. + - this is the same behavior as `add_attribute_buffer`. + */ void set_attribute_buffer(std::string_view component, std::string_view attribute, Data* data) requires is_indptr_mutable_v { diff --git a/power_grid_model_c/power_grid_model/include/power_grid_model/main_model_impl.hpp b/power_grid_model_c/power_grid_model/include/power_grid_model/main_model_impl.hpp index cf64a7d80..6e29885fb 100644 --- a/power_grid_model_c/power_grid_model/include/power_grid_model/main_model_impl.hpp +++ b/power_grid_model_c/power_grid_model/include/power_grid_model/main_model_impl.hpp @@ -720,7 +720,7 @@ class MainModelImpl, ComponentLis return true; } - auto const process_span = [](auto const& all_spans) -> bool { + auto const process_buffer_span = [](auto const& all_spans) -> bool { // Remember the first batch size, then loop over the remaining batches and check if they are of the same // length auto const elements_per_scenario = static_cast(all_spans.front().size()); @@ -745,13 +745,13 @@ class MainModelImpl, ComponentLis }); }; - auto const is_component_update_independent = [&update_data, &process_span]() -> bool { + auto const is_component_update_independent = [&update_data, &process_buffer_span]() -> bool { // get span of all the update data if (update_data.is_columnar(CT::name)) { - return process_span.template operator()( + return process_buffer_span.template operator()( update_data.get_columnar_buffer_span_all_scenarios()); } - return process_span.template operator()( + return process_buffer_span.template operator()( update_data.get_buffer_span_all_scenarios()); }; @@ -836,7 +836,7 @@ class MainModelImpl, ComponentLis void output_result(MathOutput> const& math_output, MutableDataset const& result_data, Idx pos = 0) const { auto const output_func = [this, &math_output, &result_data, pos]() { - auto process_output = [this, &math_output](auto const& span) { + auto process_output_span = [this, &math_output](auto const& span) { if (std::empty(span)) { return; } @@ -846,11 +846,11 @@ class MainModelImpl, ComponentLis if (result_data.is_columnar(CT::name)) { auto const span = result_data.get_columnar_buffer_span::type, CT>(pos); - process_output(span); + process_output_span(span); } else { auto const span = result_data.get_buffer_span::type, CT>(pos); - process_output(span); + process_output_span(span); } }; diff --git a/power_grid_model_c/power_grid_model_c/include/power_grid_model_c/dataset.h b/power_grid_model_c/power_grid_model_c/include/power_grid_model_c/dataset.h index 0a4b2b378..cffb87bc0 100644 --- a/power_grid_model_c/power_grid_model_c/include/power_grid_model_c/dataset.h +++ b/power_grid_model_c/power_grid_model_c/include/power_grid_model_c/dataset.h @@ -140,7 +140,7 @@ PGM_API void PGM_destroy_dataset_const(PGM_ConstDataset* dataset); * If the component is not uniform, indptr must point to an array of size (batch_size + 1). * The values in the array must be not decreasing. * And we must have indptr[0] = 0, indptr[batch_size] = total_elements. - * @param data A void pointer to the buffer data. + * @param data A void pointer to the row based buffer data or a nullptr for columnar data. * @return */ PGM_API void PGM_dataset_const_add_buffer(PGM_Handle* handle, PGM_ConstDataset* dataset, char const* component, @@ -185,7 +185,7 @@ PGM_API PGM_DatasetInfo const* PGM_dataset_writable_get_info(PGM_Handle* handle, * @param indptr A pointer to an array of indptr of a non-uniform component. * If the component is uniform, indptr must be NULL. * If the component is not uniform, indptr must point to an array of size (batch_size + 1). - * @param data A void pointer to the buffer data. + * @param data A void pointer to the row based buffer data or a nullptr for columnar data. * @return */ PGM_API void PGM_dataset_writable_set_buffer(PGM_Handle* handle, PGM_WritableDataset* dataset, char const* component, @@ -237,7 +237,7 @@ PGM_API void PGM_destroy_dataset_mutable(PGM_MutableDataset* dataset); * If the component is not uniform, indptr must point to an array of size (batch_size + 1). * The values in the array must be not decreasing. * And we must have indptr[0] = 0, indptr[batch_size] = total_elements. - * @param data A void pointer to the buffer data. + * @param data A void pointer to the row based buffer data or a nullptr for columnar data. * @return */ PGM_API void PGM_dataset_mutable_add_buffer(PGM_Handle* handle, PGM_MutableDataset* dataset, char const* component, diff --git a/tests/c_api_tests/test_cpp_api_model.cpp b/tests/c_api_tests/test_cpp_api_model.cpp index 8f9007325..421a9780d 100644 --- a/tests/c_api_tests/test_cpp_api_model.cpp +++ b/tests/c_api_tests/test_cpp_api_model.cpp @@ -163,7 +163,6 @@ TEST_CASE("C++ API Model") { DatasetConst const single_update_dataset{"update", 0, 1}; single_update_dataset.add_buffer("source", 1, 1, nullptr, source_update_buffer); single_update_dataset.add_buffer("sym_load", 1, 1, nullptr, load_updates_buffer.get()); - // update containing columnar data still fail single_update_dataset.add_buffer("line", 2, 2, nullptr, nullptr); single_update_dataset.add_attribute_buffer("line", "id", line_id.data()); single_update_dataset.add_attribute_buffer("line", "from_status", line_from_status.data()); From ca9159be32b3e7a32d6f2ed1c31a0b2be151f8b1 Mon Sep 17 00:00:00 2001 From: Jerry Guo Date: Mon, 16 Sep 2024 14:24:09 +0200 Subject: [PATCH 15/18] removed unnecessary `const` in the c++ wrapper and api tests Signed-off-by: Jerry Guo --- .../include/power_grid_model_cpp/buffer.hpp | 6 +- .../include/power_grid_model_cpp/dataset.hpp | 16 ++--- tests/native_api_tests/test_api_model.cpp | 64 +++++++++---------- .../test_api_serialization.cpp | 2 +- 4 files changed, 44 insertions(+), 44 deletions(-) diff --git a/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/buffer.hpp b/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/buffer.hpp index e1b44d5c7..9f96024ef 100644 --- a/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/buffer.hpp +++ b/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/buffer.hpp @@ -33,14 +33,14 @@ class Buffer { buffer.handle_.call_with(PGM_buffer_set_value, attribute, buffer.buffer_.get(), src_ptr, buffer_offset, size, src_stride); } - void set_value(MetaAttribute const* attribute, RawDataConstPtr src_ptr, Idx src_stride) const { + void set_value(MetaAttribute const* attribute, RawDataConstPtr src_ptr, Idx src_stride) { set_value(attribute, *this, src_ptr, 0, size_, src_stride); } - void set_value(MetaAttribute const* attribute, RawDataConstPtr src_ptr, Idx buffer_offset, Idx src_stride) const { + void set_value(MetaAttribute const* attribute, RawDataConstPtr src_ptr, Idx buffer_offset, Idx src_stride) { set_value(attribute, *this, src_ptr, buffer_offset, 1, src_stride); } void set_value(MetaAttribute const* attribute, RawDataConstPtr src_ptr, Idx buffer_offset, Idx size, - Idx src_stride) const { + Idx src_stride) { set_value(attribute, *this, src_ptr, buffer_offset, size, src_stride); } diff --git a/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/dataset.hpp b/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/dataset.hpp index daf04c0af..77f886fe5 100644 --- a/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/dataset.hpp +++ b/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/dataset.hpp @@ -133,7 +133,7 @@ class DatasetMutable { elements_per_scenario, total_elements, indptr, data); } void add_buffer(std::string const& component, Idx elements_per_scenario, Idx total_elements, Idx const* indptr, - RawDataPtr data) const { + RawDataPtr data) { add_buffer(*this, component, elements_per_scenario, total_elements, indptr, data); } @@ -143,7 +143,7 @@ class DatasetMutable { elements_per_scenario, total_elements, indptr, data.get()); } void add_buffer(std::string const& component, Idx elements_per_scenario, Idx total_elements, Idx const* indptr, - Buffer const& data) const { + Buffer const& data) { add_buffer(*this, component, elements_per_scenario, total_elements, indptr, data); } @@ -152,7 +152,7 @@ class DatasetMutable { dataset.handle_.call_with(PGM_dataset_mutable_add_attribute_buffer, dataset.dataset_.get(), component.c_str(), attribute.c_str(), data); } - void add_attribute_buffer(std::string const& component, std::string const& attribute, RawDataPtr data) const { + void add_attribute_buffer(std::string const& component, std::string const& attribute, RawDataPtr data) { add_attribute_buffer(*this, component, attribute, data); } @@ -161,7 +161,7 @@ class DatasetMutable { dataset.handle_.call_with(PGM_dataset_mutable_add_attribute_buffer, dataset.dataset_.get(), component.c_str(), attribute.c_str(), data.get()); } - void add_attribute_buffer(std::string const& component, std::string const& attribute, Buffer const& data) const { + void add_attribute_buffer(std::string const& component, std::string const& attribute, Buffer const& data) { add_attribute_buffer(*this, component, attribute, data); } @@ -194,7 +194,7 @@ class DatasetConst { elements_per_scenario, total_elements, indptr, data); } void add_buffer(std::string const& component, Idx elements_per_scenario, Idx total_elements, Idx const* indptr, - RawDataConstPtr data) const { + RawDataConstPtr data) { add_buffer(*this, component, elements_per_scenario, total_elements, indptr, data); } @@ -204,7 +204,7 @@ class DatasetConst { elements_per_scenario, total_elements, indptr, data.get()); } void add_buffer(std::string const& component, Idx elements_per_scenario, Idx total_elements, Idx const* indptr, - Buffer const& data) const { + Buffer const& data) { add_buffer(*this, component, elements_per_scenario, total_elements, indptr, data); } @@ -213,7 +213,7 @@ class DatasetConst { dataset.handle_.call_with(PGM_dataset_const_add_attribute_buffer, dataset.dataset_.get(), component.c_str(), attribute.c_str(), data); } - void add_attribute_buffer(std::string const& component, std::string const& attribute, RawDataConstPtr data) const { + void add_attribute_buffer(std::string const& component, std::string const& attribute, RawDataConstPtr data) { add_attribute_buffer(*this, component, attribute, data); } @@ -222,7 +222,7 @@ class DatasetConst { dataset.handle_.call_with(PGM_dataset_const_add_attribute_buffer, dataset.dataset_.get(), component.c_str(), attribute.c_str(), data.get()); } - void add_attribute_buffer(std::string const& component, std::string const& attribute, Buffer const& data) const { + void add_attribute_buffer(std::string const& component, std::string const& attribute, Buffer const& data) { add_attribute_buffer(*this, component, attribute, data); } diff --git a/tests/native_api_tests/test_api_model.cpp b/tests/native_api_tests/test_api_model.cpp index be8eccd91..8deba7a59 100644 --- a/tests/native_api_tests/test_api_model.cpp +++ b/tests/native_api_tests/test_api_model.cpp @@ -49,34 +49,34 @@ TEST_CASE("API Model") { Options const options{}; // input data - DatasetConst const input_dataset{"input", 0, 1}; + DatasetConst input_dataset{"input", 0, 1}; // node buffer - std::vector node_id{0, 4}; - std::vector node_u_rated{100.0, 100.0}; + std::vector const node_id{0, 4}; + std::vector const node_u_rated{100.0, 100.0}; Buffer node_buffer{PGM_def_input_node, 2}; node_buffer.set_nan(0, node_buffer.size()); node_buffer.set_value(PGM_def_input_node_id, node_id.data(), -1); node_buffer.set_value(PGM_def_input_node_u_rated, node_u_rated.data(), -1); - std::vector line_id{5, 6}; - std::vector line_from_node{0, 4}; - std::vector line_to_node{4, 0}; - std::vector line_from_status{0, 1}; - std::vector line_to_status{1, 0}; - std::vector batch_line_id{5, 6, 5, 6}; - std::vector batch_line_from_node{0, 4, 0, 4}; - std::vector batch_line_to_node{4, 0, 4, 0}; - std::vector batch_line_from_status{0, 1, 0, 1}; - std::vector batch_line_to_status{1, 0, 1, 0}; + std::vector const line_id{5, 6}; + std::vector const line_from_node{0, 4}; + std::vector const line_to_node{4, 0}; + std::vector const line_from_status{0, 1}; + std::vector const line_to_status{1, 0}; + std::vector const batch_line_id{5, 6, 5, 6}; + std::vector const batch_line_from_node{0, 4, 0, 4}; + std::vector const batch_line_to_node{4, 0, 4, 0}; + std::vector const batch_line_from_status{0, 1, 0, 1}; + std::vector const batch_line_to_status{1, 0, 1, 0}; // source buffer - ID source_id = 1; - ID source_node = 0; - int8_t source_status = 1; - double source_u_ref = 1.0; - double source_sk = 1000.0; - double source_rx_ratio = 0.0; + ID const source_id = 1; + ID const source_node = 0; + int8_t const source_status = 1; + double const source_u_ref = 1.0; + double const source_sk = 1000.0; + double const source_rx_ratio = 0.0; Buffer source_buffer{PGM_def_input_source, 1}; source_buffer.set_nan(); source_buffer.set_value(PGM_def_input_source_id, &source_id, -1); @@ -88,12 +88,12 @@ TEST_CASE("API Model") { // load buffer ID load_id = 2; - ID load_node = 0; - int8_t load_status = 1; - int8_t load_type = 2; - double load_p_specified = 0.0; - double load_q_specified = 500.0; - Buffer const load_buffer{PGM_def_input_sym_load, 1}; + ID const load_node = 0; + int8_t const load_status = 1; + int8_t const load_type = 2; + double const load_p_specified = 0.0; + double const load_q_specified = 500.0; + Buffer load_buffer{PGM_def_input_sym_load, 1}; load_buffer.set_value(PGM_def_input_sym_load_id, &load_id, -1); load_buffer.set_value(PGM_def_input_sym_load_node, &load_node, -1); load_buffer.set_value(PGM_def_input_sym_load_status, &load_status, -1); @@ -119,11 +119,11 @@ TEST_CASE("API Model") { // output data Buffer node_output{PGM_def_sym_output_node, 2}; node_output.set_nan(); - DatasetMutable const single_output_dataset{"sym_output", 0, 1}; + DatasetMutable single_output_dataset{"sym_output", 0, 1}; single_output_dataset.add_buffer("node", 2, 2, nullptr, node_output); Buffer node_batch_output{PGM_def_sym_output_node, 4}; node_batch_output.set_nan(); - DatasetMutable const batch_output_dataset{"sym_output", 1, 2}; + DatasetMutable batch_output_dataset{"sym_output", 1, 2}; batch_output_dataset.add_buffer("node", 2, 4, nullptr, node_batch_output); std::vector node_result_id(2); @@ -139,9 +139,9 @@ TEST_CASE("API Model") { // update data ID source_update_id = 1; - int8_t source_update_status = std::numeric_limits::min(); - double source_update_u_ref = 0.5; - double source_update_u_ref_angle = std::numeric_limits::quiet_NaN(); + int8_t const source_update_status = std::numeric_limits::min(); + double const source_update_u_ref = 0.5; + double const source_update_u_ref_angle = std::numeric_limits::quiet_NaN(); Buffer source_update_buffer{PGM_def_update_source, 1}; source_update_buffer.set_nan(); source_update_buffer.set_value(PGM_def_update_source_id, &source_update_id, 0, -1); @@ -160,14 +160,14 @@ TEST_CASE("API Model") { load_updates_buffer.set_value(PGM_def_update_sym_load_q_specified, load_updates_q_specified.data(), 0, -1); load_updates_buffer.set_value(PGM_def_update_sym_load_q_specified, load_updates_q_specified.data(), 1, -1); // dataset - DatasetConst const single_update_dataset{"update", 0, 1}; + DatasetConst single_update_dataset{"update", 0, 1}; single_update_dataset.add_buffer("source", 1, 1, nullptr, source_update_buffer); single_update_dataset.add_buffer("sym_load", 1, 1, nullptr, load_updates_buffer.get()); single_update_dataset.add_buffer("line", 2, 2, nullptr, nullptr); single_update_dataset.add_attribute_buffer("line", "id", line_id.data()); single_update_dataset.add_attribute_buffer("line", "from_status", line_from_status.data()); single_update_dataset.add_attribute_buffer("line", "to_status", line_to_status.data()); - DatasetConst const batch_update_dataset{"update", 1, 2}; + DatasetConst batch_update_dataset{"update", 1, 2}; batch_update_dataset.add_buffer("source", -1, 1, source_update_indptr.data(), source_update_buffer.get()); batch_update_dataset.add_buffer("sym_load", 1, 2, nullptr, load_updates_buffer); batch_update_dataset.add_buffer("line", 2, 4, nullptr, nullptr); diff --git a/tests/native_api_tests/test_api_serialization.cpp b/tests/native_api_tests/test_api_serialization.cpp index fa1c456a1..6d447aa77 100644 --- a/tests/native_api_tests/test_api_serialization.cpp +++ b/tests/native_api_tests/test_api_serialization.cpp @@ -54,7 +54,7 @@ TEST_CASE("API Serialization and Deserialization") { std::vector const total_elements = {1, 2}; SUBCASE("Serializer") { - DatasetConst const dataset{"input", is_batch, batch_size}; + DatasetConst dataset{"input", is_batch, batch_size}; dataset.add_buffer("node", elements_per_scenario[0], total_elements[0], nullptr, node_buffer); dataset.add_buffer("source", elements_per_scenario[1], total_elements[1], nullptr, source_buffer); From 6cfabe371c6e5376e822c964f69fc90a10c778e0 Mon Sep 17 00:00:00 2001 From: Jerry Guo Date: Mon, 16 Sep 2024 15:54:02 +0200 Subject: [PATCH 16/18] sonar cloud: no const Signed-off-by: Jerry Guo --- .../include/power_grid_model_cpp/dataset.hpp | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/dataset.hpp b/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/dataset.hpp index 77f886fe5..4f4112851 100644 --- a/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/dataset.hpp +++ b/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/dataset.hpp @@ -133,7 +133,7 @@ class DatasetMutable { elements_per_scenario, total_elements, indptr, data); } void add_buffer(std::string const& component, Idx elements_per_scenario, Idx total_elements, Idx const* indptr, - RawDataPtr data) { + RawDataPtr data) { // NOSONAR: no const add_buffer(*this, component, elements_per_scenario, total_elements, indptr, data); } @@ -143,7 +143,7 @@ class DatasetMutable { elements_per_scenario, total_elements, indptr, data.get()); } void add_buffer(std::string const& component, Idx elements_per_scenario, Idx total_elements, Idx const* indptr, - Buffer const& data) { + Buffer const& data) { // NOSONAR: no const add_buffer(*this, component, elements_per_scenario, total_elements, indptr, data); } @@ -152,7 +152,8 @@ class DatasetMutable { dataset.handle_.call_with(PGM_dataset_mutable_add_attribute_buffer, dataset.dataset_.get(), component.c_str(), attribute.c_str(), data); } - void add_attribute_buffer(std::string const& component, std::string const& attribute, RawDataPtr data) { + void add_attribute_buffer(std::string const& component, std::string const& attribute, + RawDataPtr data) { // NOSONAR: no const add_attribute_buffer(*this, component, attribute, data); } @@ -161,7 +162,8 @@ class DatasetMutable { dataset.handle_.call_with(PGM_dataset_mutable_add_attribute_buffer, dataset.dataset_.get(), component.c_str(), attribute.c_str(), data.get()); } - void add_attribute_buffer(std::string const& component, std::string const& attribute, Buffer const& data) { + void add_attribute_buffer(std::string const& component, std::string const& attribute, + Buffer const& data) { // NOSONAR: no const: no const add_attribute_buffer(*this, component, attribute, data); } @@ -194,7 +196,7 @@ class DatasetConst { elements_per_scenario, total_elements, indptr, data); } void add_buffer(std::string const& component, Idx elements_per_scenario, Idx total_elements, Idx const* indptr, - RawDataConstPtr data) { + RawDataConstPtr data) { // NOSONAR: no const add_buffer(*this, component, elements_per_scenario, total_elements, indptr, data); } @@ -204,7 +206,7 @@ class DatasetConst { elements_per_scenario, total_elements, indptr, data.get()); } void add_buffer(std::string const& component, Idx elements_per_scenario, Idx total_elements, Idx const* indptr, - Buffer const& data) { + Buffer const& data) { // NOSONAR: no const add_buffer(*this, component, elements_per_scenario, total_elements, indptr, data); } @@ -213,7 +215,8 @@ class DatasetConst { dataset.handle_.call_with(PGM_dataset_const_add_attribute_buffer, dataset.dataset_.get(), component.c_str(), attribute.c_str(), data); } - void add_attribute_buffer(std::string const& component, std::string const& attribute, RawDataConstPtr data) { + void add_attribute_buffer(std::string const& component, std::string const& attribute, + RawDataConstPtr data) { // NOSONAR: no const add_attribute_buffer(*this, component, attribute, data); } @@ -222,7 +225,8 @@ class DatasetConst { dataset.handle_.call_with(PGM_dataset_const_add_attribute_buffer, dataset.dataset_.get(), component.c_str(), attribute.c_str(), data.get()); } - void add_attribute_buffer(std::string const& component, std::string const& attribute, Buffer const& data) { + void add_attribute_buffer(std::string const& component, std::string const& attribute, + Buffer const& data) { // NOSONAR: no const add_attribute_buffer(*this, component, attribute, data); } From 90259260f28982cdddc7985bb732423514cf872b Mon Sep 17 00:00:00 2001 From: Jerry Guo Date: Mon, 16 Sep 2024 17:39:18 +0200 Subject: [PATCH 17/18] serialization test + sonar cloud Signed-off-by: Jerry Guo --- .../test_api_serialization.cpp | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/tests/native_api_tests/test_api_serialization.cpp b/tests/native_api_tests/test_api_serialization.cpp index 6d447aa77..09ac99c8b 100644 --- a/tests/native_api_tests/test_api_serialization.cpp +++ b/tests/native_api_tests/test_api_serialization.cpp @@ -51,7 +51,9 @@ TEST_CASE("API Serialization and Deserialization") { Idx const batch_size = 1; Idx const is_batch = 0; std::vector const elements_per_scenario = {1, 2}; + std::vector const elements_per_scenario_complete = {1, 1}; std::vector const total_elements = {1, 2}; + std::vector const total_elements_complete = {1, 1}; SUBCASE("Serializer") { DatasetConst dataset{"input", is_batch, batch_size}; @@ -155,6 +157,59 @@ TEST_CASE("API Serialization and Deserialization") { check_deserializer(msgpack_deserializer); } + SUBCASE("Deserializer with columnar data") { + // msgpack data + auto const json_document = nlohmann::json::parse(complete_json_data); + std::vector msgpack_data; + + nlohmann::json::to_msgpack(json_document, msgpack_data); + + // test move-ability + Deserializer json_deserializer{complete_json_data, 0}; + Deserializer json_dummy{std::move(json_deserializer)}; + json_deserializer = std::move(json_dummy); + Deserializer msgpack_deserializer{msgpack_data, 1}; + + auto check_metadata = [&](DatasetInfo const& info) { + CHECK(info.name() == "input"s); + CHECK(info.is_batch() == is_batch); + CHECK(info.batch_size() == batch_size); + CHECK(info.n_components() == n_components); + CHECK(info.component_name(0) == "node"s); + CHECK(info.component_name(1) == "source"s); + for (Idx const idx : {0, 1}) { + CHECK(info.component_elements_per_scenario(idx) == elements_per_scenario_complete[idx]); + CHECK(info.component_total_elements(idx) == total_elements_complete[idx]); + } + }; + + auto check_deserializer = [&](Deserializer& deserializer) { + // get dataset + auto& dataset = deserializer.get_dataset(); + auto const& info = dataset.get_info(); + // check meta data + check_metadata(info); + ID node_id_2{0}; + double node_u_rated_2; + // set buffer + dataset.set_buffer("node", nullptr, nullptr); + dataset.set_attribute_buffer("node", "id", &node_id_2); + dataset.set_attribute_buffer("node", "u_rated", &node_u_rated_2); + dataset.set_buffer("source", nullptr, source_buffer_2); + // parse + deserializer.parse_to_buffer(); + // check + ID source_2_id; + source_buffer_2.get_value(PGM_def_input_source_id, &source_2_id, -1); + CHECK(node_id_2 == 5); + CHECK(node_u_rated_2 == doctest::Approx(10.5e3)); + CHECK(source_2_id == 6); + }; + + check_deserializer(json_deserializer); + check_deserializer(msgpack_deserializer); + } + SUBCASE("Use deserialized dataset") { Deserializer deserializer_json(complete_json_data, 0); From bc217198f7bc0ad6aa10edef48a7b2e173662326 Mon Sep 17 00:00:00 2001 From: Jerry Guo Date: Mon, 16 Sep 2024 20:42:54 +0200 Subject: [PATCH 18/18] bug fixed (gcc) Signed-off-by: Jerry Guo --- tests/native_api_tests/test_api_serialization.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/native_api_tests/test_api_serialization.cpp b/tests/native_api_tests/test_api_serialization.cpp index 09ac99c8b..7eb77e3cd 100644 --- a/tests/native_api_tests/test_api_serialization.cpp +++ b/tests/native_api_tests/test_api_serialization.cpp @@ -192,15 +192,16 @@ TEST_CASE("API Serialization and Deserialization") { ID node_id_2{0}; double node_u_rated_2; // set buffer + Buffer source_buffer_columnar{PGM_def_input_source, 1}; dataset.set_buffer("node", nullptr, nullptr); dataset.set_attribute_buffer("node", "id", &node_id_2); dataset.set_attribute_buffer("node", "u_rated", &node_u_rated_2); - dataset.set_buffer("source", nullptr, source_buffer_2); + dataset.set_buffer("source", nullptr, source_buffer_columnar); // parse deserializer.parse_to_buffer(); // check ID source_2_id; - source_buffer_2.get_value(PGM_def_input_source_id, &source_2_id, -1); + source_buffer_columnar.get_value(PGM_def_input_source_id, &source_2_id, -1); CHECK(node_id_2 == 5); CHECK(node_u_rated_2 == doctest::Approx(10.5e3)); CHECK(source_2_id == 6);