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