alpaqa no-casadi-dep
Nonconvex constrained optimization
Loading...
Searching...
No Matches
casadi-external-function.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <alpaqa/casadi-loader-export.h>
6
7#include <cassert>
8#include <memory>
9#include <optional>
10#include <span>
11#include <stdexcept>
12#include <utility>
13#include <vector>
14
16
17/// Class that loads and calls pre-compiled CasADi functions in a DLL/SO file.
18/// Designed to match (part of) the `casadi::Function` API.
20 public:
21 Function(std::shared_ptr<void> so_handle, const std::string &func_name);
22 Function(const Function &);
23 Function(Function &&) noexcept;
24 ~Function();
25
26 public:
27 class CASADI_LOADER_EXPORT Sparsity {
28 public:
29 [[nodiscard]] std::pair<casadi_int, casadi_int> size() const;
30 [[nodiscard]] casadi_int size1() const;
31 [[nodiscard]] casadi_int size2() const;
32 [[nodiscard]] casadi_int nnz() const;
33 [[nodiscard]] bool is_dense() const;
34 [[nodiscard]] const casadi_int *row() const;
35 [[nodiscard]] const casadi_int *colind() const;
36
37 private:
38 friend class Function;
39 explicit Sparsity(const casadi_int *data) : data{data} {}
41 };
42 [[nodiscard]] casadi_int n_in() const;
43 [[nodiscard]] casadi_int n_out() const;
44 [[nodiscard]] std::pair<casadi_int, casadi_int> size_in(casadi_int) const;
45 [[nodiscard]] std::pair<casadi_int, casadi_int> size_out(casadi_int) const;
46 [[nodiscard]] casadi_int size1_in(casadi_int) const;
47 [[nodiscard]] casadi_int size1_out(casadi_int) const;
48 [[nodiscard]] casadi_int size2_in(casadi_int) const;
49 [[nodiscard]] casadi_int size2_out(casadi_int) const;
50 [[nodiscard]] Sparsity sparsity_in(casadi_int) const;
51 [[nodiscard]] Sparsity sparsity_out(casadi_int) const;
52
53 public:
54 void operator()(std::span<const double *const> arg,
55 std::span<double *const> res) {
56 if (arg.size() != static_cast<size_t>(n_in()))
57 throw std::invalid_argument("Wrong number of arguments to CasADi "
58 "function");
59 if (res.size() != static_cast<size_t>(n_out()))
60 throw std::invalid_argument("Wrong number of outputs to CasADi "
61 "function");
62 init_work();
63 assert(work);
64 std::ranges::copy(arg, work->arg.begin());
65 std::ranges::copy(res, work->res.begin());
66 functions.call(work->arg.data(), work->res.data(), work->iw.data(),
67 work->w.data(), mem);
68 // TODO: what to do upon failure?
69 }
70
71 private:
72 void load(void *so_handle, const std::string &func_name);
73 void init_work();
74
75 private:
76 std::shared_ptr<void> so_handle;
77 struct Functions {
78 fname_incref::signature_t *incref = nullptr;
79 fname_decref::signature_t *decref = nullptr;
80 fname_n_in::signature_t *n_in = nullptr;
81 fname_n_out::signature_t *n_out = nullptr;
82 fname_name_in::signature_t *name_in = nullptr;
83 fname_name_out::signature_t *name_out = nullptr;
84 fname_sparsity_in::signature_t *sparsity_in = nullptr;
85 fname_sparsity_out::signature_t *sparsity_out = nullptr;
86 fname_alloc_mem::signature_t *alloc_mem = nullptr;
87 fname_init_mem::signature_t *init_mem = nullptr;
88 fname_free_mem::signature_t *free_mem = nullptr;
89 fname_work::signature_t *work = nullptr;
90 fname::signature_t *call = nullptr;
91 } functions;
92 struct Work {
93 std::vector<const casadi_real *> arg;
94 std::vector<casadi_real *> res;
95 std::vector<casadi_int> iw;
96 std::vector<casadi_real> w;
97 };
98 std::optional<Work> work;
99 void *mem = nullptr;
100};
101
102inline std::pair<casadi_int, casadi_int> Function::Sparsity::size() const {
103 return {size1(), size2()};
104}
105inline casadi_int Function::Sparsity::size1() const { return data[0]; }
106inline casadi_int Function::Sparsity::size2() const { return data[1]; }
107inline casadi_int Function::Sparsity::nnz() const { return colind()[size2()]; }
108inline bool Function::Sparsity::is_dense() const { return data[2] != 0; }
109inline const casadi_int *Function::Sparsity::row() const {
110 return &colind()[size2() + 1];
111}
112inline const casadi_int *Function::Sparsity::colind() const {
113 assert(!is_dense());
114 return &data[2];
115}
116
117/// Load the given CasADi function from the given DLL/SO file.
118CASADI_LOADER_EXPORT Function external(const std::string &name,
119 const std::string &bin_name);
120
121} // namespace alpaqa::inline ALPAQA_CASADI_LOADER_NAMESPACE::casadi
#define ALPAQA_CASADI_LOADER_NAMESPACE
Class that loads and calls pre-compiled CasADi functions in a DLL/SO file.
std::vector< const casadi_real * > arg
std::vector< casadi_real * > res
std::vector< casadi_int > iw
std::vector< casadi_real > w
std::shared_ptr< void > so_handle
std::optional< Work > work
void operator()(std::span< const double *const > arg, std::span< double *const > res)
constexpr const auto inf
Definition config.hpp:112
Function external(const std::string &name, const std::string &bin_name)
Load the given CasADi function from the given DLL/SO file.
long long int casadi_int