26 std::string s(16,
'0');
27 auto begin = s.data(), end = begin + s.size();
28 auto [ptr, ec] = std::to_chars(begin, end, version, 16);
29 if (ec != std::errc())
30 throw std::logic_error(std::make_error_code(ec).message());
31 std::rotate(begin, ptr, end);
40 "alpaqa::dl::DLProblem::DLProblem: "
41 "Incompatible problem definition (problem ABI version 0x" +
42 prob_version +
", this version of alpaqa supports 0x" +
43 alpaqa_version +
")");
59 using sparsity::Symmetry;
61 return sparsity::Dense{
62 .rows = sp.dense.rows,
63 .cols = sp.dense.cols,
64 .symmetry =
static_cast<Symmetry
>(sp.dense.symmetry),
67 using SparseCSC = sparsity::SparseCSC<int, int>;
69 .rows = sp.sparse_csc.rows,
70 .cols = sp.sparse_csc.cols,
71 .symmetry =
static_cast<Symmetry
>(sp.sparse_csc.symmetry),
72 .inner_idx = std::span{sp.sparse_csc.inner_idx,
static_cast<size_t>(sp.sparse_csc.nnz)},
73 .outer_ptr = std::span{sp.sparse_csc.outer_ptr,
static_cast<size_t>(sp.sparse_csc.cols + 1)},
74 .order =
static_cast<typename SparseCSC::Order
>(sp.sparse_csc.order),
77 using SparseCSCl = sparsity::SparseCSC<long, long>;
79 .rows = sp.sparse_csc_l.rows,
80 .cols = sp.sparse_csc_l.cols,
81 .symmetry =
static_cast<Symmetry
>(sp.sparse_csc_l.symmetry),
82 .inner_idx = std::span{sp.sparse_csc_l.inner_idx,
static_cast<size_t>(sp.sparse_csc_l.nnz)},
83 .outer_ptr = std::span{sp.sparse_csc_l.outer_ptr,
static_cast<size_t>(sp.sparse_csc_l.cols + 1)},
84 .order =
static_cast<typename SparseCSCl::Order
>(sp.sparse_csc_l.order),
87 using SparseCSCll = sparsity::SparseCSC<long long, long long>;
89 .rows = sp.sparse_csc_ll.rows,
90 .cols = sp.sparse_csc_ll.cols,
91 .symmetry =
static_cast<Symmetry
>(sp.sparse_csc_ll.symmetry),
92 .inner_idx = std::span{sp.sparse_csc_ll.inner_idx,
static_cast<size_t>(sp.sparse_csc_ll.nnz)},
93 .outer_ptr = std::span{sp.sparse_csc_ll.outer_ptr,
static_cast<size_t>(sp.sparse_csc_ll.cols + 1)},
94 .order =
static_cast<typename SparseCSCll::Order
>(sp.sparse_csc_ll.order),
97 using SparseCOO = sparsity::SparseCOO<int>;
99 .rows = sp.sparse_coo.rows,
100 .cols = sp.sparse_coo.cols,
101 .symmetry =
static_cast<Symmetry
>(sp.sparse_coo.symmetry),
102 .row_indices = std::span{sp.sparse_coo.row_indices,
static_cast<size_t>(sp.sparse_coo.nnz)},
103 .col_indices = std::span{sp.sparse_coo.col_indices,
static_cast<size_t>(sp.sparse_coo.nnz)},
104 .order =
static_cast<typename SparseCOO::Order
>(sp.sparse_coo.order),
105 .first_index = sp.sparse_coo.first_index,
108 using SparseCOOl = sparsity::SparseCOO<long>;
110 .rows = sp.sparse_coo_l.rows,
111 .cols = sp.sparse_coo_l.cols,
112 .symmetry =
static_cast<Symmetry
>(sp.sparse_coo_l.symmetry),
113 .row_indices = std::span{sp.sparse_coo_l.row_indices,
static_cast<size_t>(sp.sparse_coo_l.nnz)},
114 .col_indices = std::span{sp.sparse_coo_l.col_indices,
static_cast<size_t>(sp.sparse_coo_l.nnz)},
115 .order =
static_cast<typename SparseCOOl::Order
>(sp.sparse_coo_l.order),
116 .first_index = sp.sparse_coo_l.first_index,
119 using SparseCOOll = sparsity::SparseCOO<long long>;
121 .rows = sp.sparse_coo_ll.rows,
122 .cols = sp.sparse_coo_ll.cols,
123 .symmetry =
static_cast<Symmetry
>(sp.sparse_coo_ll.symmetry),
124 .row_indices = std::span{sp.sparse_coo_ll.row_indices,
static_cast<size_t>(sp.sparse_coo_ll.nnz)},
125 .col_indices = std::span{sp.sparse_coo_ll.col_indices,
static_cast<size_t>(sp.sparse_coo_ll.nnz)},
126 .order =
static_cast<typename SparseCOOll::Order
>(sp.sparse_coo_ll.order),
127 .first_index = sp.sparse_coo_ll.first_index,
129 default:
throw std::invalid_argument(
"Invalid sparsity kind");
137 const std::string &function_name,
139 DynamicLoadFlags dl_flags)
141 if (so_filename.empty())
142 throw std::invalid_argument(
"Invalid problem filename");
143 handle = guanaqo::load_lib(so_filename, dl_flags);
146 guanaqo::load_func(
handle.get(), function_name +
"_version"));
147 check_abi_version(version_func());
148 }
catch (
const dynamic_load_error &) {
149 std::cerr <<
"Warning: problem " << so_filename
150 <<
" does not provide a function to query the ABI version, "
151 "alpaqa_dl_abi_version_t "
152 << function_name <<
"_version(void)\n";
154 auto *register_func =
156 guanaqo::load_func(
handle.get(), function_name));
157 auto r = register_func(user_param);
159 std::unique_ptr<void, void (*)(
void *)> unique_inst{r.instance, r.cleanup};
160 std::unique_ptr<alpaqa_function_dict_t> unique_extra{r.extra_functions};
161 std::unique_ptr<alpaqa_exception_ptr_t> unique_exception{r.exception};
162 check_abi_version(r.abi_version);
164 if (unique_exception) {
174 std::rethrow_exception(unique_exception->exc);
177 throw std::logic_error(
"alpaqa::dl::DLProblem::DLProblem: plugin did "
178 "not return any functions");
180 instance = std::shared_ptr<void>{std::move(unique_inst)};
182 extra_funcs = std::shared_ptr<function_dict_t>{std::move(unique_extra)};
188 if (
functions->initialize_variable_bounds)
192 if (
functions->initialize_general_bounds)
207 const std::string &function_name, std::any &user_param,
208 DynamicLoadFlags dl_flags)
215 const std::string &function_name,
216 std::span<std::string_view> user_param,
217 DynamicLoadFlags dl_flags)
225 if (
functions->eval_projecting_difference_constraints)
226 return functions->eval_projecting_difference_constraints(
227 instance.get(), z.data(), e.data());
233 if (
functions->eval_projection_multipliers)
241 if (
functions->eval_proximal_gradient_step)
242 return functions->eval_proximal_gradient_step(
243 instance.get(), γ, x.data(), grad_ψ.data(), x̂.data(), p.data());
250 if (
functions->eval_inactive_indices_res_lna)
251 return functions->eval_inactive_indices_res_lna(
252 instance.get(), γ, x.data(), grad_ψ.data(), J.data());
260 return file.filename().string();
274auto DLProblem::eval_augmented_lagrangian_hessian_product(
crvec x,
crvec y,
crvec Σ,
real_t scale,
crvec v,
rvec Hv)
const ->
void {
return functions->eval_augmented_lagrangian_hessian_product(
instance.get(), x.data(), y.data(), Σ.data(), scale,
general_bounds.lower.data(),
general_bounds.upper.data(), v.data(), Hv.data()); }
275auto DLProblem::eval_augmented_lagrangian_hessian(
crvec x,
crvec y,
crvec Σ,
real_t scale,
rvec H_values)
const ->
void {
return functions->eval_augmented_lagrangian_hessian(
instance.get(), x.data(), y.data(), Σ.data(), scale,
general_bounds.lower.data(),
general_bounds.upper.data(), H_values.size() == 0 ?
nullptr : H_values.data()); }
282auto DLProblem::eval_augmented_lagrangian_gradient(
crvec x,
crvec y,
crvec Σ,
rvec grad_ψ,
rvec work_n,
rvec work_m)
const ->
void {
return functions->eval_augmented_lagrangian_gradient(
instance.get(), x.data(), y.data(), Σ.data(),
general_bounds.lower.data(),
general_bounds.upper.data(), grad_ψ.data(), work_n.data(), work_m.data()); }
283auto DLProblem::eval_augmented_lagrangian_and_gradient(
crvec x,
crvec y,
crvec Σ,
rvec grad_ψ,
rvec work_n,
rvec work_m)
const ->
real_t {
return functions->eval_augmented_lagrangian_and_gradient(
instance.get(), x.data(), y.data(), Σ.data(),
general_bounds.lower.data(),
general_bounds.upper.data(), grad_ψ.data(), work_n.data(), work_m.data()); }
313 const std::string &function_name,
315 DynamicLoadFlags dl_flags) {
316 if (so_filename.empty())
317 throw std::invalid_argument(
"Invalid problem filename");
318 handle = guanaqo::load_lib(so_filename, dl_flags);
321 guanaqo::load_func(
handle.get(), function_name +
"_version"));
322 check_abi_version(version_func());
323 }
catch (
const dynamic_load_error &) {
324 std::cerr <<
"Warning: problem " << so_filename
325 <<
" does not provide a function to query the ABI version, "
326 "alpaqa_dl_abi_version_t "
327 << function_name <<
"_version(void)\n";
329 auto *register_func =
331 guanaqo::load_func(
handle.get(), function_name));
332 auto r = register_func(user_param);
334 std::unique_ptr<void, void (*)(
void *)> unique_inst{r.instance, r.cleanup};
335 std::unique_ptr<alpaqa_function_dict_t> unique_extra{r.extra_functions};
336 std::unique_ptr<alpaqa_exception_ptr_t> unique_exception{r.exception};
337 check_abi_version(r.abi_version);
339 if (unique_exception) {
349 std::rethrow_exception(unique_exception->exc);
352 throw std::logic_error(
"alpaqa::dl::DLControlProblem::DLControlProblem:"
353 " plugin did not return any functions");
355 instance = std::shared_ptr<void>{std::move(unique_inst)};
357 extra_funcs = std::shared_ptr<function_dict_t>{std::move(unique_extra)};
376auto DLControlProblem::eval_add_R_masked(
index_t timestep,
crvec xu,
crvec h,
crindexvec mask,
rmat R,
rvec work)
const ->
void {
return functions->eval_add_R_masked(
instance.get(), timestep, xu.data(), h.data(), mask.data(), R.data(), work.data()); }
377auto DLControlProblem::eval_add_S_masked(
index_t timestep,
crvec xu,
crvec h,
crindexvec mask,
rmat S,
rvec work)
const ->
void {
return functions->eval_add_S_masked(
instance.get(), timestep, xu.data(), h.data(), mask.data(), S.data(), work.data()); }
378auto DLControlProblem::eval_add_R_prod_masked(
index_t timestep,
crvec xu,
crvec h,
crindexvec mask_J,
crindexvec mask_K,
crvec v,
rvec out,
rvec work)
const ->
void {
return functions->eval_add_R_prod_masked(
instance.get(), timestep, xu.data(), h.data(), mask_J.data(), mask_K.data(), v.data(), out.data(), work.data()); }
379auto DLControlProblem::eval_add_S_prod_masked(
index_t timestep,
crvec xu,
crvec h,
crindexvec mask_K,
crvec v,
rvec out,
rvec work)
const ->
void {
return functions->eval_add_S_prod_masked(
instance.get(), timestep, xu.data(), h.data(), mask_K.data(), v.data(), out.data(), work.data()); }
index_t eval_inactive_indices_res_lna(real_t γ, crvec x, crvec grad_ψ, rindexvec J) const
void eval_projection_multipliers(rvec y, real_t M) const
BoxConstrProblem(length_t num_variables, length_t num_constraints)
real_t eval_proximal_gradient_step(real_t γ, crvec x, crvec grad_ψ, rvec x̂, rvec p) const
alpaqa::Box< config_t > Box
void eval_projecting_difference_constraints(crvec z, rvec p) const
bool provides_get_variable_bounds() const
Only supported if the ℓ₁-regularization term is zero.
void eval_add_S_masked(index_t timestep, crvec xu, crvec h, crindexvec mask, rmat S, rvec work) const
bool provides_eval_grad_constr_prod() const
void eval_add_Q_N(crvec x, crvec h, rmat Q) const
bool provides_eval_add_gn_hess_constr() const
void eval_q_N(crvec x, crvec h, rvec q) const
void eval_add_gn_hess_constr(index_t timestep, crvec x, crvec M, rmat out) const
void eval_grad_constr_prod(index_t timestep, crvec x, crvec p, rvec grad_cx_p) const
void eval_add_R_prod_masked(index_t timestep, crvec xu, crvec h, crindexvec mask_J, crindexvec mask_K, crvec v, rvec out, rvec work) const
bool provides_eval_add_R_prod_masked() const
length_t get_S_work_size() const
void eval_constr_N(crvec x, rvec c) const
void get_D_N(Box &D) const
DLControlProblem(const std::filesystem::path &so_filename, const std::string &function_name="register_alpaqa_control_problem", alpaqa_register_arg_t user_param={}, DynamicLoadFlags dl_flags={})
Load a problem from a shared library.
bool provides_get_D() const
bool provides_get_S_work_size() const
void eval_grad_f_prod(index_t timestep, crvec x, crvec u, crvec p, rvec grad_fxu_p) const
bool provides_eval_add_Q_N() const
std::shared_ptr< void > instance
Problem instance created by the registration function, including the deleter to destroy it.
void eval_jac_f(index_t timestep, crvec x, crvec u, rmat J_fxu) const
real_t eval_l_N(crvec h) const
void eval_h_N(crvec x, rvec h) const
real_t eval_l(index_t timestep, crvec h) const
void eval_grad_constr_prod_N(crvec x, crvec p, rvec grad_cx_p) const
bool provides_eval_constr() const
control_problem_functions_t * functions
Pointer to the struct of function pointers for evaluating the objective, constraints,...
bool provides_get_D_N() const
void eval_add_gn_hess_constr_N(crvec x, crvec M, rmat out) const
void eval_f(index_t timestep, crvec x, crvec u, rvec fxu) const
bool provides_eval_grad_constr_prod_N() const
length_t get_R_work_size() const
void eval_add_S_prod_masked(index_t timestep, crvec xu, crvec h, crindexvec mask_K, crvec v, rvec out, rvec work) const
alpaqa::Box< config_t > Box
bool provides_eval_add_S_prod_masked() const
void get_x_init(rvec x_init) const
void eval_h(index_t timestep, crvec x, crvec u, rvec h) const
void eval_add_R_masked(index_t timestep, crvec xu, crvec h, crindexvec mask, rmat R, rvec work) const
std::shared_ptr< void > handle
Handle to the shared module defining the problem.
void eval_qr(index_t timestep, crvec xu, crvec h, rvec qr) const
ExtraFuncs extra_funcs
Dictionary of extra functions that were registered by the problem.
bool provides_eval_constr_N() const
void eval_add_Q(index_t timestep, crvec xu, crvec h, rmat Q) const
bool provides_get_R_work_size() const
bool provides_eval_add_gn_hess_constr_N() const
void eval_constr(index_t timestep, crvec x, rvec c) const
bool provides_eval_constraints_jacobian() const
bool provides_eval_objective() const
void eval_projection_multipliers(rvec y, real_t M) const
void eval_grad_gi(crvec x, index_t i, rvec grad_gi) const
Sparsity get_lagrangian_hessian_sparsity() const
void eval_objective_gradient(crvec x, rvec grad_fx) const
void eval_constraints(crvec x, rvec gx) const
void eval_constraints_gradient_product(crvec x, crvec y, rvec grad_gxy) const
real_t eval_augmented_lagrangian_and_gradient(crvec x, crvec y, crvec Σ, rvec grad_ψ, rvec work_n, rvec work_m) const
bool provides_eval_augmented_lagrangian() const
real_t eval_objective_and_gradient(crvec x, rvec grad_fx) const
bool provides_eval_constraints_gradient_product() const
bool provides_eval_objective_and_gradient() const
bool provides_eval_augmented_lagrangian_and_gradient() const
bool provides_eval_inactive_indices_res_lna() const
void eval_objective_gradient_and_constraints_gradient_product(crvec x, crvec y, rvec grad_f, rvec grad_gxy) const
std::shared_ptr< void > instance
Problem instance created by the registration function, including the deleter to destroy it.
bool provides_eval_objective_gradient_and_constraints_gradient_product() const
bool provides_eval_objective_and_constraints() const
real_t eval_objective(crvec x) const
DLProblem(const std::filesystem::path &so_filename, const std::string &function_name="register_alpaqa_problem", alpaqa_register_arg_t user_param={}, DynamicLoadFlags dl_flags={})
Load a problem from a shared library.
bool provides_get_lagrangian_hessian_sparsity() const
index_t eval_inactive_indices_res_lna(real_t γ, crvec x, crvec grad_ψ, rindexvec J) const
bool provides_eval_lagrangian_hessian_product() const
bool provides_get_constraints_jacobian_sparsity() const
void eval_augmented_lagrangian_hessian(crvec x, crvec y, crvec Σ, real_t scale, rvec H_values) const
void eval_augmented_lagrangian_gradient(crvec x, crvec y, crvec Σ, rvec grad_ψ, rvec work_n, rvec work_m) const
Sparsity get_constraints_jacobian_sparsity() const
bool provides_eval_constraints() const
bool provides_eval_augmented_lagrangian_hessian() const
void eval_lagrangian_gradient(crvec x, crvec y, rvec grad_L, rvec work_n) const
void eval_constraints_jacobian(crvec x, rvec J_values) const
real_t eval_objective_and_constraints(crvec x, rvec g) const
bool provides_eval_augmented_lagrangian_gradient() const
bool provides_get_variable_bounds() const
bool provides_eval_grad_gi() const
std::filesystem::path file
Path to the shared module file.
problem_functions_t * functions
Pointer to the struct of function pointers for evaluating the objective, constraints,...
bool provides_eval_augmented_lagrangian_hessian_product() const
bool provides_get_general_bounds() const
bool provides_eval_lagrangian_hessian() const
std::shared_ptr< void > handle
Handle to the shared module defining the problem.
void eval_lagrangian_hessian_product(crvec x, crvec y, real_t scale, crvec v, rvec Hv) const
ExtraFuncs extra_funcs
Dictionary of extra functions that were registered by the problem.
bool provides_get_augmented_lagrangian_hessian_sparsity() const
Sparsity get_augmented_lagrangian_hessian_sparsity() const
bool provides_eval_objective_gradient() const
real_t eval_augmented_lagrangian(crvec x, crvec y, crvec Σ, rvec ŷ) const
bool provides_eval_lagrangian_gradient() const
void eval_lagrangian_hessian(crvec x, crvec y, real_t scale, rvec H_values) const
void eval_projecting_difference_constraints(crvec z, rvec e) const
void eval_augmented_lagrangian_hessian_product(crvec x, crvec y, crvec Σ, real_t scale, crvec v, rvec Hv) const
std::string get_name() const
real_t eval_proximal_gradient_step(real_t γ, crvec x, crvec grad_ψ, rvec x̂, rvec p) const
#define USING_ALPAQA_CONFIG(Conf)
#define ALPAQA_DL_ABI_VERSION
@ alpaqa_register_arg_strings
The data pointer points to a dynamic C++ std::span of std::string_view.
@ alpaqa_register_arg_std_any
The data pointer points to a C++ std::any object.
uint64_t alpaqa_dl_abi_version_t
User-provided argument that is passed to the problem registration functions.
void check_abi_version(uint64_t abi_version)
std::string format_abi_version(uint64_t version)
std::list< std::shared_ptr< void > > leaked_modules
Sparsity convert_sparsity(alpaqa_sparsity_t sp)
void leak_lib(std::shared_ptr< void > handle)
std::mutex leaked_modules_mutex
alpaqa_problem_register_t problem_register_t
alpaqa_control_problem_register_t control_problem_register_t
typename Conf::real_t real_t
typename Conf::rindexvec rindexvec
typename Conf::index_t index_t
typename Conf::length_t length_t
typename Conf::crvec crvec
typename Conf::crindexvec crindexvec
enum alpaqa_sparsity_t::@134212053240032245237223311064313221324035054276 kind
@ alpaqa_sparsity_sparse_csc
@ alpaqa_sparsity_sparse_coo_l
@ alpaqa_sparsity_sparse_coo_ll
@ alpaqa_sparsity_sparse_csc_ll
@ alpaqa_sparsity_sparse_csc_l
@ alpaqa_sparsity_sparse_coo