From 22289967243cf5b039c065bf8d613bce50878ba7 Mon Sep 17 00:00:00 2001 From: gbanjac Date: Wed, 29 May 2019 14:16:05 +0200 Subject: [PATCH] Check in osqp_ functions that workspace is created --- docs/examples/setup-and-solve.rst | 55 ++++---- docs/examples/update-matrices.rst | 48 ++++--- docs/examples/update-vectors.rst | 51 +++---- examples/osqp_demo.c | 46 +++--- src/auxil.c | 16 ++- src/osqp.c | 226 +++++++++++++++++++++++++++++- 6 files changed, 343 insertions(+), 99 deletions(-) diff --git a/docs/examples/setup-and-solve.rst b/docs/examples/setup-and-solve.rst index d9715f01d..9db641aee 100644 --- a/docs/examples/setup-and-solve.rst +++ b/docs/examples/setup-and-solve.rst @@ -116,39 +116,44 @@ C c_int n = 2; c_int m = 3; - // Problem settings - OSQPSettings * settings = (OSQPSettings *)c_malloc(sizeof(OSQPSettings)); + // Exitflag + c_int exitflag = 0; - // Structures - OSQPWorkspace * work; // Workspace - OSQPData * data; // OSQPData + // Workspace structures + OSQPWorkspace *work; + OSQPSettings *settings = (OSQPSettings *)c_malloc(sizeof(OSQPSettings)); + OSQPData *data = (OSQPData *)c_malloc(sizeof(OSQPData)); // Populate data - data = (OSQPData *)c_malloc(sizeof(OSQPData)); - data->n = n; - data->m = m; - data->P = csc_matrix(data->n, data->n, P_nnz, P_x, P_i, P_p); - data->q = q; - data->A = csc_matrix(data->m, data->n, A_nnz, A_x, A_i, A_p); - data->l = l; - data->u = u; - - // Define Solver settings as default - osqp_set_default_settings(settings); - settings->alpha = 1.0; // Change alpha parameter + if (data) { + data->n = n; + data->m = m; + data->P = csc_matrix(data->n, data->n, P_nnz, P_x, P_i, P_p); + data->q = q; + data->A = csc_matrix(data->m, data->n, A_nnz, A_x, A_i, A_p); + data->l = l; + data->u = u; + } + + // Define solver settings as default + if (settings) { + osqp_set_default_settings(settings); + settings->alpha = 1.0; // Change alpha parameter + } // Setup workspace - osqp_setup(&work, data, settings); + exitflag = osqp_setup(&work, data, settings); // Solve Problem osqp_solve(work); // Cleanup - osqp_cleanup(work); - c_free(data->A); - c_free(data->P); - c_free(data); - c_free(settings); - - return 0; + if (data) { + if (data->A) c_free(data->A); + if (data->P) c_free(data->P); + c_free(data); + } + if (settings) c_free(settings); + + return exitflag; }; diff --git a/docs/examples/update-matrices.rst b/docs/examples/update-matrices.rst index e6c8ccf49..d17e5d09d 100644 --- a/docs/examples/update-matrices.rst +++ b/docs/examples/update-matrices.rst @@ -156,28 +156,31 @@ C c_int n = 2; c_int m = 3; - // Problem settings - OSQPSettings * settings = (OSQPSettings *)c_malloc(sizeof(OSQPSettings)); + // Exitflag + c_int exitflag = 0; - // Structures - OSQPWorkspace * work; // Workspace - OSQPData * data; // OSQPData + // Workspace structures + OSQPWorkspace *work; + OSQPSettings *settings = (OSQPSettings *)c_malloc(sizeof(OSQPSettings)); + OSQPData *data = (OSQPData *)c_malloc(sizeof(OSQPData)); // Populate data - data = (OSQPData *)c_malloc(sizeof(OSQPData)); - data->n = n; - data->m = m; - data->P = csc_matrix(data->n, data->n, P_nnz, P_x, P_i, P_p); - data->q = q; - data->A = csc_matrix(data->m, data->n, A_nnz, A_x, A_i, A_p); - data->l = l; - data->u = u; + if (data) { + data = (OSQPData *)c_malloc(sizeof(OSQPData)); + data->n = n; + data->m = m; + data->P = csc_matrix(data->n, data->n, P_nnz, P_x, P_i, P_p); + data->q = q; + data->A = csc_matrix(data->m, data->n, A_nnz, A_x, A_i, A_p); + data->l = l; + data->u = u; + } // Define Solver settings as default - osqp_set_default_settings(settings); + if (settings) osqp_set_default_settings(settings); // Setup workspace - osqp_setup(&work, data, settings); + exitflag = osqp_setup(&work, data, settings); // Solve problem osqp_solve(work); @@ -191,11 +194,12 @@ C osqp_solve(work); // Cleanup - osqp_cleanup(work); - c_free(data->A); - c_free(data->P); - c_free(data); - c_free(settings); - - return 0; + if (data) { + if (data->A) c_free(data->A); + if (data->P) c_free(data->P); + c_free(data); + } + if (settings) c_free(settings); + + return exitflag; }; diff --git a/docs/examples/update-vectors.rst b/docs/examples/update-vectors.rst index 1ca659e2b..67b728b00 100644 --- a/docs/examples/update-vectors.rst +++ b/docs/examples/update-vectors.rst @@ -154,28 +154,30 @@ C c_int n = 2; c_int m = 3; - // Problem settings - OSQPSettings * settings = (OSQPSettings *)c_malloc(sizeof(OSQPSettings)); + // Exitflag + c_int exitflag = 0; - // Structures - OSQPWorkspace * work; // Workspace - OSQPData * data; // OSQPData + // Workspace structures + OSQPWorkspace *work; + OSQPSettings *settings = (OSQPSettings *)c_malloc(sizeof(OSQPSettings)); + OSQPData *data = (OSQPData *)c_malloc(sizeof(OSQPData)); // Populate data - data = (OSQPData *)c_malloc(sizeof(OSQPData)); - data->n = n; - data->m = m; - data->P = csc_matrix(data->n, data->n, P_nnz, P_x, P_i, P_p); - data->q = q; - data->A = csc_matrix(data->m, data->n, A_nnz, A_x, A_i, A_p); - data->l = l; - data->u = u; - - // Define Solver settings as default - osqp_set_default_settings(settings); + if (data) { + data->n = n; + data->m = m; + data->P = csc_matrix(data->n, data->n, P_nnz, P_x, P_i, P_p); + data->q = q; + data->A = csc_matrix(data->m, data->n, A_nnz, A_x, A_i, A_p); + data->l = l; + data->u = u; + } + + // Define solver settings as default + if (settings) osqp_set_default_settings(settings); // Setup workspace - osqp_setup(&work, data, settings); + exitflag = osqp_setup(&work, data, settings); // Solve problem osqp_solve(work); @@ -188,11 +190,12 @@ C osqp_solve(work); // Cleanup - osqp_cleanup(work); - c_free(data->A); - c_free(data->P); - c_free(data); - c_free(settings); - - return 0; + if (data) { + if (data->A) c_free(data->A); + if (data->P) c_free(data->P); + c_free(data); + } + if (settings) c_free(settings); + + return exitflag; }; diff --git a/examples/osqp_demo.c b/examples/osqp_demo.c index f7d1667eb..107f83ee7 100644 --- a/examples/osqp_demo.c +++ b/examples/osqp_demo.c @@ -17,38 +17,42 @@ int main(int argc, char **argv) { c_int n = 2; c_int m = 3; - // Problem settings - OSQPSettings *settings = (OSQPSettings *)c_malloc(sizeof(OSQPSettings)); + // Exitflag + c_int exitflag = 0; - // Structures - OSQPWorkspace *work; // Workspace - OSQPData *data; // OSQPData + // Workspace structures + OSQPWorkspace *work; + OSQPSettings *settings = (OSQPSettings *)c_malloc(sizeof(OSQPSettings)); + OSQPData *data = (OSQPData *)c_malloc(sizeof(OSQPData)); // Populate data - data = (OSQPData *)c_malloc(sizeof(OSQPData)); - data->n = n; - data->m = m; - data->P = csc_matrix(data->n, data->n, P_nnz, P_x, P_i, P_p); - data->q = q; - data->A = csc_matrix(data->m, data->n, A_nnz, A_x, A_i, A_p); - data->l = l; - data->u = u; + if (data) { + data->n = n; + data->m = m; + data->P = csc_matrix(data->n, data->n, P_nnz, P_x, P_i, P_p); + data->q = q; + data->A = csc_matrix(data->m, data->n, A_nnz, A_x, A_i, A_p); + data->l = l; + data->u = u; + } // Define solver settings as default - osqp_set_default_settings(settings); + if (settings) osqp_set_default_settings(settings); // Setup workspace - osqp_setup(&work, data, settings); + exitflag = osqp_setup(&work, data, settings); // Solve Problem osqp_solve(work); // Clean workspace osqp_cleanup(work); - c_free(data->A); - c_free(data->P); - c_free(data); - c_free(settings); - - return 0; + if (data) { + if (data->A) c_free(data->A); + if (data->P) c_free(data->P); + c_free(data); + } + if (settings) c_free(settings); + + return exitflag; } diff --git a/src/auxil.c b/src/auxil.c index 7a33396ad..acf353fdb 100644 --- a/src/auxil.c +++ b/src/auxil.c @@ -797,7 +797,21 @@ c_int validate_data(const OSQPData *data) { if (!data) { # ifdef PRINTING c_eprint("Missing data"); -# endif /* ifdef PRINTING */ +# endif + return 1; + } + + if (!(data->P)) { +# ifdef PRINTING + c_eprint("Missing matrix P"); +# endif + return 1; + } + + if (!(data->A)) { +# ifdef PRINTING + c_eprint("Missing matrix A"); +# endif return 1; } diff --git a/src/osqp.c b/src/osqp.c index 9c25bb42f..7e83f15ee 100644 --- a/src/osqp.c +++ b/src/osqp.c @@ -749,6 +749,14 @@ c_int osqp_cleanup(OSQPWorkspace *work) { ************************/ c_int osqp_update_lin_cost(OSQPWorkspace *work, const c_float *q_new) { + // Check if workspace has been initialized + if (!work) { +#ifdef PRINTING + c_eprint("Workspace not initialized"); +#endif /* ifdef PRINTING */ + return -1; + } + #ifdef PROFILING if (work->clear_update_time == 1) { work->clear_update_time = 0; @@ -781,6 +789,14 @@ c_int osqp_update_bounds(OSQPWorkspace *work, const c_float *u_new) { c_int i, exitflag = 0; + // Check if workspace has been initialized + if (!work) { +#ifdef PRINTING + c_eprint("Workspace not initialized"); +#endif /* ifdef PRINTING */ + return -1; + } + #ifdef PROFILING if (work->clear_update_time == 1) { work->clear_update_time = 0; @@ -827,6 +843,14 @@ c_int osqp_update_bounds(OSQPWorkspace *work, c_int osqp_update_lower_bound(OSQPWorkspace *work, const c_float *l_new) { c_int i, exitflag = 0; + // Check if workspace has been initialized + if (!work) { +#ifdef PRINTING + c_eprint("Workspace not initialized"); +#endif /* ifdef PRINTING */ + return -1; + } + #ifdef PROFILING if (work->clear_update_time == 1) { work->clear_update_time = 0; @@ -871,6 +895,14 @@ c_int osqp_update_lower_bound(OSQPWorkspace *work, const c_float *l_new) { c_int osqp_update_upper_bound(OSQPWorkspace *work, const c_float *u_new) { c_int i, exitflag = 0; + // Check if workspace has been initialized + if (!work) { +#ifdef PRINTING + c_eprint("Workspace not initialized"); +#endif /* ifdef PRINTING */ + return -1; + } + #ifdef PROFILING if (work->clear_update_time == 1) { work->clear_update_time = 0; @@ -913,6 +945,15 @@ c_int osqp_update_upper_bound(OSQPWorkspace *work, const c_float *u_new) { } c_int osqp_warm_start(OSQPWorkspace *work, const c_float *x, const c_float *y) { + + // Check if workspace has been initialized + if (!work) { +#ifdef PRINTING + c_eprint("Workspace not initialized"); +#endif /* ifdef PRINTING */ + return -1; + } + // Update warm_start setting to true if (!work->settings->warm_start) work->settings->warm_start = 1; @@ -934,6 +975,15 @@ c_int osqp_warm_start(OSQPWorkspace *work, const c_float *x, const c_float *y) { } c_int osqp_warm_start_x(OSQPWorkspace *work, const c_float *x) { + + // Check if workspace has been initialized + if (!work) { +#ifdef PRINTING + c_eprint("Workspace not initialized"); +#endif /* ifdef PRINTING */ + return -1; + } + // Update warm_start setting to true if (!work->settings->warm_start) work->settings->warm_start = 1; @@ -952,6 +1002,15 @@ c_int osqp_warm_start_x(OSQPWorkspace *work, const c_float *x) { } c_int osqp_warm_start_y(OSQPWorkspace *work, const c_float *y) { + + // Check if workspace has been initialized + if (!work) { +#ifdef PRINTING + c_eprint("Workspace not initialized"); +#endif /* ifdef PRINTING */ + return -1; + } + // Update warm_start setting to true if (!work->settings->warm_start) work->settings->warm_start = 1; @@ -978,6 +1037,14 @@ c_int osqp_update_P(OSQPWorkspace *work, c_int exitflag; // Exit flag c_int nnzP; // Number of nonzeros in P + // Check if workspace has been initialized + if (!work) { +#ifdef PRINTING + c_eprint("Workspace not initialized"); +#endif /* ifdef PRINTING */ + return -1; + } + #ifdef PROFILING if (work->clear_update_time == 1) { work->clear_update_time = 0; @@ -1055,6 +1122,14 @@ c_int osqp_update_A(OSQPWorkspace *work, c_int exitflag; // Exit flag c_int nnzA; // Number of nonzeros in A + // Check if workspace has been initialized + if (!work) { +#ifdef PRINTING + c_eprint("Workspace not initialized"); +#endif /* ifdef PRINTING */ + return -1; + } + #ifdef PROFILING if (work->clear_update_time == 1) { work->clear_update_time = 0; @@ -1134,6 +1209,14 @@ c_int osqp_update_P_A(OSQPWorkspace *work, c_int exitflag; // Exit flag c_int nnzP, nnzA; // Number of nonzeros in P and A + // Check if workspace has been initialized + if (!work) { +#ifdef PRINTING + c_eprint("Workspace not initialized"); +#endif /* ifdef PRINTING */ + return -1; + } + #ifdef PROFILING if (work->clear_update_time == 1) { work->clear_update_time = 0; @@ -1233,6 +1316,14 @@ c_int osqp_update_P_A(OSQPWorkspace *work, c_int osqp_update_rho(OSQPWorkspace *work, c_float rho_new) { c_int exitflag, i; + // Check if workspace has been initialized + if (!work) { +#ifdef PRINTING + c_eprint("Workspace not initialized"); +#endif /* ifdef PRINTING */ + return -1; + } + // Check value of rho if (rho_new <= 0) { # ifdef PRINTING @@ -1286,6 +1377,15 @@ c_int osqp_update_rho(OSQPWorkspace *work, c_float rho_new) { * Update problem settings * ****************************/ c_int osqp_update_max_iter(OSQPWorkspace *work, c_int max_iter_new) { + + // Check if workspace has been initialized + if (!work) { +#ifdef PRINTING + c_eprint("Workspace not initialized"); +#endif /* ifdef PRINTING */ + return -1; + } + // Check that max_iter is positive if (max_iter_new <= 0) { #ifdef PRINTING @@ -1301,6 +1401,15 @@ c_int osqp_update_max_iter(OSQPWorkspace *work, c_int max_iter_new) { } c_int osqp_update_eps_abs(OSQPWorkspace *work, c_float eps_abs_new) { + + // Check if workspace has been initialized + if (!work) { +#ifdef PRINTING + c_eprint("Workspace not initialized"); +#endif /* ifdef PRINTING */ + return -1; + } + // Check that eps_abs is positive if (eps_abs_new < 0.) { #ifdef PRINTING @@ -1316,6 +1425,15 @@ c_int osqp_update_eps_abs(OSQPWorkspace *work, c_float eps_abs_new) { } c_int osqp_update_eps_rel(OSQPWorkspace *work, c_float eps_rel_new) { + + // Check if workspace has been initialized + if (!work) { +#ifdef PRINTING + c_eprint("Workspace not initialized"); +#endif /* ifdef PRINTING */ + return -1; + } + // Check that eps_rel is positive if (eps_rel_new < 0.) { #ifdef PRINTING @@ -1331,6 +1449,15 @@ c_int osqp_update_eps_rel(OSQPWorkspace *work, c_float eps_rel_new) { } c_int osqp_update_eps_prim_inf(OSQPWorkspace *work, c_float eps_prim_inf_new) { + + // Check if workspace has been initialized + if (!work) { +#ifdef PRINTING + c_eprint("Workspace not initialized"); +#endif /* ifdef PRINTING */ + return -1; + } + // Check that eps_prim_inf is positive if (eps_prim_inf_new < 0.) { #ifdef PRINTING @@ -1346,6 +1473,15 @@ c_int osqp_update_eps_prim_inf(OSQPWorkspace *work, c_float eps_prim_inf_new) { } c_int osqp_update_eps_dual_inf(OSQPWorkspace *work, c_float eps_dual_inf_new) { + + // Check if workspace has been initialized + if (!work) { +#ifdef PRINTING + c_eprint("Workspace not initialized"); +#endif /* ifdef PRINTING */ + return -1; + } + // Check that eps_dual_inf is positive if (eps_dual_inf_new < 0.) { #ifdef PRINTING @@ -1362,6 +1498,15 @@ c_int osqp_update_eps_dual_inf(OSQPWorkspace *work, c_float eps_dual_inf_new) { } c_int osqp_update_alpha(OSQPWorkspace *work, c_float alpha_new) { + + // Check if workspace has been initialized + if (!work) { +#ifdef PRINTING + c_eprint("Workspace not initialized"); +#endif /* ifdef PRINTING */ + return -1; + } + // Check that alpha is between 0 and 2 if ((alpha_new <= 0.) || (alpha_new >= 2.)) { #ifdef PRINTING @@ -1377,6 +1522,15 @@ c_int osqp_update_alpha(OSQPWorkspace *work, c_float alpha_new) { } c_int osqp_update_warm_start(OSQPWorkspace *work, c_int warm_start_new) { + + // Check if workspace has been initialized + if (!work) { +#ifdef PRINTING + c_eprint("Workspace not initialized"); +#endif /* ifdef PRINTING */ + return -1; + } + // Check that warm_start is either 0 or 1 if ((warm_start_new != 0) && (warm_start_new != 1)) { #ifdef PRINTING @@ -1391,8 +1545,16 @@ c_int osqp_update_warm_start(OSQPWorkspace *work, c_int warm_start_new) { return 0; } -c_int osqp_update_scaled_termination(OSQPWorkspace *work, - c_int scaled_termination_new) { +c_int osqp_update_scaled_termination(OSQPWorkspace *work, c_int scaled_termination_new) { + + // Check if workspace has been initialized + if (!work) { +#ifdef PRINTING + c_eprint("Workspace not initialized"); +#endif /* ifdef PRINTING */ + return -1; + } + // Check that scaled_termination is either 0 or 1 if ((scaled_termination_new != 0) && (scaled_termination_new != 1)) { #ifdef PRINTING @@ -1407,8 +1569,16 @@ c_int osqp_update_scaled_termination(OSQPWorkspace *work, return 0; } -c_int osqp_update_check_termination(OSQPWorkspace *work, - c_int check_termination_new) { +c_int osqp_update_check_termination(OSQPWorkspace *work, c_int check_termination_new) { + + // Check if workspace has been initialized + if (!work) { +#ifdef PRINTING + c_eprint("Workspace not initialized"); +#endif /* ifdef PRINTING */ + return -1; + } + // Check that check_termination is nonnegative if (check_termination_new < 0) { #ifdef PRINTING @@ -1426,6 +1596,15 @@ c_int osqp_update_check_termination(OSQPWorkspace *work, #ifndef EMBEDDED c_int osqp_update_delta(OSQPWorkspace *work, c_float delta_new) { + + // Check if workspace has been initialized + if (!work) { +#ifdef PRINTING + c_eprint("Workspace not initialized"); +#endif /* ifdef PRINTING */ + return -1; + } + // Check that delta is positive if (delta_new <= 0.) { # ifdef PRINTING @@ -1441,6 +1620,15 @@ c_int osqp_update_delta(OSQPWorkspace *work, c_float delta_new) { } c_int osqp_update_polish(OSQPWorkspace *work, c_int polish_new) { + + // Check if workspace has been initialized + if (!work) { +#ifdef PRINTING + c_eprint("Workspace not initialized"); +#endif /* ifdef PRINTING */ + return -1; + } + // Check that polish is either 0 or 1 if ((polish_new != 0) && (polish_new != 1)) { # ifdef PRINTING @@ -1461,8 +1649,16 @@ c_int osqp_update_polish(OSQPWorkspace *work, c_int polish_new) { return 0; } -c_int osqp_update_polish_refine_iter(OSQPWorkspace *work, - c_int polish_refine_iter_new) { +c_int osqp_update_polish_refine_iter(OSQPWorkspace *work, c_int polish_refine_iter_new) { + + // Check if workspace has been initialized + if (!work) { +#ifdef PRINTING + c_eprint("Workspace not initialized"); +#endif /* ifdef PRINTING */ + return -1; + } + // Check that polish_refine_iter is nonnegative if (polish_refine_iter_new < 0) { # ifdef PRINTING @@ -1478,6 +1674,15 @@ c_int osqp_update_polish_refine_iter(OSQPWorkspace *work, } c_int osqp_update_verbose(OSQPWorkspace *work, c_int verbose_new) { + + // Check if workspace has been initialized + if (!work) { +#ifdef PRINTING + c_eprint("Workspace not initialized"); +#endif /* ifdef PRINTING */ + return -1; + } + // Check that verbose is either 0 or 1 if ((verbose_new != 0) && (verbose_new != 1)) { # ifdef PRINTING @@ -1496,6 +1701,15 @@ c_int osqp_update_verbose(OSQPWorkspace *work, c_int verbose_new) { #ifdef PROFILING c_int osqp_update_time_limit(OSQPWorkspace *work, c_float time_limit_new) { + + // Check if workspace has been initialized + if (!work) { +#ifdef PRINTING + c_eprint("Workspace not initialized"); +#endif /* ifdef PRINTING */ + return -1; + } + // Check that time_limit is nonnegative if (time_limit_new < 0.) { # ifdef PRINTING