pardiso_loader.c 3.1 KB

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