#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; }