3#include <alpaqa/casadi-loader-export.h>
11#if ALPAQA_WITH_EXTERNAL_CASADI
12#include <casadi/core/function.hpp>
13#include <casadi/mem.h>
23 using std::invalid_argument::invalid_argument;
28template <Config Conf,
size_t N_in,
size_t N_out>
32 static_assert(std::is_same_v<real_t, casadi_real>);
38#if ALPAQA_WITH_EXTERNAL_CASADI
39 :
fun(std::move(f)), iwork(
fun.sz_iw()), dwork(
fun.sz_w()),
40 arg_work(
fun.sz_arg()), res_work(
fun.sz_res())
50 const std::array<casadi_dim, N_in> &dim_in,
51 const std::array<casadi_dim, N_out> &dim_out)
58 using namespace std::literals::string_literals;
59 if (N_in !=
fun.n_in())
61 "Invalid number of input arguments: got "s +
62 std::to_string(
fun.n_in()) +
", should be " +
63 std::to_string(N_in) +
".");
64 if (N_out !=
fun.n_out())
66 "Invalid number of output arguments: got "s +
67 std::to_string(
fun.n_out()) +
", should be " +
68 std::to_string(N_out) +
".");
74 const std::array<casadi_dim, N_in> &dim_in = {},
75 const std::array<casadi_dim, N_out> &dim_out = {}) {
76 using namespace std::literals::string_literals;
77 static constexpr std::array count{
"first",
"second",
"third",
78 "fourth",
"fifth",
"sixth",
80 static_assert(N_in <= count.size());
81 static_assert(N_out <= count.size());
83 return "(" + std::to_string(d.first) +
", " +
84 std::to_string(d.second) +
")";
86 for (
size_t n = 0; n < N_in; ++n) {
88 if (dim_in[n].first != 0 && dim_in[n] !=
fun.size_in(cs_n))
89 throw invalid_argument_dimensions(
90 "Invalid dimension of "s + count[n] +
91 " input argument: got " + to_string(
fun.size_in(cs_n)) +
92 ", should be " + to_string(dim_in[n]) +
".");
94 for (
size_t n = 0; n < N_out; ++n) {
96 if (dim_out[n].first != 0 && dim_out[n] !=
fun.size_out(cs_n))
97 throw invalid_argument_dimensions(
98 "Invalid dimension of "s + count[n] +
99 " output argument: got " + to_string(
fun.size_out(cs_n)) +
100 ", should be " + to_string(dim_out[n]) +
".");
107 const std::array<casadi_dim, N_out> &dim_out = {}) {
111#if ALPAQA_WITH_EXTERNAL_CASADI
113 void operator()(
const double *
const *in,
double *
const *out)
const {
114 std::copy_n(in, N_in, arg_work.begin());
115 std::copy_n(out, N_out, res_work.begin());
116 fun(arg_work.data(), res_work.data(), iwork.data(), dwork.data(), 0);
120 void operator()(
const double *
const (&in)[N_in],
121 double *
const (&out)[N_out])
const {
127 double *
const (&out)[N_out]) {
128 fun(std::span{in}, std::span{out});
135#if ALPAQA_WITH_EXTERNAL_CASADI
137 mutable std::vector<casadi_int> iwork;
138 mutable std::vector<double> dwork;
139 mutable std::vector<const double *> arg_work;
140 mutable std::vector<double *> res_work;
#define BEGIN_ALPAQA_CASADI_LOADER_NAMESPACE
#define END_ALPAQA_CASADI_LOADER_NAMESPACE
Class that loads and calls pre-compiled CasADi functions in a DLL/SO file.
CasADiFunctionEvaluator(casadi::Function &&f, const std::array< casadi_dim, N_in > &dim_in, const std::array< casadi_dim, N_out > &dim_out)
static void validate_num_args(const casadi::Function &fun)
void operator()(const double *const (&in)[N_in], double *const (&out)[N_out])
CasADiFunctionEvaluator(casadi::Function &&f)
void validate_dimensions(const std::array< casadi_dim, N_in > &dim_in={}, const std::array< casadi_dim, N_out > &dim_out={})
static void validate_dimensions(const casadi::Function &fun, const std::array< casadi_dim, N_in > &dim_in={}, const std::array< casadi_dim, N_out > &dim_out={})
std::pair< casadi_int, casadi_int > casadi_dim
#define USING_ALPAQA_CONFIG(Conf)