uno_interface.cpp
1 /*
2  * This file is part of CasADi.
3  *
4  * CasADi -- A symbolic framework for dynamic optimization.
5  * Copyright (C) 2010-2023 Joel Andersson, Joris Gillis, Moritz Diehl,
6  * KU Leuven. All rights reserved.
7  * Copyright (C) 2011-2014 Greg Horn
8  *
9  * CasADi is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 3 of the License, or (at your option) any later version.
13  *
14  * CasADi is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with CasADi; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22  *
23  */
24 
25 #include "uno_interface.hpp"
26 #include "casadi/core/casadi_misc.hpp"
27 #include "casadi/core/casadi_interrupt.hpp"
28 #include "casadi/core/code_generator.hpp"
29 
30 #include <uno_runtime_str.h>
31 
32 #include <cstdlib>
33 #include <limits>
34 
35 namespace casadi {
36 
37  extern "C"
38  int CASADI_NLPSOL_UNO_EXPORT
39  casadi_register_nlpsol_uno(Nlpsol::Plugin* plugin) {
40  plugin->creator = UnoInterface::creator;
41  plugin->name = "uno";
42  plugin->doc = UnoInterface::meta_doc.c_str();
43  plugin->version = CASADI_VERSION;
44  plugin->options = &UnoInterface::options_;
45  plugin->deserialize = &UnoInterface::deserialize;
46  return 0;
47  }
48 
49  extern "C"
50  void CASADI_NLPSOL_UNO_EXPORT casadi_load_nlpsol_uno() {
52  }
53 
54  UnoInterface::UnoInterface(const std::string& name, const Function& nlp)
55  : Nlpsol(name, nlp) {}
56 
58  clear_mem();
59  }
60 
62  = {{&Nlpsol::options_},
63  {{"uno",
64  {OT_DICT,
65  "Options to be passed to UNO"}}
66  }
67  };
68 
69  UnoMemory::UnoMemory(const UnoInterface& uno_interface)
70  : self(uno_interface), NlpsolMemory() {
71  return_status = "Unset";
72  d_uno.solver = nullptr;
73  d_uno.model = nullptr;
74  }
75 
77  casadi_uno_free_mem<double>(&d_uno);
78  }
79 
80  void UnoInterface::free_mem(void* mem) const {
81  delete static_cast<UnoMemory*>(mem);
82  }
83 
84  void UnoInterface::init(const Dict& opts) {
85  Nlpsol::init(opts);
86 
87  calc_f_ = true;
88  calc_g_ = true;
89 
90  for (auto&& op : opts) {
91  if (op.first == "uno") opts_ = op.second;
92  }
93 
94  create_function("nlp_f", {"x", "p"}, {"f"});
95  create_function("nlp_g", {"x", "p"}, {"g"});
96  if (!has_function("nlp_grad_f")) {
97  create_function("nlp_grad_f", {"x", "p"}, {"grad:f:x"});
98  }
99  Function gf_jg_fcn = create_function("nlp_jac_g", {"x", "p"}, {"jac:g:x"});
100  jacg_sp_ = gf_jg_fcn.sparsity_out(0);
101 
102  Function hess_l_fcn = create_function("nlp_hess_l", {"x", "p", "lam:f", "lam:g"},
103  {"triu:hess:gamma:x:x"},
104  {{"gamma", {"f", "g"}}});
105  hesslag_sp_ = hess_l_fcn.sparsity_out(0);
106  casadi_assert(hesslag_sp_.is_triu(), "Hessian must be upper triangular");
107 
108  // Hessian-vector product (matrix-free, used by e.g. the LBFGS preset):
109  // the forward derivative of grad(gamma) wrt x, seeded along fwd:x.
110  Dict final_options;
111  final_options["is_diff_in"] = std::vector<bool>{true, false, false, false};
112  final_options["is_diff_out"] = std::vector<bool>{true};
113  Dict func_opts;
114  func_opts["final_options"] = final_options;
115  create_function("nlp_grad_l", {"x", "p", "lam:f", "lam:g"},
116  {"grad:gamma:x"}, {{"gamma", {"f", "g"}}}, func_opts);
117  create_forward("nlp_grad_l", 1); // registers "fwd1_nlp_grad_l"
118 
119  {
120  auto jr = jacg_sp_.get_row(), jc = jacg_sp_.get_col();
121  auto hr = hesslag_sp_.get_row(), hc = hesslag_sp_.get_col();
122  jacobian_row_indices_.assign(jr.begin(), jr.end());
123  jacobian_column_indices_.assign(jc.begin(), jc.end());
124  hessian_row_indices_.assign(hr.begin(), hr.end());
125  hessian_column_indices_.assign(hc.begin(), hc.end());
126  }
127 
128  placeholder_lb_g_.assign(ng_, -std::numeric_limits<double>::infinity());
129  placeholder_ub_g_.assign(ng_, std::numeric_limits<double>::infinity());
130 
131  set_uno_prob();
132  }
133 
134  void UnoInterface::set_uno_prob() {
135  p_uno_.nlp = p_nlp_;
136  p_uno_.sp_a = jacg_sp_;
137  p_uno_.sp_h = hesslag_sp_;
138  p_uno_.jac_row = jacobian_row_indices_.data();
139  p_uno_.jac_col = jacobian_column_indices_.data();
140  p_uno_.n_jac = static_cast<uno_int>(jacobian_row_indices_.size());
141  p_uno_.hess_row = hessian_row_indices_.data();
142  p_uno_.hess_col = hessian_column_indices_.data();
143  p_uno_.n_hess = static_cast<uno_int>(hessian_row_indices_.size());
144  p_uno_.obj_cb = &casadi_uno_obj_wrapper<double>;
145  p_uno_.obj_grad_cb = &casadi_uno_obj_grad_wrapper<double>;
146  p_uno_.constr_cb = &casadi_uno_constr_wrapper<double>;
147  p_uno_.jac_cb = &casadi_uno_jac_wrapper<double>;
148  p_uno_.hess_cb = &casadi_uno_hess_wrapper<double>;
149  p_uno_.hess_prod_cb = &casadi_uno_hess_prod_wrapper<double>;
150  p_uno_.nlp_f = OracleCallback("nlp_f", this);
151  p_uno_.nlp_g = OracleCallback("nlp_g", this);
152  p_uno_.nlp_grad_f = OracleCallback("nlp_grad_f", this);
153  p_uno_.nlp_jac_g = OracleCallback("nlp_jac_g", this);
154  p_uno_.nlp_hess_l = OracleCallback("nlp_hess_l", this);
155  p_uno_.fwd1_nlp_grad_l = OracleCallback("fwd1_nlp_grad_l", this);
156  }
157 
158  static void set_uno_option(void* solver, const std::string& name, const GenericType& value) {
159  if (value.is_bool()) {
160  uno_set_solver_bool_option(solver, name.c_str(), value.to_bool());
161  } else if (value.is_int()) {
162  uno_set_solver_integer_option(solver, name.c_str(), static_cast<uno_int>(value.to_int()));
163  } else if (value.is_double()) {
164  uno_set_solver_double_option(solver, name.c_str(), value.to_double());
165  } else if (value.is_string()) {
166  uno_set_solver_string_option(solver, name.c_str(), value.to_string().c_str());
167  } else {
168  casadi_assert(false, "Unsupported UNO option type for " + name);
169  }
170  }
171 
172  static void insert_casadi_options(void* solver, Dict opts) {
173  Dict casadi_options = Options::sanitize(opts);
174  // Apply the preset first: it overwrites some options (e.g. it would reset
175  // the Hessian model to exact, clobbering an explicit hessian_model=LBFGS).
176  for (auto&& op : casadi_options) {
177  if (op.first == "preset") {
178  uno_set_solver_preset(solver, op.second.to_string().c_str());
179  break;
180  }
181  }
182  for (auto&& op : casadi_options) {
183  if (op.first != "preset") set_uno_option(solver, op.first, op.second);
184  }
185  }
186 
187  static uno_int casadi_uno_term_cb_cpp(uno_int, uno_int, const double* primals,
188  const double* lower_mult, const double* upper_mult, const double* constraint_mult,
189  double, double, double, double, void* user_data) {
190  constexpr uno_int CONTINUE = 1;
191  constexpr uno_int TERMINATE = 0;
192  auto* m = static_cast<UnoMemory*>(user_data); // wired in init_mem
193  const UnoInterface& self = m->self;
194  if (self.fcallback_.is_null()) return CONTINUE;
195 
196  auto* d_nlp = &m->d_nlp;
197  casadi_copy(primals, self.nx_, d_nlp->z);
198  for (casadi_int i = 0; i < self.nx_; ++i) {
199  // Negative sign convention: bound multipliers are added (cf casadi_uno_solve).
200  d_nlp->lam[i] = lower_mult[i] + upper_mult[i];
201  }
202  if (self.ng_ > 0) {
203  casadi_copy(constraint_mult, self.ng_, d_nlp->lam + self.nx_);
204  }
205  std::fill_n(m->arg, self.fcallback_.n_in(), nullptr);
206  m->arg[NLPSOL_X] = d_nlp->z;
207  m->arg[NLPSOL_LAM_X] = d_nlp->lam;
208  m->arg[NLPSOL_LAM_G] = d_nlp->lam + self.nx_;
209  std::fill_n(m->res, self.fcallback_.n_out(), nullptr);
210  double ret_double = 0;
211  m->res[0] = &ret_double;
212  try {
213  self.fcallback_(m->arg, m->res, m->iw, m->w, 0);
214  } catch (KeyboardInterruptException&) {
215  return TERMINATE;
216  } catch (std::exception& ex) {
217  casadi_warning(std::string("intermediate_callback: ") + ex.what());
218  return self.iteration_callback_ignore_errors_ ? CONTINUE : TERMINATE;
219  }
220  return static_cast<casadi_int>(ret_double) ? TERMINATE : CONTINUE;
221  }
222 
223  int UnoInterface::init_mem(void* mem) const {
224  if (Nlpsol::init_mem(mem)) return 1;
225  auto m = static_cast<UnoMemory*>(mem);
226 
227  if (verbose_) {
228  uno_int uno_major, uno_minor, uno_patch;
229  uno_get_version(&uno_major, &uno_minor, &uno_patch);
230  casadi_message("Using Uno v" + str(uno_major) + "." + str(uno_minor) + "." + str(uno_patch));
231  }
232 
233  m->d_uno.prob = &p_uno_;
234  casadi_uno_init_mem<double>(&m->d_uno);
235  casadi_uno_init_model<double>(&m->d_uno,
236  placeholder_lb_g_.data(), placeholder_ub_g_.data());
237  // Override the runtime's no-op termination cb with one that fires
238  // Nlpsol::fcallback_ each iteration (opti.callback support). Pass UnoMemory*
239  // (not casadi_uno_data*) so the cb can reach m->self.fcallback_ etc.
240  uno_set_solver_callbacks(m->d_uno.solver, nullptr, &casadi_uno_term_cb_cpp, m);
241  insert_casadi_options(m->d_uno.solver, opts_);
242  return 0;
243  }
244 
245  void UnoInterface::set_work(void* mem, const double**& arg, double**& res,
246  casadi_int*& iw, double*& w) const {
247  Nlpsol::set_work(mem, arg, res, iw, w);
248  auto m = static_cast<UnoMemory*>(mem);
249  // Mirror NlpsolMemory's d_nlp into the by-value field on casadi_uno_data
250  // (the runtime helpers and codegen path both read d->nlp.* there). Then
251  // retarget the prob pointer at our own p_uno_.nlp -- the canonical
252  // copy that the codegen path also references.
253  m->d_uno.nlp = m->d_nlp;
254  m->d_uno.nlp.prob = &p_uno_.nlp;
255  // Wiring trap (cf casadi_nlpsol_plugin skill): the OracleCallback path
256  // dispatches via cb->oracle_->calc_function(d->m, ...). Without this set,
257  // d->m is NULL on the first eval and the plugin segfaults.
258  m->d_nlp.oracle->m = static_cast<void*>(m);
259  m->d_uno.nlp.oracle = m->d_nlp.oracle;
260  }
261 
262  inline const char* return_status_string(int sol) {
263  switch (sol) {
264  case UNO_FEASIBLE_KKT_POINT: return "Converged with feasible KKT point";
265  case UNO_FEASIBLE_FJ_POINT: return "Converged with feasible FJ point";
266  case UNO_INFEASIBLE_STATIONARY_POINT: return "Converged with infeasible stationary point";
267  case UNO_FEASIBLE_SMALL_STEP: return "Terminated with feasible small step";
268  case UNO_INFEASIBLE_SMALL_STEP: return "Terminated with infeasible small step";
269  case UNO_UNBOUNDED: return "Terminated with unbounded problem";
270  case UNO_NOT_OPTIMAL: return "Terminated with not optimal point";
271  default: return "Terminated with an unknown status";
272  }
273  }
274 
275  int UnoInterface::solve(void* mem) const {
276  auto m = static_cast<UnoMemory*>(mem);
277 
278  casadi_uno_solve<double>(&m->d_uno);
279 
280  m->success = m->d_uno.success;
281  m->unified_return_status = static_cast<UnifiedReturnStatus>(m->d_uno.unified_return_status);
282  m->return_status = return_status_string(uno_get_solution_status(m->d_uno.solver));
283  return 0;
284  }
285 
286  Dict UnoInterface::get_stats(void* mem) const {
287  Dict stats = Nlpsol::get_stats(mem);
288  auto m = static_cast<UnoMemory*>(mem);
289  stats["return_status"] = m->return_status;
290  stats["iter_count"] = static_cast<casadi_int>(m->d_uno.iter_count);
291  stats["primal_infeasbility"] = m->d_uno.primal_infeasibility;
292  stats["stationarity"] = m->d_uno.stationarity;
293  stats["complementarity"] = m->d_uno.complementarity;
294  return stats;
295  }
296 
299  s.version("UnoInterface", 1);
300  s.pack("UnoInterface::jacg_sp", jacg_sp_);
301  s.pack("UnoInterface::hesslag_sp", hesslag_sp_);
302  s.pack("UnoInterface::opts", opts_);
303  }
304 
306  s.version("UnoInterface", 1);
307  s.unpack("UnoInterface::jacg_sp", jacg_sp_);
308  s.unpack("UnoInterface::hesslag_sp", hesslag_sp_);
309  s.unpack("UnoInterface::opts", opts_);
310  auto jr = jacg_sp_.get_row(), jc = jacg_sp_.get_col();
311  auto hr = hesslag_sp_.get_row(), hc = hesslag_sp_.get_col();
312  jacobian_row_indices_.assign(jr.begin(), jr.end());
313  jacobian_column_indices_.assign(jc.begin(), jc.end());
314  hessian_row_indices_.assign(hr.begin(), hr.end());
315  hessian_column_indices_.assign(hc.begin(), hc.end());
316  placeholder_lb_g_.assign(ng_, -std::numeric_limits<double>::infinity());
317  placeholder_ub_g_.assign(ng_, std::numeric_limits<double>::infinity());
318  set_uno_prob();
319  }
320 
321  // ----- Codegen --------------------------------------------------------------
322 
324  g.local("d", "struct casadi_uno_data*");
325  g.init_local("d", "&" + codegen_mem(g));
326  // Static prob: nx/ng + sparsity + callbacks are problem-invariant, so
327  // the prob struct lives forever (one per generated function). Storing
328  // it function-scope-static lets us call uno_create_model from init_mem,
329  // matching the C++ vm path's "build everything at allocation time".
330  g.local("p", "static struct casadi_uno_prob");
331  set_uno_prob(g);
332  g << "d->prob = &p;\n";
333  // Wire d->nlp at the persistent NLP scratch on this memory block.
334  // (Casadi convention has d_nlp/p_nlp/d_oracle as per-call function-scope
335  // locals via Nlpsol::codegen_body_enter; uno opts out of that and uses
336  // the by-value fields on casadi_uno_data instead.)
337  g << "\n";
338  Nlpsol::codegen_setup_constants(g, "d->nlp", "p.nlp", "d->d_oracle");
339  g << "casadi_uno_init_mem(d);\n";
340  g << "casadi_uno_init_model(d, "
341  << g.constant(placeholder_lb_g_) << ", "
342  << g.constant(placeholder_ub_g_) << ");\n";
343  // Apply user options (statically known at codegen time). The preset must go
344  // first: it overwrites some options (e.g. it would reset the Hessian model,
345  // clobbering an explicit hessian_model=LBFGS). Mirrors insert_casadi_options.
346  for (auto&& kv : opts_) {
347  if (kv.first == "preset") {
348  g << "uno_set_solver_preset(d->solver, \"" << kv.second.to_string() << "\");\n";
349  }
350  }
351  for (auto&& kv : opts_) {
352  const std::string& key = kv.first;
353  if (key == "preset") {
354  continue;
355  } else if (kv.second.is_bool()) {
356  g << "uno_set_solver_bool_option(d->solver, \"" << key << "\", "
357  << (kv.second.to_bool() ? "1" : "0") << ");\n";
358  } else if (kv.second.is_int()) {
359  g << "uno_set_solver_integer_option(d->solver, \"" << key << "\", "
360  << kv.second.to_int() << ");\n";
361  } else if (kv.second.is_double()) {
362  g << "uno_set_solver_double_option(d->solver, \"" << key << "\", "
363  << g.constant(kv.second.to_double()) << ");\n";
364  } else if (kv.second.is_string()) {
365  g << "uno_set_solver_string_option(d->solver, \"" << key << "\", \""
366  << kv.second.to_string() << "\");\n";
367  } else {
368  casadi_error("Unsupported uno option type for '" + key + "'");
369  }
370  }
371  g << "return 0;\n";
372  }
373 
375  g << "casadi_uno_free_mem(&" + codegen_mem(g) + ");\n";
376  }
377 
383  g.add_dependency(get_function("nlp_f"));
384  g.add_dependency(get_function("nlp_g"));
385  g.add_dependency(get_function("nlp_grad_f"));
386  g.add_dependency(get_function("nlp_jac_g"));
387  g.add_dependency(get_function("nlp_hess_l"));
388  g.add_dependency(get_function("fwd1_nlp_grad_l"));
389  g.add_include("Uno_C_API.h");
390  g.auxiliaries << g.sanitize_source(uno_runtime_str, {"casadi_real"});
391  }
392 
393  // Point a prob field at a uno_int (32-bit) index array. g.constant only emits
394  // casadi_int (64-bit when WITH_LONGLONG_CORE), so emit a typed array via
395  // array()+initializer(). It must be "static const": p is a static prob that
396  // outlives init_mem, so a plain local array would dangle once init_mem
397  // returns. The empty case sets the pointer to 0.
398  static void codegen_int_array(CodeGenerator& g, const std::string& name,
399  const std::vector<uno_int>& v) {
400  if (v.empty()) {
401  g << "p." << name << " = 0;\n";
402  return;
403  }
404  g << g.array("static const int", "p_" + name, v.size(),
405  g.initializer(vector_static_cast<casadi_int>(v)));
406  g << "p." << name << " = p_" << name << ";\n";
407  }
408 
409  void UnoInterface::set_uno_prob(CodeGenerator& g) const {
410  g << "p.sp_a = " << g.sparsity(jacg_sp_) << ";\n";
411  g << "p.sp_h = " << g.sparsity(hesslag_sp_) << ";\n";
412  codegen_int_array(g, "jac_row", jacobian_row_indices_);
413  codegen_int_array(g, "jac_col", jacobian_column_indices_);
414  g << "p.n_jac = " << jacobian_row_indices_.size() << ";\n";
415  codegen_int_array(g, "hess_row", hessian_row_indices_);
416  codegen_int_array(g, "hess_col", hessian_column_indices_);
417  g << "p.n_hess = " << hessian_row_indices_.size() << ";\n";
418  g.setup_callback("p.nlp_f", get_function("nlp_f"));
419  g.setup_callback("p.nlp_g", get_function("nlp_g"));
420  g.setup_callback("p.nlp_grad_f", get_function("nlp_grad_f"));
421  g.setup_callback("p.nlp_jac_g", get_function("nlp_jac_g"));
422  g.setup_callback("p.nlp_hess_l", get_function("nlp_hess_l"));
423  g.setup_callback("p.fwd1_nlp_grad_l", get_function("fwd1_nlp_grad_l"));
424  g << "p.obj_cb = &casadi_uno_obj_wrapper;\n";
425  g << "p.obj_grad_cb = &casadi_uno_obj_grad_wrapper;\n";
426  g << "p.constr_cb = &casadi_uno_constr_wrapper;\n";
427  g << "p.jac_cb = &casadi_uno_jac_wrapper;\n";
428  g << "p.hess_cb = &casadi_uno_hess_wrapper;\n";
429  g << "p.hess_prod_cb = &casadi_uno_hess_prod_wrapper;\n";
430  }
431 
433  // No codegen_body_enter / codegen_body_exit: d_nlp / p_nlp / d_oracle
434  // live on casadi_uno_data, populated from codegen_init_mem (constants)
435  // and the codegen_setup_per_call call below (per-call wiring).
436  g.local("d", "struct casadi_uno_data*");
437  g.init_local("d", "&" + codegen_mem(g));
438  Nlpsol::codegen_setup_per_call(g, "d->nlp");
439  g << "casadi_uno_set_work(d, &arg, &res, &iw, &w);\n";
440  g << "casadi_oracle_set_work(&d->d_oracle, &arg, &res, &iw, &w);\n";
441  g << "casadi_uno_solve(d);\n";
442  Nlpsol::codegen_post_solve(g, "d->nlp");
443  // Signal failure to the caller so error_on_fail works in generated code too
444  // (the vm path does this via the return status); otherwise infeasible/limit
445  // outcomes look like success.
446  if (error_on_fail_) {
447  g << "return d->unified_return_status;\n";
448  } else {
449  g << "return 0;\n";
450  }
451  }
452 
453 } // namespace casadi
Helper class for C code generation.
std::string add_dependency(const Function &f)
Add a function dependency.
std::string constant(const std::vector< casadi_int > &v)
Represent an array constant; adding it when new.
static std::string array(const std::string &type, const std::string &name, casadi_int len, const std::string &def=std::string())
void local(const std::string &name, const std::string &type, const std::string &ref="")
Declare a local variable.
void init_local(const std::string &name, const std::string &def)
Specify the default value for a local variable.
std::string sanitize_source(const std::string &src, const std::vector< std::string > &inst, bool add_shorthand=true)
Sanitize source files for codegen.
void add_include(const std::string &new_include, bool relative_path=false, const std::string &use_ifdef=std::string())
Add an include file optionally using a relative path "..." instead of an absolute path <....
std::string initializer(const std::vector< T > &v)
Print an initializer.
std::string sparsity(const Sparsity &sp, bool canonical=true)
std::stringstream auxiliaries
void add_auxiliary(Auxiliary f, const std::vector< std::string > &inst={"casadi_real"})
Add a built-in auxiliary function.
Helper class for Serialization.
void unpack(Sparsity &e)
Reconstruct an object from the input stream.
void version(const std::string &name, int v)
std::string codegen_mem(CodeGenerator &g, const std::string &index="mem") const
Get thread-local memory object.
Function self() const
Get a public class instance.
Function object.
Definition: function.hpp:60
const Sparsity & sparsity_out(casadi_int ind) const
Get sparsity of a given output.
Definition: function.cpp:1183
Generic data type, can hold different types such as bool, casadi_int, std::string etc.
bool is_string() const
Check if a particular type.
std::string to_string() const
Convert to a type.
bool is_bool() const
Check if a particular type.
double to_double() const
Convert to a type.
bool is_double() const
Check if a particular type.
casadi_int to_int() const
Convert to a type.
bool to_bool() const
Convert to a type.
bool is_int() const
Check if a particular type.
NLP solver storage class.
Definition: nlpsol_impl.hpp:59
void codegen_post_solve(CodeGenerator &g, const std::string &d_nlp) const
Definition: nlpsol.cpp:1373
Dict get_stats(void *mem) const override
Get all statistics.
Definition: nlpsol.cpp:1251
static const Options options_
Options.
void codegen_declarations(CodeGenerator &g) const override
Generate code for the declarations of the C function.
Definition: nlpsol.cpp:1348
void init(const Dict &opts) override
Initialize.
Definition: nlpsol.cpp:499
casadi_int ng_
Number of constraints.
Definition: nlpsol_impl.hpp:69
void codegen_setup_per_call(CodeGenerator &g, const std::string &d_nlp) const
Definition: nlpsol.cpp:1313
int init_mem(void *mem) const override
Initalize memory block.
Definition: nlpsol.cpp:692
void codegen_setup_constants(CodeGenerator &g, const std::string &d_nlp, const std::string &p_nlp, const std::string &d_oracle) const
Definition: nlpsol.cpp:1281
casadi_nlpsol_prob< double > p_nlp_
Definition: nlpsol_impl.hpp:63
void serialize_body(SerializingStream &s) const override
Serialize an object without type information.
Definition: nlpsol.cpp:1409
bool calc_f_
Options.
Definition: nlpsol_impl.hpp:97
bool calc_g_
Options.
Definition: nlpsol_impl.hpp:97
void set_work(void *mem, const double **&arg, double **&res, casadi_int *&iw, double *&w) const override
Set the (persistent) work vectors.
Definition: nlpsol.cpp:884
Function create_function(const Function &oracle, const std::string &fname, const std::vector< std::string > &s_in, const std::vector< std::string > &s_out, const Function::AuxOut &aux=Function::AuxOut(), const Dict &opts=Dict())
Function create_forward(const std::string &fname, casadi_int nfwd)
std::vector< std::string > get_function() const override
Get list of dependency functions.
bool has_function(const std::string &fname) const override
static void registerPlugin(const Plugin &plugin, bool needs_lock=true)
Register an integrator in the factory.
bool error_on_fail_
Throw an exception on failure?
bool verbose_
Verbose printout.
void clear_mem()
Clear all memory (called from destructor)
Helper class for Serialization.
void version(const std::string &name, int v)
void pack(const Sparsity &e)
Serializes an object to the output stream.
std::vector< casadi_int > get_col() const
Get the column for each non-zero entry.
Definition: sparsity.cpp:368
std::vector< casadi_int > get_row() const
Get the row for each non-zero entry.
Definition: sparsity.cpp:372
'uno' plugin for Nlpsol
UnoInterface(const std::string &name, const Function &nlp)
void codegen_declarations(CodeGenerator &g) const override
Generate code for the declarations of the C function.
static Nlpsol * creator(const std::string &name, const Function &nlp)
void codegen_init_mem(CodeGenerator &g) const override
Codegen decref for init_mem.
static ProtoFunction * deserialize(DeserializingStream &s)
int solve(void *mem) const override
Dict get_stats(void *mem) const override
Get all statistics.
int init_mem(void *mem) const override
Initalize memory block.
void free_mem(void *mem) const override
Free memory block.
void codegen_free_mem(CodeGenerator &g) const override
Codegen for free_mem.
static const std::string meta_doc
void init(const Dict &opts) override
Initialize.
void codegen_body(CodeGenerator &g) const override
Generate code for the function body.
void set_work(void *mem, const double **&arg, double **&res, casadi_int *&iw, double *&w) const override
Set the (persistent) work vectors.
static const Options options_
void serialize_body(SerializingStream &s) const override
Serialize an object without type information.
The casadi namespace.
Definition: archiver.cpp:28
static void codegen_int_array(CodeGenerator &g, const std::string &name, const std::vector< uno_int > &v)
@ NLPSOL_X
Decision variables at the optimal solution (nx x 1)
Definition: nlpsol.hpp:217
@ NLPSOL_LAM_G
Lagrange multipliers for bounds on G at the solution (ng x 1)
Definition: nlpsol.hpp:225
@ NLPSOL_LAM_X
Lagrange multipliers for bounds on X at the solution (nx x 1)
Definition: nlpsol.hpp:223
static void set_uno_option(void *solver, const std::string &name, const GenericType &value)
void casadi_copy(const T1 *x, casadi_int n, T1 *y)
COPY: y <-x.
const char * return_status_string(Bonmin::TMINLP::SolverReturn status)
int CASADI_NLPSOL_UNO_EXPORT casadi_register_nlpsol_uno(Nlpsol::Plugin *plugin)
void CASADI_NLPSOL_UNO_EXPORT casadi_load_nlpsol_uno()
std::string str(const T &v)
String representation, any type.
GenericType::Dict Dict
C++ equivalent of Python's dict or MATLAB's struct.
static uno_int casadi_uno_term_cb_cpp(uno_int, uno_int, const double *primals, const double *lower_mult, const double *upper_mult, const double *constraint_mult, double, double, double, double, void *user_data)
static void insert_casadi_options(void *solver, Dict opts)
UnifiedReturnStatus
Integrator memory.
Definition: nlpsol_impl.hpp:40
Options metadata for a class.
Definition: options.hpp:40
static Dict sanitize(const Dict &opts, bool top_level=true)
Sanitize a options dictionary.
Definition: options.cpp:173
const char * return_status
UnoMemory(const UnoInterface &uno_interface)
casadi_uno_data< double > d_uno
const casadi_nlpsol_prob< T1 > * prob
Definition: casadi_nlp.hpp:75
casadi_nlpsol_data< T1 > nlp
Definition: uno_runtime.hpp:70
const casadi_int * sp_a
Definition: uno_runtime.hpp:31
uno_lagrangian_hessian_operator_callback hess_prod_cb
Definition: uno_runtime.hpp:50
OracleCallback nlp_grad_f
Definition: uno_runtime.hpp:41
uno_lagrangian_hessian_callback hess_cb
Definition: uno_runtime.hpp:49
OracleCallback nlp_hess_l
Definition: uno_runtime.hpp:43
uno_constraints_callback constr_cb
Definition: uno_runtime.hpp:47
const uno_int * hess_row
Definition: uno_runtime.hpp:36
OracleCallback nlp_g
Definition: uno_runtime.hpp:40
const uno_int * hess_col
Definition: uno_runtime.hpp:37
casadi_nlpsol_prob< T1 > nlp
Definition: uno_runtime.hpp:30
const uno_int * jac_col
Definition: uno_runtime.hpp:34
uno_objective_callback obj_cb
Definition: uno_runtime.hpp:45
OracleCallback nlp_f
Definition: uno_runtime.hpp:39
const uno_int * jac_row
Definition: uno_runtime.hpp:33
OracleCallback fwd1_nlp_grad_l
Definition: uno_runtime.hpp:44
const casadi_int * sp_h
Definition: uno_runtime.hpp:32
uno_constraints_jacobian_callback jac_cb
Definition: uno_runtime.hpp:48
uno_objective_gradient_callback obj_grad_cb
Definition: uno_runtime.hpp:46
OracleCallback nlp_jac_g
Definition: uno_runtime.hpp:42