blob: f120e47210d835710dd647621a280994370ca6dd [file] [log] [blame]
Austin Schuh9049e202022-02-20 17:34:16 -08001#include "lib_handler.h"
2#include "pardiso_loader.h"
3
4#include "glob_opts.h"
5#include "constants.h"
6
7#ifdef IS_WINDOWS
8#define PARDISOLIBNAME "mkl_rt." SHAREDLIBEXT
9#else
10#define PARDISOLIBNAME "libmkl_rt." SHAREDLIBEXT
11#endif
12
13typedef void (*voidfun)(void);
14
15voidfun lh_load_sym (soHandle_t h, const char *symName);
16
17
18// Interfaces for Pardiso functions
19typedef void (*pardiso_t)(void**, const c_int*, const c_int*, const c_int*,
20 const c_int*, const c_int*, const c_float*,
21 const c_int*, const c_int*, c_int*,
22 const c_int*, c_int*, const c_int*, c_float*,
23 c_float*, c_int*);
24typedef int (*mkl_set_ifl_t)(int);
25typedef int (*mkl_get_mt_t)();
26
27
28// Handlers are static variables
29static soHandle_t Pardiso_handle = OSQP_NULL;
30static pardiso_t func_pardiso = OSQP_NULL;
31static mkl_set_ifl_t func_mkl_set_interface_layer = OSQP_NULL;
32static mkl_get_mt_t func_mkl_get_max_threads = OSQP_NULL;
33
34// Wrappers for loaded Pardiso function handlers
35void pardiso(void** pt, const c_int* maxfct, const c_int* mnum,
36 const c_int* mtype, const c_int* phase, const c_int* n,
37 const c_float* a, const c_int* ia, const c_int* ja,
38 c_int* perm, const c_int* nrhs, c_int* iparm,
39 const c_int* msglvl, c_float* b, c_float* x,
40 c_int* error) {
41 if(func_pardiso){
42 // Call function pardiso only if it has been initialized
43 func_pardiso(pt, maxfct, mnum, mtype, phase, n, a, ia, ja,
44 perm, nrhs, iparm, msglvl, b, x, error);
45 }
46 else
47 {
48#ifdef PRINTING
49 c_eprint("Pardiso not loaded correctly");
50#endif
51 }
52}
53
54c_int mkl_set_interface_layer(c_int code) {
55 return (c_int)func_mkl_set_interface_layer((int)code);
56}
57
58c_int mkl_get_max_threads() {
59 return (c_int)func_mkl_get_max_threads();
60}
61
62
63c_int lh_load_pardiso(const char* libname) {
64 // DEBUG
65 // if (Pardiso_handle) return 0;
66
67 // Load Pardiso library
68 if (libname) {
69 Pardiso_handle = lh_load_lib(libname);
70 } else { /* try a default library name */
71 Pardiso_handle = lh_load_lib(PARDISOLIBNAME);
72 }
73 if (!Pardiso_handle) return 1;
74
75 // Load Pardiso functions
76 func_pardiso = (pardiso_t)lh_load_sym(Pardiso_handle, "pardiso");
77 if (!func_pardiso) return 1;
78
79 func_mkl_set_interface_layer = (mkl_set_ifl_t)lh_load_sym(Pardiso_handle,
80 "MKL_Set_Interface_Layer");
81 if (!func_mkl_set_interface_layer) return 1;
82
83 func_mkl_get_max_threads = (mkl_get_mt_t)lh_load_sym(Pardiso_handle,
84 "MKL_Get_Max_Threads");
85 if (!func_mkl_get_max_threads) return 1;
86
87 return 0;
88}
89
90c_int lh_unload_pardiso() {
91
92 if (Pardiso_handle == OSQP_NULL) return 0;
93
94 return lh_unload_lib(Pardiso_handle);
95
96 /* If multiple OSQP objects are laoded, the lines below cause a crash */
97 // Pardiso_handle = OSQP_NULL;
98 // func_pardiso = OSQP_NULL;
99 // func_mkl_set_interface_layer = OSQP_NULL;
100 // func_mkl_get_max_threads = OSQP_NULL;
101
102}