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