26 #include "madnlp_interface.hpp"
27 #include <madnlp_runtime_str.h>
29 #include "casadi/core/casadi_misc.hpp"
30 #include "../../core/global_options.hpp"
31 #include "../../core/casadi_interrupt.hpp"
32 #include "../../core/convexify.hpp"
45 int CASADI_NLPSOL_MADNLP_EXPORT
48 plugin->name =
"madnlp";
50 plugin->version = CASADI_VERSION;
73 "Options to be passed to madnlp"}},
74 {
"convexify_strategy",
76 "NONE|regularize|eigen-reflect|eigen-clip. "
77 "Strategy to convexify the Lagrange Hessian before passing it to the solver."}},
80 "When using a convexification strategy, make sure that "
81 "the smallest eigenvalue is at least this (default: 1e-7)."}},
87 for (
const auto& kv : opts) {
88 switch (kv.second.getType()) {
93 ret[prefix + kv.first] = kv.second;
102 casadi_int struct_cnt=0;
105 std::string convexify_strategy =
"none";
106 double convexify_margin = 1e-7;
107 casadi_int max_iter_eig = 200;
114 for (
auto&& op : opts) {
115 if (op.first==
"convexify_strategy") {
116 convexify_strategy = op.second.to_string();
117 }
else if (op.first==
"convexify_margin") {
118 convexify_margin = op.second;
119 }
else if (op.first==
"max_iter") {
120 max_iter_eig = op.second;
121 }
else if (op.first==
"madnlp") {
128 auto hessian_approximation =
opts_.find(
"hessian_approximation");
129 if (hessian_approximation!=
opts_.end()) {
148 {
"tril:hess:gamma:x:x"}, {{
"gamma", {
"f",
"g"}}});
153 if (convexify_strategy!=
"none") {
156 opts[
"strategy"] = convexify_strategy;
157 opts[
"margin"] = convexify_margin;
158 opts[
"max_iter_eig"] = max_iter_eig;
174 std::vector<char*> _argv = {};
177 int argc = _argv.size();
178 char** argv =
reinterpret_cast<char**
>(_argv.data());
188 libmad_create_options_dict(&(m->d.libmad_opts));
189 for (
const auto& kv :
opts_) {
190 switch (kv.second.getType()) {
192 libmad_set_double_option(m->d.libmad_opts, kv.first.c_str(), kv.second);
195 libmad_set_int64_option(m->d.libmad_opts, kv.first.c_str(), kv.second.to_int());
199 std::string s = kv.second.to_string();
200 libmad_set_string_option(m->d.libmad_opts, kv.first.c_str(), s.c_str());
204 libmad_set_bool_option(m->d.libmad_opts, kv.first.c_str(), kv.second.to_bool());
207 casadi_error(
"Unknown option type.");
210 casadi_madnlp_init_mem(&m->d);
217 casadi_madnlp_free_mem(&m->d);
223 casadi_int*& iw,
double*& w)
const {
230 m->d.
nlp = &m->d_nlp;
232 casadi_madnlp_set_work(&m->d, &arg, &res, &iw, &w);
234 m->d.nlp->oracle->m =
static_cast<void*
>(m);
241 ret = casadi_madnlp_presolve(&m->d);
242 casadi_assert(ret==0,
"MadNLPError in presolve");
244 ret = casadi_madnlp_solve(&m->d);
245 casadi_assert(ret==0,
"MadNLPError in solve");
247 m->success = m->d.success;
256 libmad_int iter, status;
258 double primal_feas, dual_feas;
259 ret = madnlp_get_iters(m->d.stats, &iter); casadi_assert(ret==0,
"MadNLPError in get_iters");
260 ret = madnlp_get_status(m->d.stats, &status); casadi_assert(ret==0,
"MadNLPError in get_status");
261 ret = madnlp_get_dual_feas(m->d.stats, &dual_feas);
262 casadi_assert(ret==0,
"MadNLPError in get_dual_feas");
263 ret = madnlp_get_primal_feas(m->d.stats, &primal_feas);
264 casadi_assert(ret==0,
"MadNLPError in get_primal_feas");
266 stats[
"iter_count"] =
static_cast<casadi_int
>(iter);
268 madnlp[
"dual_feas"] = dual_feas;
269 madnlp[
"primal_feas"] = primal_feas;
270 madnlp[
"status"] =
static_cast<casadi_int
>(status);
271 stats[
"madnlp"] = madnlp;
290 casadi_madnlp_setup(&p_);
295 g <<
"libmad_create_options_dict(&(" +
codegen_mem(g) +
".libmad_opts));\n";
296 for (
const auto& kv :
opts_) {
297 switch (kv.second.getType()) {
299 g <<
"libmad_set_double_option(" +
codegen_mem(g) +
".libmad_opts, "
300 + kv.first +
", " +
str(kv.second) +
");\n";
303 g <<
"libmad_set_int64_option(" +
codegen_mem(g) +
".libmad_opts, "
304 + kv.first +
", " +
str(kv.second) +
");\n";
308 std::string s = kv.second.to_string();
309 g <<
"libmad_set_string_option(" +
codegen_mem(g) +
".libmad_opts, "
310 + kv.first +
", " + s +
");\n";
314 g <<
"libmad_set_bool_option(" +
codegen_mem(g) +
".libmad_opts, "
315 + kv.first +
", " +
str(kv.second) +
");\n";
318 casadi_error(
"Unknown option type.");
321 g <<
"casadi_madnlp_init_mem(&" +
codegen_mem(g) +
");\n";
327 g <<
"casadi_madnlp_free_mem(&" +
codegen_mem(g) +
");\n";
354 g.
local(
"d",
"struct casadi_madnlp_data*");
356 g.
local(
"p",
"struct casadi_madnlp_prob");
359 g <<
"casadi_madnlp_set_work(d, &arg, &res, &iw, &w);\n";
360 g <<
"casadi_oracle_set_work(d->nlp->oracle, &arg, &res, &iw, &w);\n";
361 g <<
"casadi_madnlp_presolve(d);\n";
362 g <<
"casadi_madnlp_solve(d);\n";
367 g <<
"return d->unified_return_status;\n";
375 casadi_error(
"Empty sparsity pattern not supported in MADNLP C interface");
377 g <<
"d->nlp = &d_nlp;\n";
378 g <<
"d->prob = &p;\n";
379 g <<
"p.nlp = &p_nlp;\n";
391 g <<
"p.sp_h = 0;\n";
394 g <<
"casadi_madnlp_setup(&p);\n";
398 int version = s.
version(
"MadnlpInterface", 1, 2);
406 std::vector<libmad_int> dummy;
407 s.
unpack(
"MadnlpInterface::nzj_i", dummy);
408 s.
unpack(
"MadnlpInterface::nzj_j", dummy);
409 s.
unpack(
"MadnlpInterface::nzh_i", dummy);
410 s.
unpack(
"MadnlpInterface::nzh_j", dummy);
418 s.
version(
"MadnlpInterface", 2);
Helper class for C code generation.
std::string add_dependency(const Function &f)
Add a function dependency.
void local(const std::string &name, const std::string &type, const std::string &ref="")
Declare a local variable.
void setup_callback(const std::string &s, const Function &f)
Setup a callback.
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 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.
static Sparsity setup(ConvexifyData &d, const Sparsity &H, const Dict &opts=Dict(), bool inplace=true)
Helper class for Serialization.
void unpack(Sparsity &e)
Reconstruct an object from the input stream.
void version(const std::string &name, int v)
void alloc_iw(size_t sz_iw, bool persistent=false)
Ensure required length of iw field.
void alloc_res(size_t sz_res, bool persistent=false)
Ensure required length of res field.
void alloc_arg(size_t sz_arg, bool persistent=false)
Ensure required length of arg field.
std::string codegen_mem(CodeGenerator &g, const std::string &index="mem") const
Get thread-local memory object.
size_t sz_res() const
Get required length of res field.
size_t sz_w() const
Get required length of w field.
void alloc_w(size_t sz_w, bool persistent=false)
Ensure required length of w field.
size_t sz_arg() const
Get required length of arg field.
size_t sz_iw() const
Get required length of iw field.
static const Options options_
Options.
MadnlpInterface(const std::string &name, const Function &nlp)
void codegen_init_mem(CodeGenerator &g) const override
Codegen alloc_mem.
Dict get_stats(void *mem) const override
Get all statistics.
void codegen_declarations(CodeGenerator &g) const override
Generate code for the declarations of the C function.
void init(const Dict &opts) override
Initialize.
void codegen_free_mem(CodeGenerator &g) const override
Codegen free_mem.
static Nlpsol * creator(const std::string &name, const Function &nlp)
Create a new NLP Solver.
int init_mem(void *mem) const override
Initalize memory block.
bool convexify_
convexify?
void free_mem(void *mem) const override
Free memory block.
void serialize_body(SerializingStream &s) const override
Serialize an object without type information.
void set_work(void *mem, const double **&arg, double **&res, casadi_int *&iw, double *&w) const override
Set the (persistent) work vectors.
~MadnlpInterface() override
static const std::string meta_doc
A documentation string.
bool exact_hessian_
Exact Hessian?
static ProtoFunction * deserialize(DeserializingStream &s)
Deserialize into MX.
Dict opts_
All MADNLP options.
void codegen_body(CodeGenerator &g) const override
Generate code for the function body.
ConvexifyData convexify_data_
Data for convexification.
int solve(void *mem) const override
NLP solver storage class.
void codegen_body_exit(CodeGenerator &g) const override
Generate code for the function body.
Dict get_stats(void *mem) const override
Get all statistics.
static const Options options_
Options.
void codegen_body_enter(CodeGenerator &g) const override
Generate code for the function body.
void codegen_declarations(CodeGenerator &g) const override
Generate code for the declarations of the C function.
void init(const Dict &opts) override
Initialize.
int init_mem(void *mem) const override
Initalize memory block.
casadi_nlpsol_prob< double > p_nlp_
void serialize_body(SerializingStream &s) const override
Serialize an object without type information.
void set_work(void *mem, const double **&arg, double **&res, casadi_int *&iw, double *&w) const override
Set the (persistent) work vectors.
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())
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.
casadi_int size1() const
Get the number of rows.
bool is_tril(bool strictly=false) const
Is lower triangular?
casadi_int nnz() const
Get the number of (structural) non-zeros.
void CASADI_NLPSOL_MADNLP_EXPORT casadi_load_nlpsol_madnlp()
std::string str(const T &v)
String representation, any type.
GenericType::Dict Dict
C++ equivalent of Python's dict or MATLAB's struct.
int CASADI_NLPSOL_MADNLP_EXPORT casadi_register_nlpsol_madnlp(Nlpsol::Plugin *plugin)
void flatten_opts(Dict &ret, const Dict &opts, const std::string &prefix)
Options metadata for a class.
OracleCallback nlp_hess_l
const casadi_nlpsol_prob< T1 > * nlp
OracleCallback nlp_grad_f