Skip to content

Commit 0cbf5e6

Browse files
committed
Merge branch 'main' into 211-python-dependencies
2 parents 3e0aae1 + 089a7e0 commit 0cbf5e6

29 files changed

+1255
-334
lines changed

cpp/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ option(MEMILIO_BUILD_TESTS "Build memilio unit tests." ON)
66
option(MEMILIO_BUILD_EXAMPLES "Build memilio examples." ON)
77
option(MEMILIO_BUILD_MODELS "Build memilio models." ON)
88
option(MEMILIO_BUILD_SIMULATIONS "Build memilio simulations that were used for scientific articles." ON)
9+
option(MEMILIO_BUILD_BENCHMARKS "Build memilio benchmarks with google benchmark." OFF)
910
option(MEMILIO_USE_BUNDLED_SPDLOG "Use spdlog bundled with epi" ON)
1011
option(MEMILIO_USE_BUNDLED_EIGEN "Use eigen bundled with epi" ON)
1112
option(MEMILIO_USE_BUNDLED_BOOST "Use boost bundled with epi (only for epi-io)" ON)
@@ -84,6 +85,9 @@ endif()
8485
if (MEMILIO_BUILD_SIMULATIONS)
8586
add_subdirectory(simulations)
8687
endif()
88+
if (MEMILIO_BUILD_BENCHMARKS)
89+
add_subdirectory(benchmarks)
90+
endif()
8791

8892
# install
8993
include(GNUInstallDirs)

cpp/benchmarks/CMakeLists.txt

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
set(BENCHMARK_ENABLE_TESTING OFF CACHE BOOL "Disable benchmark testing" FORCE)
2+
#set(BENCHMARK_ENABLE_EXCEPTIONS OFF CACHE BOOL "Disable benchmark exceptions" FORCE)
3+
set(BENCHMARK_ENABLE_INSTALL OFF CACHE BOOL "Don't install benchmark" FORCE)
4+
set(BENCHMARK_DOWNLOAD_DEPENDENCIES OFF CACHE BOOL "Don't download dependencies" FORCE)
5+
set(BENCHMARK_ENABLE_GTEST_TESTS OFF CACHE BOOL "Disable Google Test in benchmark" FORCE)
6+
7+
if(CMAKE_VERSION VERSION_LESS 3.11)
8+
set(UPDATE_DISCONNECTED_IF_AVAILABLE "UPDATE_DISCONNECTED 1")
9+
10+
include(DownloadProject)
11+
download_project(PROJ benchmark
12+
GIT_REPOSITORY https://github.com/google/benchmark.git
13+
GIT_TAG v1.6.1
14+
UPDATE_DISCONNECTED 1
15+
QUIET
16+
)
17+
18+
# CMake warning suppression will not be needed in version 1.9
19+
set(CMAKE_SUPPRESS_DEVELOPER_WARNINGS 1 CACHE BOOL "")
20+
add_subdirectory(${benchmark_SOURCE_DIR} ${benchmark_SOURCE_DIR} EXCLUDE_FROM_ALL)
21+
unset(CMAKE_SUPPRESS_DEVELOPER_WARNINGS)
22+
else()
23+
include(FetchContent)
24+
FetchContent_Declare(benchmark
25+
GIT_REPOSITORY https://github.com/google/benchmark.git
26+
GIT_TAG v1.6.1)
27+
FetchContent_GetProperties(benchmark)
28+
if(NOT benchmark_POPULATED)
29+
FetchContent_Populate(benchmark)
30+
set(CMAKE_SUPPRESS_DEVELOPER_WARNINGS 1 CACHE BOOL "")
31+
add_subdirectory(${benchmark_SOURCE_DIR} ${benchmark_BINARY_DIR} EXCLUDE_FROM_ALL)
32+
unset(CMAKE_SUPPRESS_DEVELOPER_WARNINGS)
33+
endif()
34+
endif()
35+
36+
set_target_properties(benchmark PROPERTIES FOLDER "Extern")
37+
38+
add_executable(simulation_benchmark simulation.cpp)
39+
target_link_libraries(simulation_benchmark PRIVATE memilio secir benchmark::benchmark)
40+
41+
add_executable(integrator_step_benchmark integrator_step.cpp)
42+
target_link_libraries(integrator_step_benchmark PRIVATE memilio secir benchmark::benchmark)

cpp/benchmarks/integrator_step.config

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"abs_tol" : 1e-10,
3+
"dt_init" : 1,
4+
"dt_max" : 1.7976931348623157e+308,
5+
"dt_min" : 2.2250738585072014e-308,
6+
"num_agegroups" : 1,
7+
"rel_tol" : 1e-5,
8+
"t_init" : 50,
9+
"yt" :
10+
[
11+
6377.873644,
12+
35.24915600,
13+
30.02961100,
14+
182.1458650,
15+
66.15305900,
16+
79.53062100,
17+
3069.383604,
18+
159.6344400
19+
]
20+
}

cpp/benchmarks/integrator_step.cpp

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
* Copyright (cfg) 2020-2021 German Aerospace Center (DLR-SC)
3+
*
4+
* Authors: Rene Schmieding
5+
*
6+
* Contact: Martin J. Kuehn <[email protected]>
7+
*
8+
* Licensed under the Apache License, Version 2.0 (the "License");
9+
* you may not use this file except in compliance with the License.
10+
* You may obtain a copy of the License at
11+
*
12+
* http://www.apache.org/licenses/LICENSE-2.0
13+
*
14+
* Unless required by applicable law or agreed to in writing, software
15+
* distributed under the License is distributed on an "AS IS" BASIS,
16+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17+
* See the License for the specific language governing permissions and
18+
* limitations under the License.
19+
*/
20+
#include "benchmarks/integrator_step.h"
21+
#include "benchmarks/secir_ageres_setups.h"
22+
23+
#include "memilio/math/adapt_rk.h"
24+
#include "memilio/math/stepper_wrapper.h"
25+
26+
template <class Integrator>
27+
void integrator_step(::benchmark::State& state)
28+
{
29+
// suppress non-critical messages
30+
mio::set_log_level(mio::LogLevel::critical);
31+
// NOTE: make sure that yt has sensible values, e.g. by creating a simulation with the chosen model
32+
// with "num_agegroups" agegroups, and taking "yt" as the state of the simulation at "t_init"
33+
// NOTE: yt must have #agegroups * #compartments entries
34+
// benchmark setup
35+
auto cfg = mio::benchmark::IntegratorStepConfig::initialize("benchmarks/integrator_step.config");
36+
//auto cfg = mio::benchmark::IntegratorStepConfig::initialize();
37+
auto model = mio::benchmark::model::SecirAgeres(cfg.num_agegroups);
38+
// set deriv function and integrator
39+
mio::DerivFunction f = [model](Eigen::Ref<const Eigen::VectorXd> x, double s, Eigen::Ref<Eigen::VectorXd> dxds) {
40+
model.eval_right_hand_side(x, x, s, dxds);
41+
};
42+
auto I = Integrator(cfg.abs_tol, cfg.rel_tol, cfg.dt_min, cfg.dt_max);
43+
44+
double t, dt;
45+
for (auto _ : state) {
46+
// This code gets timed
47+
t = cfg.t_init;
48+
dt = cfg.dt_init;
49+
I.step(f, cfg.yt, t, dt, cfg.ytp1);
50+
}
51+
}
52+
53+
// dummy runs to avoid large effects of cpu scaling on times of actual benchmarks
54+
BENCHMARK_TEMPLATE(integrator_step, mio::RKIntegratorCore)->Name("Dummy 1/3");
55+
BENCHMARK_TEMPLATE(integrator_step, mio::RKIntegratorCore)->Name("Dummy 2/3");
56+
BENCHMARK_TEMPLATE(integrator_step, mio::RKIntegratorCore)->Name("Dummy 3/3");
57+
// register functions as a benchmarks and set a name
58+
BENCHMARK_TEMPLATE(integrator_step, mio::RKIntegratorCore)->Name("simulate SecirModel adapt_rk");
59+
BENCHMARK_TEMPLATE(integrator_step, mio::ControlledStepperWrapper<boost::numeric::odeint::runge_kutta_cash_karp54>)
60+
->Name("simulate SecirModel boost rk_ck54");
61+
BENCHMARK_TEMPLATE(integrator_step, mio::ControlledStepperWrapper<boost::numeric::odeint::runge_kutta_dopri5>)
62+
->Name("simulate SecirModel boost rk_dopri5");
63+
BENCHMARK_TEMPLATE(integrator_step, mio::ControlledStepperWrapper<boost::numeric::odeint::runge_kutta_fehlberg78>)
64+
->Name("simulate SecirModel boost rkf78");
65+
// run all benchmarks
66+
BENCHMARK_MAIN();

cpp/benchmarks/integrator_step.h

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
/*
2+
* Copyright (C) 2020-2021 German Aerospace Center (DLR-SC)
3+
*
4+
* Authors: Rene Schmieding
5+
*
6+
* Contact: Martin J. Kuehn <[email protected]>
7+
*
8+
* Licensed under the Apache License, Version 2.0 (the "License");
9+
* you may not use this file except in compliance with the License.
10+
* You may obtain a copy of the License at
11+
*
12+
* http://www.apache.org/licenses/LICENSE-2.0
13+
*
14+
* Unless required by applicable law or agreed to in writing, software
15+
* distributed under the License is distributed on an "AS IS" BASIS,
16+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17+
* See the License for the specific language governing permissions and
18+
* limitations under the License.
19+
*/
20+
#ifndef INTEGRATOR_STEP_H_
21+
#define INTEGRATOR_STEP_H_
22+
23+
#include "memilio/io/json_serializer.h"
24+
#include "memilio/utils/logging.h"
25+
26+
#include "benchmark/benchmark.h"
27+
28+
namespace mio
29+
{
30+
namespace benchmark
31+
{
32+
/// @brief parameters for integrator-step benchmark
33+
struct IntegratorStepConfig {
34+
int num_agegroups;
35+
double t_init, dt_init, abs_tol, rel_tol, dt_min, dt_max;
36+
Eigen::VectorXd yt, ytp1;
37+
/**
38+
* @brief creates configuration with default parameters for a secir model
39+
* @return configuration for integrator-step benchmark
40+
*/
41+
static IntegratorStepConfig initialize()
42+
{
43+
const double vals[8] = {6377.873644, 35.249156, 30.029611, 182.145865,
44+
66.153059, 79.530621, 3069.383604, 159.634440};
45+
return IntegratorStepConfig{1,
46+
50,
47+
1,
48+
1e-10,
49+
1e-5,
50+
std::numeric_limits<double>::min(),
51+
std::numeric_limits<double>::max(),
52+
Eigen::Matrix<double, 8, 1>(vals),
53+
Eigen::VectorXd::Zero(8)};
54+
}
55+
/**
56+
* @brief reads configuration from json file
57+
* @param path the path of the configfile
58+
* @return configuration for integrator-step benchmark
59+
*/
60+
static IntegratorStepConfig initialize(std::string path)
61+
{
62+
auto result = mio::read_json(path, mio::Tag<IntegratorStepConfig>{});
63+
if (!result) { // failed to read config
64+
mio::log(mio::LogLevel::critical, result.error().formatted_message());
65+
abort();
66+
}
67+
return result.value();
68+
}
69+
/// @brief function implementing mio::deserialize, used by read_json in initialize
70+
template <class IOContext>
71+
static mio::IOResult<IntegratorStepConfig> deserialize(IOContext& io)
72+
{
73+
auto obj = io.expect_object("integrator_step");
74+
auto num_agegroups_io = obj.expect_element("num_agegroups", mio::Tag<int>{});
75+
auto t_init_io = obj.expect_element("t_init", mio::Tag<double>{});
76+
auto dt_init_io = obj.expect_element("dt_init", mio::Tag<double>{});
77+
auto abs_tol_io = obj.expect_element("abs_tol", mio::Tag<double>{});
78+
auto rel_tol_io = obj.expect_element("rel_tol", mio::Tag<double>{});
79+
auto dt_min_io = obj.expect_element("dt_min", mio::Tag<double>{});
80+
auto dt_max_io = obj.expect_element("dt_max", mio::Tag<double>{});
81+
auto yt_io = obj.expect_list("yt", mio::Tag<double>{});
82+
return mio::apply(
83+
io,
84+
[](auto&& num_agegroups, auto&& t_init, auto&& dt_init, auto&& abs_tol, auto&& rel_tol, auto&& dt_min,
85+
auto&& dt_max, auto&& yt) {
86+
IntegratorStepConfig cfg{num_agegroups,
87+
t_init,
88+
dt_init,
89+
abs_tol,
90+
rel_tol,
91+
dt_min,
92+
dt_max,
93+
Eigen::VectorXd::Zero(yt.size()),
94+
Eigen::VectorXd::Zero(yt.size())};
95+
for (size_t i = 0; i < yt.size(); i++) {
96+
cfg.yt[i] = yt[i];
97+
}
98+
return cfg;
99+
},
100+
num_agegroups_io, t_init_io, dt_init_io, abs_tol_io, rel_tol_io, dt_min_io, dt_max_io, yt_io);
101+
}
102+
};
103+
} // namespace benchmark
104+
105+
} // namespace mio
106+
107+
#endif

0 commit comments

Comments
 (0)