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#include <guanaqo/dl-flags.hpp>
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 {
17
18using guanaqo::DynamicLoadFlags;
19
21namespace casadi {
22
23/// Class that loads and calls pre-compiled CasADi functions in a DLL/SO file.
24/// Designed to match (part of) the `casadi::Function` API.
25class CASADI_LOADER_EXPORT Function {
26 public:
42
43 public:
45 Function(std::shared_ptr<void> so_handle, const std::string &func_name);
47 Function(const Function &);
48 Function(Function &&) noexcept;
49 ~Function();
50
51 public:
52 class CASADI_LOADER_EXPORT Sparsity {
53 public:
54 [[nodiscard]] std::pair<casadi_int, casadi_int> size() const;
55 [[nodiscard]] casadi_int size1() const;
56 [[nodiscard]] casadi_int size2() const;
57 [[nodiscard]] casadi_int nnz() const;
58 [[nodiscard]] bool is_dense() const;
59 [[nodiscard]] const casadi_int *row() const;
60 [[nodiscard]] const casadi_int *colind() const;
61
62 private:
63 friend class Function;
64 explicit Sparsity(const casadi_int *data) : data{data} {}
66 };
67 [[nodiscard]] casadi_int n_in() const;
68 [[nodiscard]] casadi_int n_out() const;
69 [[nodiscard]] std::pair<casadi_int, casadi_int> size_in(casadi_int) const;
70 [[nodiscard]] std::pair<casadi_int, casadi_int> size_out(casadi_int) const;
71 [[nodiscard]] casadi_int size1_in(casadi_int) const;
72 [[nodiscard]] casadi_int size1_out(casadi_int) const;
73 [[nodiscard]] casadi_int size2_in(casadi_int) const;
74 [[nodiscard]] casadi_int size2_out(casadi_int) const;
75 [[nodiscard]] Sparsity sparsity_in(casadi_int) const;
76 [[nodiscard]] Sparsity sparsity_out(casadi_int) const;
77
78 public:
79 void operator()(std::span<const double *const> arg,
80 std::span<double *const> res) {
81 if (arg.size() != static_cast<size_t>(n_in()))
82 throw std::invalid_argument("Wrong number of arguments to CasADi "
83 "function");
84 if (res.size() != static_cast<size_t>(n_out()))
85 throw std::invalid_argument("Wrong number of outputs to CasADi "
86 "function");
87 init_work();
88 assert(work);
89 std::ranges::copy(arg, work->arg.begin());
90 std::ranges::copy(res, work->res.begin());
91 functions.call(work->arg.data(), work->res.data(), work->iw.data(),
92 work->w.data(), mem);
93 // TODO: what to do upon failure?
94 }
95
96 private:
97 void load(void *so_handle, const std::string &func_name);
98 void init_work();
99
100 private:
101 std::shared_ptr<void> so_handle;
103 struct Work {
104 std::vector<const casadi_real *> arg;
105 std::vector<casadi_real *> res;
106 std::vector<casadi_int> iw;
107 std::vector<casadi_real> w;
108 };
109 std::optional<Work> work;
110 int mem = 0;
111};
112
113inline std::pair<casadi_int, casadi_int> Function::Sparsity::size() const {
114 return {size1(), size2()};
115}
116inline casadi_int Function::Sparsity::size1() const { return data[0]; }
117inline casadi_int Function::Sparsity::size2() const { return data[1]; }
118inline casadi_int Function::Sparsity::nnz() const { return colind()[size2()]; }
119inline bool Function::Sparsity::is_dense() const { return data[2] != 0; }
120inline const casadi_int *Function::Sparsity::row() const {
121 return &colind()[size2() + 1];
122}
124 assert(!is_dense());
125 return &data[2];
126}
127
128/// Load the given CasADi function from the given DLL/SO file.
129CASADI_LOADER_EXPORT Function external(const std::string &name,
130 const std::string &bin_name,
131 DynamicLoadFlags dl_flags);
132
133} // namespace casadi
135} // namespace alpaqa
#define BEGIN_ALPAQA_CASADI_LOADER_NAMESPACE
#define END_ALPAQA_CASADI_LOADER_NAMESPACE
std::pair< casadi_int, casadi_int > size() const
std::vector< const casadi_real * > arg
casadi_int size1_out(casadi_int) const
std::pair< casadi_int, casadi_int > size_in(casadi_int) const
fname_sparsity_in::signature_t * sparsity_in
std::pair< casadi_int, casadi_int > size_out(casadi_int) const
fname_sparsity_out::signature_t * sparsity_out
Sparsity sparsity_in(casadi_int) const
casadi_int size2_out(casadi_int) const
Sparsity sparsity_out(casadi_int) const
casadi_int size1_in(casadi_int) const
void operator()(std::span< const double *const > arg, std::span< double *const > res)
casadi_int size2_in(casadi_int) const
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.
long long int casadi_int