26 #include "sleqp_interface.hpp"
27 #include "sleqp_func.hpp"
58 casadi_warning(message);
61 casadi_error(message);
69 int CASADI_NLPSOL_SLEQP_EXPORT
72 plugin->name =
"sleqp";
74 plugin->version = CASADI_VERSION;
97 if (settings_) SLEQP_CALL_EXC(sleqp_settings_release(&settings_));
99 }
catch(std::exception e) {
100 casadi_message(std::string(
"SLEQP error ") + e.what());
108 "Options to be passed to SLEQP"}},
111 "Print level of SLEQP (default: 2/SLEQP_LOG_WARN)"}},
114 "Maximum number of iterations"}},
117 "maximum wall time allowed"}}
123 bool SLEQPInterface::exact_hess()
const
125 SLEQP_HESS_EVAL hess_eval = (SLEQP_HESS_EVAL) sleqp_settings_enum_value(settings_,
126 SLEQP_SETTINGS_ENUM_HESS_EVAL);
128 return hess_eval == SLEQP_HESS_EVAL_EXACT;
134 max_iter_ = SLEQP_NONE;
135 max_wall_time_ = SLEQP_NONE;
136 print_level_ =
static_cast<int>(SLEQP_LOG_WARN);
139 for (
auto&& op : opts) {
140 if (op.first==
"sleqp") {
142 }
if (op.first==
"print_level") {
143 print_level_ = op.second;
144 }
if (op.first==
"max_iter") {
145 max_iter_ = op.second;
146 casadi_assert(max_iter_>=0,
"Invalid iteration limit " +
str(max_iter_));
147 }
if (op.first==
"time_limit") {
148 max_wall_time_ = op.second;
149 casadi_assert(max_wall_time_>=0,
"Invalid time limit " +
str(max_wall_time_));
153 SLEQP_CALL_EXC(sleqp_settings_create(&settings_));
156 SLEQP_CALL_EXC(sleqp_settings_set_enum_value(settings_,
157 SLEQP_SETTINGS_ENUM_HESS_EVAL,
158 SLEQP_HESS_EVAL_EXACT));
159 update_settings(opts_);
204 final_options[
"is_diff_in"] = std::vector<bool>{
true,
false,
false,
false};
205 final_options[
"is_diff_out"] = std::vector<bool>{
true};
207 opts[
"final_options"] = final_options;
211 {
"grad:gamma:x"}, {{
"gamma", {
"f",
"g"}}}, opts);
234 void SLEQPInterface::clear_mem_at(
SLEQPMemory* m)
const {
251 case SLEQP_STATUS_RUNNING:
253 case SLEQP_STATUS_OPTIMAL:
255 case SLEQP_STATUS_INFEASIBLE:
257 case SLEQP_STATUS_UNBOUNDED:
259 case SLEQP_STATUS_ABORT_DEADPOINT:
261 case SLEQP_STATUS_ABORT_ITER:
262 return "iteration limit";
263 case SLEQP_STATUS_ABORT_MANUAL:
264 return "manual abort";
265 case SLEQP_STATUS_ABORT_TIME:
281 stats[
"iter_count"] = sleqp_solver_iterations(m->
internal.
solver);
286 void SLEQPInterface::update_settings(
const Dict& opts)
290 for (
auto&& op : opts_) {
292 for (
int i = 0; i < SLEQP_NUM_INT_SETTINGS; ++i) {
293 SLEQP_SETTINGS_INT ii =
static_cast<SLEQP_SETTINGS_INT
>(i);
294 if (op.first==sleqp_settings_int_name(ii)) {
296 SLEQP_CALL_EXC(sleqp_settings_set_int_value(settings_,
298 op.second.to_int()));
301 for (
int i = 0; i < SLEQP_NUM_REAL_SETTINGS; ++i) {
302 SLEQP_SETTINGS_REAL ii =
static_cast<SLEQP_SETTINGS_REAL
>(i);
303 if (op.first==sleqp_settings_real_name(ii)) {
305 SLEQP_CALL_EXC(sleqp_settings_set_real_value(settings_,
307 op.second.to_double()));
310 for (
int i = 0; i < SLEQP_NUM_BOOL_SETTINGS; ++i) {
311 SLEQP_SETTINGS_BOOL ii =
static_cast<SLEQP_SETTINGS_BOOL
>(i);
312 if (op.first==sleqp_settings_bool_name(ii)) {
314 SLEQP_CALL_EXC(sleqp_settings_set_bool_value(settings_,
316 op.second.to_bool()));
319 for (
int i = 0; i < SLEQP_NUM_ENUM_SETTINGS; ++i) {
320 SLEQP_SETTINGS_ENUM ii =
static_cast<SLEQP_SETTINGS_ENUM
>(i);
321 if (op.first==sleqp_settings_enum_name(ii)) {
323 std::string value = op.second.to_string();
325 SLEQP_CALL_EXC(sleqp_settings_set_enum_value_from_string(settings_,
330 casadi_assert(found,
"Could not find option '" + op.first +
"'.");
336 casadi_int*& iw,
double*& w)
const {
349 const int num_vars =
nx_;
350 const int num_cons =
ng_;
355 sleqp_log_set_level(
static_cast<SLEQP_LOG_LEVEL
>(print_level_));
357 SLEQP_CALL_EXC(sleqp_vec_create_full(&var_lb, num_vars));
358 SLEQP_CALL_EXC(sleqp_vec_create_full(&var_ub, num_vars));
360 SLEQP_CALL_EXC(sleqp_vec_set_from_raw(var_lb,
361 const_cast<double*
>(d_nlp.
lbx),
365 SLEQP_CALL_EXC(sleqp_vec_set_from_raw(var_ub,
366 const_cast<double*
>(d_nlp.
ubx),
370 SLEQP_CALL_EXC(sleqp_vec_create_full(&m->
internal.
primal, num_vars));
373 const_cast<double*
>(d_nlp.
x0),
381 SLEQP_CALL_EXC(sleqp_vec_create_full(&cons_lb, num_cons));
382 SLEQP_CALL_EXC(sleqp_vec_create_full(&cons_ub, num_cons));
384 SLEQP_CALL_EXC(sleqp_vec_set_from_raw(cons_lb,
385 const_cast<double*
>(d_nlp.
lbg),
389 SLEQP_CALL_EXC(sleqp_vec_set_from_raw(cons_ub,
390 const_cast<double*
>(d_nlp.
ubg),
394 SleqpFunc* func =
nullptr;
422 SLEQP_CALL_EXC(sleqp_func_release(&func));
424 SLEQP_CALL_EXC(sleqp_vec_free(&cons_ub));
425 SLEQP_CALL_EXC(sleqp_vec_free(&cons_lb));
427 SLEQP_CALL_EXC(sleqp_vec_free(&var_ub));
428 SLEQP_CALL_EXC(sleqp_vec_free(&var_lb));
478 case SLEQP_STATUS_OPTIMAL:
480 case SLEQP_STATUS_INFEASIBLE:
483 case SLEQP_STATUS_ABORT_ITER:
484 case SLEQP_STATUS_ABORT_MANUAL:
485 case SLEQP_STATUS_ABORT_TIME:
502 const Function& fcallback_ = interface->fcallback_;
504 std::fill_n(m->
arg, fcallback_.n_in(),
nullptr);
507 m->
res[0] = &ret_double;
511 double obj_val = sleqp_iterate_obj_val(iterate);
515 SleqpVec* primal = sleqp_iterate_primal(iterate);
516 SLEQP_CALL(sleqp_vec_to_raw(primal, m->
cb_xk));
519 SleqpVec* cons_val = sleqp_iterate_cons_val(iterate);
520 SLEQP_CALL(sleqp_vec_to_raw(cons_val, m->
gk));
523 SleqpVec* vars_dual = sleqp_iterate_vars_dual(iterate);
524 SLEQP_CALL(sleqp_vec_to_raw(vars_dual, m->
cb_lam_xk));
527 SleqpVec* cons_dual = sleqp_iterate_cons_dual(iterate);
528 SLEQP_CALL(sleqp_vec_to_raw(cons_dual, m->
cb_lam_gk));
532 fcallback_(m->
arg, m->
res, m->
iw, m->
w, 0);
534 sleqp_raise(SLEQP_CALLBACK_ERROR,
"Interrupt caught in callback...");
535 }
catch(std::exception& ex) {
536 casadi_warning(
"intermediate_callback: " + std::string(ex.
what()));
538 sleqp_raise(SLEQP_CALLBACK_ERROR,
"Exception caught in callback...");
541 casadi_int ret =
static_cast<casadi_int
>(ret_double);
545 sleqp_raise(SLEQP_CALLBACK_ERROR,
"Error in callback...");
559 SLEQP_SOLVER_EVENT_ACCEPTED_ITERATE,
568 SleqpIterate* iterate;
577 SleqpVec* primal = sleqp_iterate_primal(iterate);
578 SLEQP_CALL_EXC(sleqp_vec_to_raw(primal, d_nlp.
z));
580 d_nlp.
objective = sleqp_iterate_obj_val(iterate);
582 SleqpVec* cons_val = sleqp_iterate_cons_val(iterate);
583 SLEQP_CALL_EXC(sleqp_vec_to_raw(cons_val, d_nlp.
z +
nx_));
585 SleqpVec* var_dual = sleqp_iterate_vars_dual(iterate);
586 SLEQP_CALL_EXC(sleqp_vec_to_raw(var_dual, d_nlp.
lam));
588 SleqpVec* cons_dual = sleqp_iterate_cons_dual(iterate);
589 SLEQP_CALL_EXC(sleqp_vec_to_raw(cons_dual, d_nlp.
lam +
nx_));
593 SLEQP_SOLVER_EVENT_ACCEPTED_ITERATE,
603 s.
version(
"SLEQPInterface", 1);
604 s.
unpack(
"SLEQPInterface::jacg_sp", jacg_sp_);
605 s.
unpack(
"SLEQPInterface::max_iter", max_iter_);
606 s.
unpack(
"SLEQPInterface::max_wall_time", max_wall_time_);
607 s.
unpack(
"SLEQPInterface::print_level", print_level_);
608 s.
unpack(
"SLEQPInterface::opts", opts_);
610 SLEQP_CALL_EXC(sleqp_settings_create(&settings_));
611 update_settings(opts_);
616 s.
version(
"SLEQPInterface", 1);
617 s.
pack(
"SLEQPInterface::jacg_sp", jacg_sp_);
618 s.
pack(
"SLEQPInterface::max_iter", max_iter_);
619 s.
pack(
"SLEQPInterface::max_wall_time", max_wall_time_);
620 s.
pack(
"SLEQPInterface::print_level", print_level_);
621 s.
pack(
"SLEQPInterface::opts", opts_);
const char * what() const override
Display error.
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_w(size_t sz_w, bool persistent=false)
Ensure required length of w field.
bool is_null() const
Is a null pointer?
NLP solver storage class.
bool iteration_callback_ignore_errors_
Options.
Dict get_stats(void *mem) const override
Get all statistics.
static const Options options_
Options.
void init(const Dict &opts) override
Initialize.
casadi_int ng_
Number of constraints.
virtual void check_inputs(void *mem) const
Check if the inputs correspond to a well-posed problem.
int init_mem(void *mem) const override
Initalize memory block.
void serialize_body(SerializingStream &s) const override
Serialize an object without type information.
casadi_int nx_
Number of variables.
void set_work(void *mem, const double **&arg, double **&res, casadi_int *&iw, double *&w) const override
Set the (persistent) work vectors.
Function fcallback_
callback function, executed at each iteration
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.
void clear_mem()
Clear all memory (called from destructor)
static const Options options_
int init_mem(void *mem) const override
Initalize memory block.
void serialize_body(SerializingStream &s) const override
Serialize an object without type information.
static ProtoFunction * deserialize(DeserializingStream &s)
Deserialize into MX.
int solve(void *mem) const override
SLEQPInterface(const std::string &name, const Function &nlp)
static const std::string meta_doc
~SLEQPInterface() override
void init(const Dict &opts) override
Initialize.
static Nlpsol * creator(const std::string &name, const Function &nlp)
Dict get_stats(void *mem) const override
Get all statistics.
void set_work(void *mem, const double **&arg, double **&res, casadi_int *&iw, double *&w) const override
Set the (persistent) work vectors.
void free_mem(void *mem) const override
Free memory block.
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 nnz() const
Get the number of (structural) non-zeros.
@ NLPSOL_G
Constraints function at the optimal solution (ng x 1)
@ NLPSOL_X
Decision variables at the optimal solution (nx x 1)
@ NLPSOL_F
Cost function value at the optimal solution (1 x 1)
@ NLPSOL_LAM_G
Lagrange multipliers for bounds on G at the solution (ng x 1)
@ NLPSOL_LAM_X
Lagrange multipliers for bounds on X at the solution (nx x 1)
int CASADI_NLPSOL_SLEQP_EXPORT casadi_register_nlpsol_sleqp(Nlpsol::Plugin *plugin)
void casadi_sleqp_func_create(SleqpFunc **star, int num_vars, int num_cons, SLEQPMemory *m)
std::string log_level_name(SLEQP_LOG_LEVEL level)
void CASADI_NLPSOL_SLEQP_EXPORT casadi_load_nlpsol_sleqp()
UnifiedReturnStatus map_status(SLEQP_STATUS status)
static std::string status_string(SLEQP_STATUS status)
std::string str(const T &v)
String representation, any type.
GenericType::Dict Dict
C++ equivalent of Python's dict or MATLAB's struct.
static void casadi_log_output(SLEQP_LOG_LEVEL level, time_t time, const char *message)
static SLEQP_RETCODE accepted_iterate(SleqpSolver *solver, SleqpIterate *iterate, void *data)
UnifiedReturnStatus unified_return_status
casadi_nlpsol_data< double > d_nlp
Options metadata for a class.
bool iteration_callback_ignore_errors
const SLEQPInterface * interface
struct casadi::SLEQPMemory::@6 internal