blob: f120e47210d835710dd647621a280994370ca6dd [file] [log] [blame]
#include "lib_handler.h"
#include "pardiso_loader.h"
#include "glob_opts.h"
#include "constants.h"
#ifdef IS_WINDOWS
#define PARDISOLIBNAME "mkl_rt." SHAREDLIBEXT
#else
#define PARDISOLIBNAME "libmkl_rt." SHAREDLIBEXT
#endif
typedef void (*voidfun)(void);
voidfun lh_load_sym (soHandle_t h, const char *symName);
// Interfaces for Pardiso functions
typedef void (*pardiso_t)(void**, const c_int*, const c_int*, const c_int*,
const c_int*, const c_int*, const c_float*,
const c_int*, const c_int*, c_int*,
const c_int*, c_int*, const c_int*, c_float*,
c_float*, c_int*);
typedef int (*mkl_set_ifl_t)(int);
typedef int (*mkl_get_mt_t)();
// Handlers are static variables
static soHandle_t Pardiso_handle = OSQP_NULL;
static pardiso_t func_pardiso = OSQP_NULL;
static mkl_set_ifl_t func_mkl_set_interface_layer = OSQP_NULL;
static mkl_get_mt_t func_mkl_get_max_threads = OSQP_NULL;
// Wrappers for loaded Pardiso function handlers
void pardiso(void** pt, const c_int* maxfct, const c_int* mnum,
const c_int* mtype, const c_int* phase, const c_int* n,
const c_float* a, const c_int* ia, const c_int* ja,
c_int* perm, const c_int* nrhs, c_int* iparm,
const c_int* msglvl, c_float* b, c_float* x,
c_int* error) {
if(func_pardiso){
// Call function pardiso only if it has been initialized
func_pardiso(pt, maxfct, mnum, mtype, phase, n, a, ia, ja,
perm, nrhs, iparm, msglvl, b, x, error);
}
else
{
#ifdef PRINTING
c_eprint("Pardiso not loaded correctly");
#endif
}
}
c_int mkl_set_interface_layer(c_int code) {
return (c_int)func_mkl_set_interface_layer((int)code);
}
c_int mkl_get_max_threads() {
return (c_int)func_mkl_get_max_threads();
}
c_int lh_load_pardiso(const char* libname) {
// DEBUG
// if (Pardiso_handle) return 0;
// Load Pardiso library
if (libname) {
Pardiso_handle = lh_load_lib(libname);
} else { /* try a default library name */
Pardiso_handle = lh_load_lib(PARDISOLIBNAME);
}
if (!Pardiso_handle) return 1;
// Load Pardiso functions
func_pardiso = (pardiso_t)lh_load_sym(Pardiso_handle, "pardiso");
if (!func_pardiso) return 1;
func_mkl_set_interface_layer = (mkl_set_ifl_t)lh_load_sym(Pardiso_handle,
"MKL_Set_Interface_Layer");
if (!func_mkl_set_interface_layer) return 1;
func_mkl_get_max_threads = (mkl_get_mt_t)lh_load_sym(Pardiso_handle,
"MKL_Get_Max_Threads");
if (!func_mkl_get_max_threads) return 1;
return 0;
}
c_int lh_unload_pardiso() {
if (Pardiso_handle == OSQP_NULL) return 0;
return lh_unload_lib(Pardiso_handle);
/* If multiple OSQP objects are laoded, the lines below cause a crash */
// Pardiso_handle = OSQP_NULL;
// func_pardiso = OSQP_NULL;
// func_mkl_set_interface_layer = OSQP_NULL;
// func_mkl_get_max_threads = OSQP_NULL;
}