Austin Schuh | 9049e20 | 2022-02-20 17:34:16 -0800 | [diff] [blame] | 1 | Contributing |
| 2 | ============= |
| 3 | |
| 4 | OSQP is an open-source project open to any academic or commercial applications. |
| 5 | Contributions are welcome as `GitHub pull requests <https://help.github.com/articles/creating-a-pull-request/>`_ in any part of the project such as |
| 6 | |
| 7 | * algorithm developments |
| 8 | * interfaces to other languages |
| 9 | * compatibility with new architectures |
| 10 | * linear system solvers interfaces |
| 11 | |
| 12 | |
| 13 | .. _interfacing_new_linear_system_solvers : |
| 14 | |
| 15 | Interfacing new linear system solvers |
| 16 | ------------------------------------- |
| 17 | OSQP is designed to be easily interfaced to new linear system solvers via dynamic library loading. |
| 18 | To add a linear system solver interface you need to edit the :code:`lin_sys/` directory subfolder :code:`direct/` or :code:`indirect/` depending on the type of solver. |
| 19 | Create a subdirectory with your solver name with four files: |
| 20 | |
| 21 | * Dynamic library loading: :code:`mysolver_loader.c` and :code:`mysolver_loader.h`. |
| 22 | * Linear system solution: :code:`mysolver.c` and :code:`mysolver.h`. |
| 23 | |
| 24 | We suggest you to have a look at the `MKL Pardiso solver interface <https://github.com/osqp/osqp/tree/master/lin_sys/direct/pardiso>`_ for more details. |
| 25 | |
| 26 | Dynamic library loading |
| 27 | ^^^^^^^^^^^^^^^^^^^^^^^ |
| 28 | In this part define the methods to load the shared library and obtain the functions required to solve the linear system. |
| 29 | The main functions to be exported are :code:`lh_load_mysolver(const char* libname)` and :code:`lh_unload_mysolver()`. |
| 30 | In addition, the file :code:`mysolver_loader.c` must define static function pointers to the shared library functions to be loaded. |
| 31 | |
| 32 | Linear system solution |
| 33 | ^^^^^^^^^^^^^^^^^^^^^^ |
| 34 | In this part we define the core of the interface: **linear system solver object**. |
| 35 | The main functions are the external method |
| 36 | |
| 37 | * :code:`init_linsys_solver_mysolver`: create the instance and perform the setup |
| 38 | |
| 39 | and the internal methods of the object |
| 40 | |
| 41 | * :code:`free_linsys_solver_mysolver`: free the instance |
| 42 | * :code:`solve_linsys_mysolver`: solve the linear system |
| 43 | * :code:`update_matrices`: update problem matrices |
| 44 | * :code:`update_rho_vec`: update :math:`\rho` as a diagonal vector. |
| 45 | |
| 46 | After the initializations these functions are assigned to the internal pointers so that, for an instance :code:`s` they can be called as :code:`s->free`, :code:`s->solve`, :code:`s->update_matrices` and :code:`s->update_rho_vec`. |
| 47 | |
| 48 | The linear system solver object is defined in :code:`mysolver.h` as follows |
| 49 | |
| 50 | .. code:: c |
| 51 | |
| 52 | typedef struct mysolver mysolver_solver; |
| 53 | |
| 54 | struct mysolver { |
| 55 | // Methods |
| 56 | enum linsys_solver_type type; // Linear system solver defined in constants.h |
| 57 | |
| 58 | c_int (*solve)(struct mysolver * self, c_float * b); |
| 59 | void (*free)(struct mysolver * self); |
| 60 | c_int (*update_matrices)(struct mysolver * self, const csc *P, const csc *A); |
| 61 | c_int (*update_rho_vec)(struct mysolver * self, const c_float * rho_vec); |
| 62 | |
| 63 | // Attributes |
| 64 | c_int nthreads; // Number of threads used (required!) |
| 65 | |
| 66 | // Internal attributes of the solver |
| 67 | ... |
| 68 | |
| 69 | // Internal attributes required for matrix updates |
| 70 | c_int * Pdiag_idx, Pdiag_n; ///< index and number of diagonal elements in P |
| 71 | c_int * PtoKKT, * AtoKKT; ///< Index of elements from P and A to KKT matrix |
| 72 | c_int * rhotoKKT; ///< Index of rho places in KKT matrix |
| 73 | ... |
| 74 | |
| 75 | }; |
| 76 | |
| 77 | // Initialize mysolver solver |
| 78 | c_int init_linsys_solver_mysolver(mysolver_solver ** s, const csc * P, const csc * A, c_float sigma, c_float * rho_vec, c_int polish); |
| 79 | |
| 80 | // Solve linear system and store result in b |
| 81 | c_int solve_linsys_mysolver(mysolver_solver * s, c_float * b); |
| 82 | |
| 83 | // Update linear system solver matrices |
| 84 | c_int update_linsys_solver_matrices_mysolver(mysolver_solver * s, const csc *P, const csc *A); |
| 85 | |
| 86 | // Update rho_vec parameter in linear system solver structure |
| 87 | c_int update_linsys_solver_rho_vec_mysolver(mysolver_solver * s, const c_float * rho_vec); |
| 88 | |
| 89 | // Free linear system solver |
| 90 | void free_linsys_solver_mysolver(mysolver_solver * s); |
| 91 | |
| 92 | |
| 93 | The function details are coded in the :code:`mysolver.c` file. |