Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/deserialized api tests #855

Merged
merged 25 commits into from
Dec 16, 2024
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
07b0cf1
migrate owning dataset to C++ wrapper
mgovers Dec 5, 2024
ae78da5
reduce complexity
mgovers Dec 5, 2024
7cb2e5d
Merge branch 'feature/resolve-sonar-cloud-issues' into feature/deseri…
mgovers Dec 5, 2024
635e926
migrate API model - all updates test to JSON input
mgovers Dec 5, 2024
df9878c
migrate update of update with alternating compute mode
mgovers Dec 5, 2024
c585b25
migrate incomplete update tests to JSON input
mgovers Dec 9, 2024
e15d5fd
migrate incomplete followed by complete update tests to JSON input
mgovers Dec 9, 2024
4ad1c3f
more migrations
mgovers Dec 10, 2024
0ccb71f
cleanup
mgovers Dec 10, 2024
9d53b55
migrate input + update data of test API model
mgovers Dec 11, 2024
5ab2320
migrate some more test api model functions
mgovers Dec 11, 2024
35eff17
remove unused code
mgovers Dec 11, 2024
0c47772
reorder
mgovers Dec 11, 2024
c75a715
Merge remote-tracking branch 'origin/main' into feature/deserialized-…
mgovers Dec 12, 2024
3190f3e
fix linux build
mgovers Dec 12, 2024
f210727
clang-tidy
mgovers Dec 12, 2024
df49310
only mutable owning dataset
mgovers Dec 12, 2024
a960b1b
use explicit constructor
mgovers Dec 12, 2024
0b7466a
Merge remote-tracking branch 'origin/main' into feature/deserialized-…
mgovers Dec 16, 2024
981d866
resolve comment
mgovers Dec 16, 2024
55b779c
fix sonar cloud
mgovers Dec 16, 2024
b918f38
more sonar cloud
mgovers Dec 16, 2024
16ea1e3
minor
mgovers Dec 16, 2024
1d6d133
throw when component type not found in dataset
mgovers Dec 16, 2024
336e1af
remove unnecessary header guards protected by pragma once
mgovers Dec 16, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "handle.hpp"

#include "power_grid_model_c/dataset.h"

namespace power_grid_model_cpp {

class DatasetInfo {
Expand Down Expand Up @@ -43,6 +44,16 @@ class DatasetInfo {
return handle_.call_with(PGM_dataset_info_total_elements, info_, component_idx);
}

Idx component_idx(std::string_view component) const {
TonyXiang8787 marked this conversation as resolved.
Show resolved Hide resolved
Idx const n_comp = n_components();
for (Idx idx = 0; idx < n_comp; ++idx) {
if (component_name(idx) == component) {
return idx;
}
}
return -1;
mgovers marked this conversation as resolved.
Show resolved Hide resolved
}

private:
Handle handle_{};
RawDatasetInfo const* info_;
Expand Down Expand Up @@ -171,6 +182,21 @@ class DatasetConst {
detail::UniquePtr<RawConstDataset, &PGM_destroy_dataset_const> dataset_;
DatasetInfo info_;
};

struct OwningMemory {
std::vector<Buffer> buffers;
std::vector<std::vector<Idx>> indptrs;
};

struct OwningDatasetMutable {
DatasetMutable dataset;
OwningMemory storage{};
};

struct OwningDatasetConst {
DatasetConst dataset;
OwningMemory storage{};
};
mgovers marked this conversation as resolved.
Show resolved Hide resolved
} // namespace power_grid_model_cpp

#endif // POWER_GRID_MODEL_CPP_DATASET_HPP
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "basics.hpp"
#include "dataset.hpp"
#include "handle.hpp"
#include "meta_data.hpp"

#include "power_grid_model_c/serialization.h"

Expand Down Expand Up @@ -90,6 +91,34 @@ class Serializer {
power_grid_model_cpp::Handle handle_{};
detail::UniquePtr<RawSerializer, &PGM_destroy_serializer> serializer_;
};

inline OwningDatasetConst create_owning_dataset(DatasetWritable& writable_dataset) {
auto const& info = writable_dataset.get_info();
bool const is_batch = info.is_batch();
Idx const batch_size = info.batch_size();
auto const& dataset_name = info.name();
DatasetMutable dataset_mutable{dataset_name, is_batch, batch_size};
DatasetConst dataset_const{dataset_mutable};
OwningMemory storage{};

for (Idx component_idx{}; component_idx < info.n_components(); ++component_idx) {
auto const& component_name = info.component_name(component_idx);
auto const& component_meta = MetaData::get_component_by_name(dataset_name, component_name);
Idx const component_elements_per_scenario = info.component_elements_per_scenario(component_idx);
Idx const component_size = info.component_total_elements(component_idx);

auto& current_indptr =
storage.indptrs.emplace_back(info.component_elements_per_scenario(component_idx) < 0 ? batch_size + 1 : 0);
if (!current_indptr.empty()) {
current_indptr.at(0) = 0;
current_indptr.at(batch_size) = component_size;
}
Idx* const indptr = current_indptr.empty() ? nullptr : current_indptr.data();
auto& current_buffer = storage.buffers.emplace_back(component_meta, component_size);
writable_dataset.set_buffer(component_name, indptr, current_buffer);
}
return OwningDatasetConst{.dataset = writable_dataset, .storage = std::move(storage)};
}
} // namespace power_grid_model_cpp

#endif // POWER_GRID_MODEL_CPP_SERIALIZATION_HPP
6 changes: 6 additions & 0 deletions tests/cpp_unit_tests/test_math_solver_common.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@

// In this unit test the powerflow solvers are tested

#pragma once
#ifndef POWER_GRID_MODEL_TESTS_CPP_UNIT_TESTS_TEST_MATH_SOLVER_COMMON_HPP
#define POWER_GRID_MODEL_TESTS_CPP_UNIT_TESTS_TEST_MATH_SOLVER_COMMON_HPP
mgovers marked this conversation as resolved.
Show resolved Hide resolved

#include <power_grid_model/calculation_parameters.hpp>
#include <power_grid_model/common/exception.hpp>
#include <power_grid_model/common/three_phase_tensor.hpp>
Expand Down Expand Up @@ -265,3 +269,5 @@ template <symmetry_tag sym_type> struct SteadyStateSolverTestGrid {
};

} // namespace power_grid_model

#endif // POWER_GRID_MODEL_TESTS_CPP_UNIT_TESTS_TEST_MATH_SOLVER_COMMON_HPP
6 changes: 6 additions & 0 deletions tests/cpp_unit_tests/test_math_solver_pf.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@

// In this unit test the powerflow solvers are tested

#pragma once
#ifndef POWER_GRID_MODEL_TESTS_CPP_UNIT_TESTS_TEST_MATH_SOLVER_PF_HPP
#define POWER_GRID_MODEL_TESTS_CPP_UNIT_TESTS_TEST_MATH_SOLVER_PF_HPP

mgovers marked this conversation as resolved.
Show resolved Hide resolved
#include "test_math_solver_common.hpp"

#include <power_grid_model/common/calculation_info.hpp>
Expand Down Expand Up @@ -142,3 +146,5 @@ TEST_CASE_TEMPLATE_DEFINE("Test math solver - PF", SolverType, test_math_solver_
}

} // namespace power_grid_model

#endif // POWER_GRID_MODEL_TESTS_CPP_UNIT_TESTS_TEST_MATH_SOLVER_PF_HPP
6 changes: 6 additions & 0 deletions tests/cpp_unit_tests/test_math_solver_se.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@

// In this unit test the powerflow solvers are tested

#pragma once
#ifndef POWER_GRID_MODEL_TESTS_CPP_UNIT_TESTS_TEST_MATH_SOLVER_SE_HPP
#define POWER_GRID_MODEL_TESTS_CPP_UNIT_TESTS_TEST_MATH_SOLVER_SE_HPP
mgovers marked this conversation as resolved.
Show resolved Hide resolved

#include "test_math_solver_common.hpp"

#include <power_grid_model/common/calculation_info.hpp>
Expand Down Expand Up @@ -516,3 +520,5 @@ TEST_CASE_TEMPLATE_DEFINE("Test math solver - SE, measurements", SolverType, tes
}

} // namespace power_grid_model

#endif // POWER_GRID_MODEL_TESTS_CPP_UNIT_TESTS_TEST_MATH_SOLVER_SE_HPP
6 changes: 6 additions & 0 deletions tests/cpp_unit_tests/test_optimizer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
//
// SPDX-License-Identifier: MPL-2.0

#pragma once
#ifndef POWER_GRID_MODEL_TESTS_CPP_UNIT_TESTS_TEST_OPTIMIZER_HPP
#define POWER_GRID_MODEL_TESTS_CPP_UNIT_TESTS_TEST_OPTIMIZER_HPP
mgovers marked this conversation as resolved.
Show resolved Hide resolved

#include <power_grid_model/auxiliary/meta_data.hpp>
#include <power_grid_model/auxiliary/meta_gen/gen_getters.hpp>
#include <power_grid_model/container.hpp>
Expand Down Expand Up @@ -246,3 +250,5 @@ template <> struct get_attributes_list<optimizer::test::StubTransformerUpdate> {
};
} // namespace meta_data
} // namespace power_grid_model

#endif // POWER_GRID_MODEL_TESTS_CPP_UNIT_TESTS_TEST_OPTIMIZER_HPP
99 changes: 23 additions & 76 deletions tests/cpp_validation_tests/test_validation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

#define PGM_ENABLE_EXPERIMENTAL

#include "power_grid_model_cpp.hpp"
#include <power_grid_model_cpp.hpp>

#include <doctest/doctest.h>
#include <nlohmann/json.hpp>
Expand Down Expand Up @@ -60,75 +60,29 @@ auto read_json(std::filesystem::path const& path) {
return j;
}

struct OwningMemory {
std::vector<Buffer> buffers;
std::vector<std::vector<Idx>> indptrs;
};

struct OwningDataset {
std::optional<DatasetMutable> dataset;
std::optional<DatasetConst> const_dataset;
OwningMemory storage{};
};
OwningDatasetMutable create_result_dataset(OwningDatasetConst const& input, std::string const& dataset_name,
bool is_batch = false, Idx batch_size = 1) {
DatasetInfo const& input_info = input.dataset.get_info();

OwningDataset create_owning_dataset(DatasetWritable& writable_dataset) {
auto const& info = writable_dataset.get_info();
bool const is_batch = info.is_batch();
Idx const batch_size = info.batch_size();
auto const& dataset_name = info.name();
OwningDataset owning_dataset{.dataset{DatasetMutable{dataset_name, is_batch, batch_size}},
.const_dataset = std::nullopt};

for (Idx component_idx{}; component_idx < info.n_components(); ++component_idx) {
auto const& component_name = info.component_name(component_idx);
auto const& component_meta = MetaData::get_component_by_name(dataset_name, component_name);
Idx const component_elements_per_scenario = info.component_elements_per_scenario(component_idx);
Idx const component_size = info.component_total_elements(component_idx);

auto& current_indptr = owning_dataset.storage.indptrs.emplace_back(
info.component_elements_per_scenario(component_idx) < 0 ? batch_size + 1 : 0);
if (!current_indptr.empty()) {
current_indptr.at(0) = 0;
current_indptr.at(batch_size) = component_size;
}
Idx* const indptr = current_indptr.empty() ? nullptr : current_indptr.data();
auto& current_buffer = owning_dataset.storage.buffers.emplace_back(component_meta, component_size);
writable_dataset.set_buffer(component_name, indptr, current_buffer);
owning_dataset.dataset.value().add_buffer(component_name, component_elements_per_scenario, component_size,
indptr, current_buffer);
}
owning_dataset.const_dataset = writable_dataset;
return owning_dataset;
}

OwningDataset create_result_dataset(OwningDataset const& input, std::string const& dataset_name, bool is_batch = false,
Idx batch_size = 1) {
OwningDataset owning_dataset{.dataset{DatasetMutable{dataset_name, is_batch, batch_size}},
.const_dataset = std::nullopt};

if (!input.const_dataset.has_value()) {
throw OptionalNotInitialized("DatasetConst");
}
DatasetInfo const& input_info = input.const_dataset.value().get_info();
OwningDatasetMutable result{.dataset{dataset_name, is_batch, batch_size}, .storage{}};

for (Idx component_idx{}; component_idx != input_info.n_components(); ++component_idx) {
auto const& component_name = input_info.component_name(component_idx);
auto const& component_meta = MetaData::get_component_by_name(dataset_name, component_name);
Idx const component_elements_per_scenario = input_info.component_elements_per_scenario(component_idx);
Idx const component_size = input_info.component_total_elements(component_idx);

auto& current_indptr = owning_dataset.storage.indptrs.emplace_back(
auto& current_indptr = result.storage.indptrs.emplace_back(
input_info.component_elements_per_scenario(component_idx) < 0 ? batch_size + 1 : 0);
Idx const* const indptr = current_indptr.empty() ? nullptr : current_indptr.data();
auto& current_buffer = owning_dataset.storage.buffers.emplace_back(component_meta, component_size);
owning_dataset.dataset.value().add_buffer(component_name, component_elements_per_scenario, component_size,
indptr, current_buffer);
auto& current_buffer = result.storage.buffers.emplace_back(component_meta, component_size);
result.dataset.add_buffer(component_name, component_elements_per_scenario, component_size, indptr,
current_buffer);
}
owning_dataset.const_dataset = owning_dataset.dataset.value();
return owning_dataset;
return result;
}

OwningDataset load_dataset(std::filesystem::path const& path) {
OwningDatasetConst load_dataset(std::filesystem::path const& path) {
// Issue in msgpack, reported in https://github.com/msgpack/msgpack-c/issues/1098
// May be a Clang Analyzer bug
#ifndef __clang_analyzer__ // TODO(mgovers): re-enable this when issue in msgpack is fixed
Expand Down Expand Up @@ -255,23 +209,17 @@ void check_individual_attribute(Buffer const& buffer, Buffer const& ref_buffer,
}
}

void assert_result(OwningDataset const& owning_result, OwningDataset const& owning_reference_result,
void assert_result(OwningDatasetMutable const& owning_result, OwningDatasetConst const& owning_reference_result,
std::map<std::string, double, std::less<>> atol, double rtol) {
using namespace std::string_literals;

if (!owning_result.const_dataset.has_value()) {
throw OptionalNotInitialized("DatasetConst");
}
DatasetConst const& result = owning_result.const_dataset.value();
DatasetConst const result{owning_result.dataset};
auto const& result_info = result.get_info();
auto const& result_name = result_info.name();
Idx const result_batch_size = result_info.batch_size();
auto const& storage = owning_result.storage;

if (!owning_reference_result.const_dataset.has_value()) {
throw OptionalNotInitialized("DatasetConst");
}
DatasetConst const& reference_result = owning_reference_result.const_dataset.value();
DatasetConst const& reference_result = owning_reference_result.dataset;
auto const& reference_result_info = reference_result.get_info();
auto const& reference_result_name = reference_result_info.name();
auto const& reference_storage = owning_reference_result.storage;
Expand Down Expand Up @@ -490,10 +438,10 @@ void add_cases(std::filesystem::path const& case_dir, std::string const& calcula
// test case with parameter
struct ValidationCase {
CaseParam param;
OwningDataset input;
std::optional<OwningDataset> output;
std::optional<OwningDataset> update_batch;
std::optional<OwningDataset> output_batch;
OwningDatasetConst input;
std::optional<OwningDatasetConst> output;
std::optional<OwningDatasetConst> update_batch;
std::optional<OwningDatasetConst> output_batch;
};

ValidationCase create_validation_case(CaseParam const& param, std::string const& output_type) {
Expand Down Expand Up @@ -574,8 +522,8 @@ void validate_single_case(CaseParam const& param) {

// create and run model
auto const& options = get_options(param);
Model model{50.0, validation_case.input.const_dataset.value()};
model.calculate(options, result.dataset.value());
Model model{50.0, validation_case.input.dataset};
model.calculate(options, result.dataset);

// check results
assert_result(result, validation_case.output.value(), param.atol, param.rtol);
Expand All @@ -586,21 +534,20 @@ void validate_batch_case(CaseParam const& param) {
execute_test(param, [&]() {
auto const output_prefix = get_output_type(param.calculation_type, param.sym);
auto const validation_case = create_validation_case(param, output_prefix);
auto const& info = validation_case.update_batch.value().const_dataset.value().get_info();
auto const& info = validation_case.update_batch.value().dataset.get_info();
Idx const batch_size = info.batch_size();
auto const batch_result =
create_result_dataset(validation_case.output_batch.value(), output_prefix, true, batch_size);

// create model
Model model{50.0, validation_case.input.const_dataset.value()};
Model model{50.0, validation_case.input.dataset};

// check results after whole update is finished
for (Idx const threading : {-1, 0, 1, 2}) {
CAPTURE(threading);
// set options and run
auto const& options = get_options(param, threading);
model.calculate(options, batch_result.dataset.value(),
validation_case.update_batch.value().const_dataset.value());
model.calculate(options, batch_result.dataset, validation_case.update_batch.value().dataset);

// check results
assert_result(batch_result, validation_case.output_batch.value(), param.atol, param.rtol);
Expand Down
21 changes: 21 additions & 0 deletions tests/native_api_tests/load_dataset.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// SPDX-FileCopyrightText: Contributors to the Power Grid Model project <[email protected]>
//
// SPDX-License-Identifier: MPL-2.0

#pragma once
#ifndef POWER_GRID_MODEL_TESTS_NATIVE_API_TESTS_LOAD_DATASET_HPP
#define POWER_GRID_MODEL_TESTS_NATIVE_API_TESTS_LOAD_DATASET_HPP

#include <power_grid_model_cpp/serialization.hpp>

namespace power_grid_model_cpp_test {
figueroa1395 marked this conversation as resolved.
Show resolved Hide resolved
inline power_grid_model_cpp::OwningDatasetConst load_dataset(std::string const& json_string) {
power_grid_model_cpp::Deserializer deserializer{json_string, PGM_json};
auto& writable_dataset = deserializer.get_dataset();
auto owning_dataset = power_grid_model_cpp::create_owning_dataset(writable_dataset);
deserializer.parse_to_buffer();
return owning_dataset;
}
} // namespace power_grid_model_cpp_test

#endif // POWER_GRID_MODEL_TESTS_NATIVE_API_TESTS_LOAD_DATASET_HPP
Loading
Loading