alpaqa no-casadi-dep
Nonconvex constrained optimization
Loading...
Searching...
No Matches
problem-with-counters.hpp
Go to the documentation of this file.
1#pragma once
2
7
8#include <type_traits>
9
10namespace alpaqa {
11
12/// @addtogroup grp_Problems
13/// @{
14
15/// Problem wrapper that keeps track of the number of evaluations and the run
16/// time of each function.
17/// You probably want to use @ref problem_with_counters or
18/// @ref problem_with_counters_ref instead of instantiating this class directly.
19/// @note The evaluation counters are stored using a `std::shared_pointers`,
20/// which means that different copies of a @ref ProblemWithCounters
21/// instance all share the same counters. To opt out of this behavior,
22/// you can use the @ref decouple_evaluations function.
23template <class Problem>
25 USING_ALPAQA_CONFIG_TEMPLATE(std::remove_cvref_t<Problem>::config_t);
28
29 // clang-format off
30 [[gnu::always_inline]] void eval_proj_diff_g(crvec z, rvec e) const { ++evaluations->proj_diff_g; return timed(evaluations->time.proj_diff_g, [&] { return problem.eval_proj_diff_g(z, e); }); }
31 [[gnu::always_inline]] void eval_proj_multipliers(rvec y, real_t M) const { ++evaluations->proj_multipliers; return timed(evaluations->time.proj_multipliers, [&] { return problem.eval_proj_multipliers(y, M); }); }
32 [[gnu::always_inline]] real_t eval_prox_grad_step(real_t γ, crvec x, crvec grad_ψ, rvec x̂, rvec p) const { ++evaluations->prox_grad_step; return timed(evaluations->time.prox_grad_step, [&] { return problem.eval_prox_grad_step(γ, x, grad_ψ, x̂, p); }); }
33 [[gnu::always_inline]] index_t eval_inactive_indices_res_lna(real_t γ, crvec x, crvec grad_ψ, rindexvec J) const requires requires { &std::remove_cvref_t<Problem>::eval_inactive_indices_res_lna; } { ++evaluations->inactive_indices_res_lna; return timed(evaluations->time.inactive_indices_res_lna, [&] { return problem.eval_inactive_indices_res_lna(γ, x, grad_ψ, J); }); }
34 [[gnu::always_inline]] real_t eval_f(crvec x) const { ++evaluations->f; return timed(evaluations->time.f, [&] { return problem.eval_f(x); }); }
35 [[gnu::always_inline]] void eval_grad_f(crvec x, rvec grad_fx) const { ++evaluations->grad_f; return timed(evaluations->time.grad_f, [&] { return problem.eval_grad_f(x, grad_fx); }); }
36 [[gnu::always_inline]] void eval_g(crvec x, rvec gx) const { ++evaluations->g; return timed(evaluations->time.g, [&] { return problem.eval_g(x, gx); }); }
37 [[gnu::always_inline]] void eval_grad_g_prod(crvec x, crvec y, rvec grad_gxy) const { ++evaluations->grad_g_prod; return timed(evaluations->time.grad_g_prod, [&] { return problem.eval_grad_g_prod(x, y, grad_gxy); }); }
38 [[gnu::always_inline]] void eval_grad_gi(crvec x, index_t i, rvec grad_gi) const requires requires { &std::remove_cvref_t<Problem>::eval_grad_gi; } { ++evaluations->grad_gi; return timed(evaluations->time.grad_gi, [&] { return problem.eval_grad_gi(x, i, grad_gi); }); }
39 [[gnu::always_inline]] void eval_jac_g(crvec x, rvec J_values) const requires requires { &std::remove_cvref_t<Problem>::eval_jac_g; } { ++evaluations->jac_g; return timed(evaluations->time.jac_g, [&] { return problem.eval_jac_g(x, J_values); }); }
40 [[gnu::always_inline]] Sparsity get_jac_g_sparsity() const requires requires { &std::remove_cvref_t<Problem>::get_jac_g_sparsity; } { return problem.get_jac_g_sparsity(); }
41 [[gnu::always_inline]] void eval_hess_L_prod(crvec x, crvec y, real_t scale, crvec v, rvec Hv) const requires requires { &std::remove_cvref_t<Problem>::eval_hess_L_prod; } { ++evaluations->hess_L_prod; return timed(evaluations->time.hess_L_prod, [&] { return problem.eval_hess_L_prod(x, y, scale, v, Hv); }); }
42 [[gnu::always_inline]] void eval_hess_L(crvec x, crvec y, real_t scale, rvec H_values) const requires requires { &std::remove_cvref_t<Problem>::eval_hess_L; } { ++evaluations->hess_L; return timed(evaluations->time.hess_L, [&] { return problem.eval_hess_L(x, y, scale, H_values); }); }
43 [[gnu::always_inline]] Sparsity get_hess_L_sparsity() const requires requires { &std::remove_cvref_t<Problem>::get_hess_L_sparsity; } { return problem.get_hess_L_sparsity(); }
44 [[gnu::always_inline]] void eval_hess_ψ_prod(crvec x, crvec y, crvec Σ, real_t scale, crvec v, rvec Hv) const requires requires { &std::remove_cvref_t<Problem>::eval_hess_ψ_prod; } { ++evaluations->hess_ψ_prod; return timed(evaluations->time.hess_ψ_prod, [&] { return problem.eval_hess_ψ_prod(x, y, Σ, scale, v, Hv); }); }
45 [[gnu::always_inline]] void eval_hess_ψ(crvec x, crvec y, crvec Σ, real_t scale, rvec H_values) const requires requires { &std::remove_cvref_t<Problem>::eval_hess_ψ; } { ++evaluations->hess_ψ; return timed(evaluations->time.hess_ψ, [&] { return problem.eval_hess_ψ(x, y, Σ, scale, H_values); }); }
46 [[gnu::always_inline]] Sparsity get_hess_ψ_sparsity() const requires requires { &std::remove_cvref_t<Problem>::get_hess_ψ_sparsity; } { return problem.get_hess_ψ_sparsity(); }
47 [[gnu::always_inline]] real_t eval_f_grad_f(crvec x, rvec grad_fx) const requires requires { &std::remove_cvref_t<Problem>::eval_f_grad_f; } { ++evaluations->f_grad_f; return timed(evaluations->time.f_grad_f, [&] { return problem.eval_f_grad_f(x, grad_fx); }); }
48 [[gnu::always_inline]] real_t eval_f_g(crvec x, rvec g) const requires requires { &std::remove_cvref_t<Problem>::eval_f_g; } { ++evaluations->f_g; return timed(evaluations->time.f_g, [&] { return problem.eval_f_g(x, g); }); }
49 [[gnu::always_inline]] void eval_grad_f_grad_g_prod(crvec x, crvec y, rvec grad_f, rvec grad_gxy) const requires requires { &std::remove_cvref_t<Problem>::eval_grad_f_grad_g_prod; } { ++evaluations->grad_f_grad_g_prod; return timed(evaluations->time.grad_f_grad_g_prod, [&] { return problem.eval_grad_f_grad_g_prod(x, y, grad_f, grad_gxy); }); }
50 [[gnu::always_inline]] void eval_grad_L(crvec x, crvec y, rvec grad_L, rvec work_n) const requires requires { &std::remove_cvref_t<Problem>::eval_grad_L; } { ++evaluations->grad_L; return timed(evaluations->time.grad_L, [&] { return problem.eval_grad_L(x, y, grad_L, work_n); }); }
51 [[gnu::always_inline]] real_t eval_ψ(crvec x, crvec y, crvec Σ, rvec ŷ) const requires requires { &std::remove_cvref_t<Problem>::eval_ψ; } { ++evaluations->ψ; return timed(evaluations->time.ψ, [&] { return problem.eval_ψ(x, y, Σ, ŷ); }); }
52 [[gnu::always_inline]] void eval_grad_ψ(crvec x, crvec y, crvec Σ, rvec grad_ψ, rvec work_n, rvec work_m) const requires requires { &std::remove_cvref_t<Problem>::eval_grad_ψ; } { ++evaluations->grad_ψ; return timed(evaluations->time.grad_ψ, [&] { return problem.eval_grad_ψ(x, y, Σ, grad_ψ, work_n, work_m); }); }
53 [[gnu::always_inline]] real_t eval_ψ_grad_ψ(crvec x, crvec y, crvec Σ, rvec grad_ψ, rvec work_n, rvec work_m) const requires requires { &std::remove_cvref_t<Problem>::eval_ψ_grad_ψ; } { ++evaluations->ψ_grad_ψ; return timed(evaluations->time.ψ_grad_ψ, [&] { return problem.eval_ψ_grad_ψ(x, y, Σ, grad_ψ, work_n, work_m); }); }
54 const Box &get_box_C() const requires requires { &std::remove_cvref_t<Problem>::get_box_C; } { return problem.get_box_C(); }
55 const Box &get_box_D() const requires requires { &std::remove_cvref_t<Problem>::get_box_D; } { return problem.get_box_D(); }
56 void check() const requires requires { &std::remove_cvref_t<Problem>::check; } { return problem.check(); }
57 [[nodiscard]] std::string get_name() const requires requires { &std::remove_cvref_t<Problem>::get_name; } { return problem.get_name(); }
58
59 [[nodiscard]] bool provides_eval_grad_gi() const requires requires (Problem p) { { p.provides_eval_grad_gi() } -> std::convertible_to<bool>; } { return problem.provides_eval_grad_gi(); }
60 [[nodiscard]] bool provides_eval_inactive_indices_res_lna() const requires requires (Problem p) { { p.provides_eval_inactive_indices_res_lna() } -> std::convertible_to<bool>; } { return problem.provides_eval_inactive_indices_res_lna(); }
61 [[nodiscard]] bool provides_eval_jac_g() const requires requires (Problem p) { { p.provides_eval_jac_g() } -> std::convertible_to<bool>; } { return problem.provides_eval_jac_g(); }
62 [[nodiscard]] bool provides_get_jac_g_sparsity() const requires requires (Problem p) { { p.provides_get_jac_g_sparsity() } -> std::convertible_to<bool>; } { return problem.provides_get_jac_g_sparsity(); }
63 [[nodiscard]] bool provides_eval_hess_L_prod() const requires requires (Problem p) { { p.provides_eval_hess_L_prod() } -> std::convertible_to<bool>; } { return problem.provides_eval_hess_L_prod(); }
64 [[nodiscard]] bool provides_eval_hess_L() const requires requires (Problem p) { { p.provides_eval_hess_L() } -> std::convertible_to<bool>; } { return problem.provides_eval_hess_L(); }
65 [[nodiscard]] bool provides_get_hess_L_sparsity() const requires requires (Problem p) { { p.provides_get_hess_L_sparsity() } -> std::convertible_to<bool>; } { return problem.provides_get_hess_L_sparsity(); }
66 [[nodiscard]] bool provides_eval_hess_ψ_prod() const requires requires (Problem p) { { p.provides_eval_hess_ψ() } -> std::convertible_to<bool>; } { return problem.provides_eval_hess_ψ_prod(); }
67 [[nodiscard]] bool provides_eval_hess_ψ() const requires requires (Problem p) { { p.provides_eval_hess_ψ() } -> std::convertible_to<bool>; } { return problem.provides_eval_hess_ψ(); }
68 [[nodiscard]] bool provides_get_hess_ψ_sparsity() const requires requires (Problem p) { { p.provides_get_hess_ψ_sparsity() } -> std::convertible_to<bool>; } { return problem.provides_get_hess_ψ_sparsity(); }
69 [[nodiscard]] bool provides_eval_f_grad_f() const requires requires (Problem p) { { p.provides_eval_f_grad_f() } -> std::convertible_to<bool>; } { return problem.provides_eval_f_grad_f(); }
70 [[nodiscard]] bool provides_eval_f_g() const requires requires (Problem p) { { p.provides_eval_f_g() } -> std::convertible_to<bool>; } { return problem.provides_eval_f_g(); }
71 [[nodiscard]] bool provides_eval_grad_f_grad_g_prod() const requires requires (Problem p) { { p.provides_eval_grad_f_grad_g_prod() } -> std::convertible_to<bool>; } { return problem.provides_eval_grad_f_grad_g_prod(); }
72 [[nodiscard]] bool provides_eval_grad_L() const requires requires (Problem p) { { p.provides_eval_grad_L() } -> std::convertible_to<bool>; } { return problem.provides_eval_grad_L(); }
73 [[nodiscard]] bool provides_eval_ψ() const requires requires (Problem p) { { p.provides_eval_ψ() } -> std::convertible_to<bool>; } { return problem.provides_eval_ψ(); }
74 [[nodiscard]] bool provides_eval_grad_ψ() const requires requires (Problem p) { { p.provides_eval_grad_ψ() } -> std::convertible_to<bool>; } { return problem.provides_eval_grad_ψ(); }
75 [[nodiscard]] bool provides_eval_ψ_grad_ψ() const requires requires (Problem p) { { p.provides_eval_ψ_grad_ψ() } -> std::convertible_to<bool>; } { return problem.provides_eval_ψ_grad_ψ(); }
76 [[nodiscard]] bool provides_get_box_C() const requires requires (Problem p) { { p.provides_get_box_C() } -> std::convertible_to<bool>; } { return problem.provides_get_box_C(); }
77 [[nodiscard]] bool provides_get_box_D() const requires requires (Problem p) { { p.provides_get_box_D() } -> std::convertible_to<bool>; } { return problem.provides_get_box_D(); }
78 [[nodiscard]] bool provides_check() const requires requires (Problem p) { { p.provides_check() } -> std::convertible_to<bool>; } { return problem.provides_check(); }
79 [[nodiscard]] bool provides_get_name() const requires requires (Problem p) { { p.provides_get_name() } -> std::convertible_to<bool>; } { return problem.provides_get_name(); }
80 // clang-format on
81
82 [[nodiscard]] length_t get_n() const { return problem.get_n(); }
83 [[nodiscard]] length_t get_m() const { return problem.get_m(); }
84
85 std::shared_ptr<EvalCounter> evaluations = std::make_shared<EvalCounter>();
86 Problem problem;
87
89 requires std::is_default_constructible_v<Problem>
90 = default;
91 template <class P>
93 requires std::is_same_v<std::remove_cvref_t<P>, std::remove_cvref_t<Problem>>
94 : problem{std::forward<P>(problem)} {}
95 template <class... Args>
96 explicit ProblemWithCounters(std::in_place_t, Args &&...args)
97 requires(!std::is_lvalue_reference_v<Problem>)
98 : problem{std::forward<Args>(args)...} {}
99
100 /// Reset all evaluation counters and timers to zero. Affects all instances
101 /// that share the same evaluations. If you only want to reset the counters
102 /// of this instance, use @ref decouple_evaluations first.
103 void reset_evaluations() { evaluations.reset(); }
104 /// Give this instance its own evaluation counters and timers, decoupling
105 /// it from any other instances they might have previously been shared with.
106 /// The evaluation counters and timers are preserved (a copy is made).
107 void decouple_evaluations() { evaluations = std::make_shared<EvalCounter>(*evaluations); }
108
109 private:
110 template <class TimeT, class FunT>
111 [[gnu::always_inline]] static decltype(auto) timed(TimeT &time, FunT &&f) {
112 util::Timed timed{time};
113 return std::forward<FunT>(f)();
114 }
115};
116
117/// Wraps the given problem into a @ref ProblemWithCounters and keeps track of
118/// how many times each function is called, and how long these calls took.
119/// The wrapper has its own copy of the given problem. Making copies of the
120/// wrapper also copies the underlying problem, but does not copy the evaluation
121/// counters, all copies share the same counters.
122template <class Problem>
123[[nodiscard]] auto problem_with_counters(Problem &&p) {
124 using Prob = std::remove_cvref_t<Problem>;
126 return ProbWithCnt{std::forward<Problem>(p)};
127}
128
129/// Wraps the given problem into a @ref ProblemWithCounters and keeps track of
130/// how many times each function is called, and how long these calls took.
131/// The wrapper keeps only a reference to the given problem, it is the
132/// responsibility of the caller to make sure that the wrapper does not outlive
133/// the original problem. Making copies of the wrapper does not copy the
134/// evaluation counters, all copies share the same counters.
135template <class Problem>
137 using Prob = std::remove_cvref_t<Problem>;
139 return ProbWithCnt{p};
140}
141
142/// @}
143
144} // namespace alpaqa
#define USING_ALPAQA_CONFIG_TEMPLATE(Conf)
Definition config.hpp:81
auto problem_with_counters(Problem &&p)
Wraps the given problem into a ProblemWithCounters and keeps track of how many times each function is...
auto problem_with_counters_ref(Problem &p)
Wraps the given problem into a ProblemWithCounters and keeps track of how many times each function is...
typename Conf::real_t real_t
Definition config.hpp:86
typename Conf::rindexvec rindexvec
Definition config.hpp:106
typename Conf::index_t index_t
Definition config.hpp:104
typename Conf::length_t length_t
Definition config.hpp:103
constexpr const auto inf
Definition config.hpp:112
typename Conf::rvec rvec
Definition config.hpp:91
typename Conf::crvec crvec
Definition config.hpp:92
Problem wrapper that keeps track of the number of evaluations and the run time of each function.
void eval_hess_ψ_prod(crvec x, crvec y, crvec Σ, real_t scale, crvec v, rvec Hv) const
void decouple_evaluations()
Give this instance its own evaluation counters and timers, decoupling it from any other instances the...
real_t eval_ψ_grad_ψ(crvec x, crvec y, crvec Σ, rvec grad_ψ, rvec work_n, rvec work_m) const
void eval_grad_ψ(crvec x, crvec y, crvec Σ, rvec grad_ψ, rvec work_n, rvec work_m) const
void eval_grad_L(crvec x, crvec y, rvec grad_L, rvec work_n) const
std::shared_ptr< EvalCounter > evaluations
real_t eval_ψ(crvec x, crvec y, crvec Σ, rvec ŷ) const
void reset_evaluations()
Reset all evaluation counters and timers to zero.
void eval_hess_L(crvec x, crvec y, real_t scale, rvec H_values) const
typename TypeErasedProblem< config_t >::Box Box
real_t eval_f_grad_f(crvec x, rvec grad_fx) const
index_t eval_inactive_indices_res_lna(real_t γ, crvec x, crvec grad_ψ, rindexvec J) const
void eval_grad_g_prod(crvec x, crvec y, rvec grad_gxy) const
void eval_hess_L_prod(crvec x, crvec y, real_t scale, crvec v, rvec Hv) const
void eval_proj_multipliers(rvec y, real_t M) const
void eval_grad_f(crvec x, rvec grad_fx) const
void eval_grad_gi(crvec x, index_t i, rvec grad_gi) const
real_t eval_f_g(crvec x, rvec g) const
real_t eval_prox_grad_step(real_t γ, crvec x, crvec grad_ψ, rvec x̂, rvec p) const
void eval_g(crvec x, rvec gx) const
void eval_jac_g(crvec x, rvec J_values) const
ProblemWithCounters(std::in_place_t, Args &&...args)
void eval_proj_diff_g(crvec z, rvec e) const
static decltype(auto) timed(TimeT &time, FunT &&f)
void eval_grad_f_grad_g_prod(crvec x, crvec y, rvec grad_f, rvec grad_gxy) const
void eval_hess_ψ(crvec x, crvec y, crvec Σ, real_t scale, rvec H_values) const