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==
"max_wall_time") {
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:
284 stats[
"iter_count"] = sleqp_solver_iterations(m->
internal.
solver);
289 void SLEQPInterface::update_settings(
const Dict& opts)
293 for (
auto&& op : opts) {
295 for (
int i = 0; i < SLEQP_NUM_INT_SETTINGS; ++i) {
296 SLEQP_SETTINGS_INT ii =
static_cast<SLEQP_SETTINGS_INT
>(i);
297 if (op.first==sleqp_settings_int_name(ii)) {
299 SLEQP_CALL_EXC(sleqp_settings_set_int_value(settings_,
301 op.second.to_int()));
304 for (
int i = 0; i < SLEQP_NUM_REAL_SETTINGS; ++i) {
305 SLEQP_SETTINGS_REAL ii =
static_cast<SLEQP_SETTINGS_REAL
>(i);
306 if (op.first==sleqp_settings_real_name(ii)) {
308 SLEQP_CALL_EXC(sleqp_settings_set_real_value(settings_,
310 op.second.to_double()));
313 for (
int i = 0; i < SLEQP_NUM_BOOL_SETTINGS; ++i) {
314 SLEQP_SETTINGS_BOOL ii =
static_cast<SLEQP_SETTINGS_BOOL
>(i);
315 if (op.first==sleqp_settings_bool_name(ii)) {
317 SLEQP_CALL_EXC(sleqp_settings_set_bool_value(settings_,
319 op.second.to_bool()));
322 for (
int i = 0; i < SLEQP_NUM_ENUM_SETTINGS; ++i) {
323 SLEQP_SETTINGS_ENUM ii =
static_cast<SLEQP_SETTINGS_ENUM
>(i);
324 if (op.first==sleqp_settings_enum_name(ii)) {
326 std::string value = op.second.to_string();
328 SLEQP_CALL_EXC(sleqp_settings_set_enum_value_from_string(settings_,
333 casadi_assert(found,
"Could not find option '" + op.first +
"'.");
339 casadi_int*& iw,
double*& w)
const {
353 const int num_vars =
nx_;
354 const int num_cons =
ng_;
359 sleqp_log_set_level(
static_cast<SLEQP_LOG_LEVEL
>(print_level_));
361 SLEQP_CALL_EXC(sleqp_vec_create_full(&var_lb, num_vars));
362 SLEQP_CALL_EXC(sleqp_vec_create_full(&var_ub, num_vars));
364 SLEQP_CALL_EXC(sleqp_vec_set_from_raw(var_lb,
365 const_cast<double*
>(d_nlp.
lbx),
369 SLEQP_CALL_EXC(sleqp_vec_set_from_raw(var_ub,
370 const_cast<double*
>(d_nlp.
ubx),
374 SLEQP_CALL_EXC(sleqp_vec_create_full(&m->
internal.
primal, num_vars));
377 const_cast<double*
>(d_nlp.
x0),
385 SLEQP_CALL_EXC(sleqp_vec_create_full(&cons_lb, num_cons));
386 SLEQP_CALL_EXC(sleqp_vec_create_full(&cons_ub, num_cons));
388 SLEQP_CALL_EXC(sleqp_vec_set_from_raw(cons_lb,
389 const_cast<double*
>(d_nlp.
lbg),
393 SLEQP_CALL_EXC(sleqp_vec_set_from_raw(cons_ub,
394 const_cast<double*
>(d_nlp.
ubg),
398 SleqpFunc* func =
nullptr;
426 SLEQP_CALL_EXC(sleqp_func_release(&func));
428 SLEQP_CALL_EXC(sleqp_vec_free(&cons_ub));
429 SLEQP_CALL_EXC(sleqp_vec_free(&cons_lb));
431 SLEQP_CALL_EXC(sleqp_vec_free(&var_ub));
432 SLEQP_CALL_EXC(sleqp_vec_free(&var_lb));
482 case SLEQP_STATUS_OPTIMAL:
484 case SLEQP_STATUS_INFEASIBLE:
487 case SLEQP_STATUS_ABORT_ITER:
488 case SLEQP_STATUS_ABORT_MANUAL:
489 case SLEQP_STATUS_ABORT_TIME:
506 const Function& fcallback_ = interface->fcallback_;
508 std::fill_n(m->
arg, fcallback_.n_in(),
nullptr);
511 m->
res[0] = &ret_double;
515 double obj_val = sleqp_iterate_obj_val(iterate);
519 SleqpVec* primal = sleqp_iterate_primal(iterate);
520 SLEQP_CALL(sleqp_vec_to_raw(primal, m->
cb_xk));
523 SleqpVec* cons_val = sleqp_iterate_cons_val(iterate);
524 SLEQP_CALL(sleqp_vec_to_raw(cons_val, m->
gk));
527 SleqpVec* vars_dual = sleqp_iterate_vars_dual(iterate);
528 SLEQP_CALL(sleqp_vec_to_raw(vars_dual, m->
cb_lam_xk));
531 SleqpVec* cons_dual = sleqp_iterate_cons_dual(iterate);
532 SLEQP_CALL(sleqp_vec_to_raw(cons_dual, m->
cb_lam_gk));
536 fcallback_(m->
arg, m->
res, m->
iw, m->
w, 0);
538 sleqp_raise(SLEQP_CALLBACK_ERROR,
"Interrupt caught in callback...");
539 }
catch(std::exception& ex) {
540 casadi_warning(
"intermediate_callback: " + std::string(ex.
what()));
542 sleqp_raise(SLEQP_CALLBACK_ERROR,
"Exception caught in callback...");
545 casadi_int ret =
static_cast<casadi_int
>(ret_double);
549 sleqp_raise(SLEQP_CALLBACK_ERROR,
"Error in callback...");
563 SLEQP_SOLVER_EVENT_ACCEPTED_ITERATE,
572 SleqpIterate* iterate;
581 SleqpVec* primal = sleqp_iterate_primal(iterate);
582 SLEQP_CALL_EXC(sleqp_vec_to_raw(primal, d_nlp.
z));
584 d_nlp.
objective = sleqp_iterate_obj_val(iterate);
586 SleqpVec* cons_val = sleqp_iterate_cons_val(iterate);
587 SLEQP_CALL_EXC(sleqp_vec_to_raw(cons_val, d_nlp.
z +
nx_));
589 SleqpVec* var_dual = sleqp_iterate_vars_dual(iterate);
590 SLEQP_CALL_EXC(sleqp_vec_to_raw(var_dual, d_nlp.
lam));
592 SleqpVec* cons_dual = sleqp_iterate_cons_dual(iterate);
593 SLEQP_CALL_EXC(sleqp_vec_to_raw(cons_dual, d_nlp.
lam +
nx_));
597 SLEQP_SOLVER_EVENT_ACCEPTED_ITERATE,
607 s.
version(
"SLEQPInterface", 1);
608 s.
unpack(
"SLEQPInterface::jacg_sp", jacg_sp_);
609 s.
unpack(
"SLEQPInterface::max_iter", max_iter_);
610 s.
unpack(
"SLEQPInterface::max_wall_time", max_wall_time_);
611 s.
unpack(
"SLEQPInterface::print_level", print_level_);
612 s.
unpack(
"SLEQPInterface::opts", opts_);
614 SLEQP_CALL_EXC(sleqp_settings_create(&settings_));
616 SLEQP_CALL_EXC(sleqp_settings_set_enum_value(settings_,
617 SLEQP_SETTINGS_ENUM_HESS_EVAL,
618 SLEQP_HESS_EVAL_EXACT));
619 update_settings(opts_);
624 s.
version(
"SLEQPInterface", 1);
625 s.
pack(
"SLEQPInterface::jacg_sp", jacg_sp_);
626 s.
pack(
"SLEQPInterface::max_iter", max_iter_);
627 s.
pack(
"SLEQPInterface::max_wall_time", max_wall_time_);
628 s.
pack(
"SLEQPInterface::print_level", print_level_);
629 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.
struct casadi::SLEQPMemory::@7 internal
bool iteration_callback_ignore_errors
const SLEQPInterface * interface