8#include <kernel/backend.hpp>
9#include <kernel/solver/direct_sparse_solver.hpp>
15#include <mkl_cluster_sparse_solver.h>
24 static_assert(
sizeof(MKLDSS_IT) ==
sizeof(MKL_INT),
"DirectSparseSolver: MKL-DSS: index type size mismatch!");
40 MKL_INT css_iparm[64];
50 MKL_INT num_global_dofs, dof_offset, num_owned_dofs, num_owned_nzes;
52 std::int64_t peak_mem_sym, peak_mem_num;
54 std::vector<MKL_INT> row_ptr, col_idx;
56 std::vector<double> mat_val, rhs_val, sol_val;
58 explicit MKLDSS_Core(
const Dist::Comm& comm, Index num_global_dofs_, Index dof_offset_,
59 Index num_owned_dofs_, Index num_owned_nzes_, Index DOXY(num_global_nzes_)) :
61 mpi_comm(MPI_Comm_c2f(comm.mpi_comm())),
67 num_global_dofs(static_cast<MKL_INT>(num_global_dofs_)),
68 dof_offset(static_cast<MKL_INT>(dof_offset_)),
69 num_owned_dofs(static_cast<MKL_INT>(num_owned_dofs_)),
70 num_owned_nzes(static_cast<MKL_INT>(num_owned_nzes_)),
75 memset(css_handle, 0,
sizeof(
void*)*64);
76 memset(css_iparm, 0,
sizeof(MKL_INT)*64);
97 css_iparm[40] = dof_offset;
98 css_iparm[41] = dof_offset + num_owned_dofs - 1;
103 MKL_INT opt = MKL_DSS_TERM_LVL_ERROR + MKL_DSS_ZERO_BASED_INDEXING;
105 opt += MKL_DSS_MSG_LVL_WARNING;
107 MKL_INT ret = ::dss_create(dss_handle, opt);
111 case MKL_DSS_SUCCESS:
113 case MKL_DSS_OUT_OF_MEMORY:
114 throw DirectSparseSolverException(
"MKL-DSS",
"out of memory");
116 throw DirectSparseSolverException(
"MKL-DSS",
"unknown error");
121 row_ptr.resize(std::size_t(num_owned_dofs+1), 0u);
122 col_idx.resize(std::size_t(num_owned_nzes), 0u);
123 mat_val.resize(std::size_t(num_owned_nzes), 0.0);
124 rhs_val.resize(std::size_t(num_owned_dofs), 0.0);
125 sol_val.resize(std::size_t(num_owned_dofs), 0.0);
138 cluster_sparse_solver(
159 MKL_INT opt = MKL_DSS_TERM_LVL_ERROR;
161 opt += MKL_DSS_MSG_LVL_WARNING;
163 ::dss_delete(dss_handle, opt);
164 dss_handle =
nullptr;
179 cluster_sparse_solver(
204 throw DirectSparseSolverException(
"MKL-DSS",
"out of memory");
207 throw DirectSparseSolverException(
"MKL-DSS",
"unknown symbolic factorization error");
211 peak_mem_sym = css_iparm[14] * 1024ll;
212 peak_mem_num = css_iparm[16] * 1024ll;
215 MKL_INT opt = MKL_DSS_NON_SYMMETRIC;
216 MKL_INT ret = ::dss_define_structure(dss_handle, opt, row_ptr.data(), num_owned_dofs,
217 num_owned_dofs, col_idx.data(), num_owned_nzes);
221 case MKL_DSS_SUCCESS:
223 case MKL_DSS_OUT_OF_MEMORY:
224 throw DirectSparseSolverException(
"MKL-DSS",
"out of memory");
225 case MKL_DSS_STRUCTURE_ERR:
226 throw DirectSparseSolverException(
"MKL-DSS",
"invalid matrix structure");
228 throw DirectSparseSolverException(
"MKL-DSS",
"unknown error");
232 opt = MKL_DSS_AUTO_ORDER;
233 ret = ::dss_reorder(dss_handle, opt,
nullptr);
237 case MKL_DSS_SUCCESS:
239 case MKL_DSS_OUT_OF_MEMORY:
240 throw DirectSparseSolverException(
"MKL-DSS",
"out of memory");
242 throw DirectSparseSolverException(
"MKL-DSS",
"unknown error");
247 double stats[3] = {0.0, 0.0, 0.0};
248 dss_statistics(dss_handle, opt,
"Peakmem,Factormem,Solvemem", stats);
249 peak_mem_sym = std::int64_t(stats[0] * 1024.0);
250 peak_mem_num = std::int64_t((stats[1]+stats[2]) * 1024.0);
265 cluster_sparse_solver(
290 throw DirectSparseSolverException(
"MKL-DSS",
"out of memory");
293 throw DirectSparseSolverException(
"MKL-DSS",
"zero pivot");
296 throw DirectSparseSolverException(
"MKL-DSS",
"unknown numeric factorization error");
299 MKL_INT opt = MKL_DSS_INDEFINITE;
300 MKL_INT ret = ::dss_factor_real(dss_handle, opt, mat_val.data());
304 case MKL_DSS_SUCCESS:
306 case MKL_DSS_OUT_OF_MEMORY:
307 throw DirectSparseSolverException(
"MKL-DSS",
"out of memory");
308 case MKL_DSS_ZERO_PIVOT:
309 throw DirectSparseSolverException(
"MKL-DSS",
"zero pivot");
311 throw DirectSparseSolverException(
"MKL-DSS",
"unknown error");
326 cluster_sparse_solver(
351 throw DirectSparseSolverException(
"MKL-DSS",
"out of memory");
354 throw DirectSparseSolverException(
"MKL-DSS",
"zero pivot");
357 throw DirectSparseSolverException(
"MKL-DSS",
"unknown solve error");
361 MKL_INT ret = ::dss_solve_real(dss_handle, opt, rhs_val.data(), num_rhs, sol_val.data());
364 case MKL_DSS_SUCCESS:
367 throw DirectSparseSolverException(
"MKL-DSS",
"unknown solve error");
372 std::int64_t get_peak_mem()
const
374 return Math::max(peak_mem_num, peak_mem_sym);
378 void* create_mkldss_core(
const Dist::Comm* comm, Index num_global_dofs, Index dof_offset,
379 Index num_owned_dofs, Index num_owned_nzes, Index num_global_nzes)
381 return new MKLDSS_Core(*comm, num_global_dofs, dof_offset, num_owned_dofs, num_owned_nzes, num_global_nzes);
384 void destroy_mkldss_core(
void* core)
387 delete reinterpret_cast<MKLDSS_Core*
>(core);
390 MKLDSS_IT* get_mkldss_row_ptr(
void* core)
393 return reinterpret_cast<MKLDSS_Core*
>(core)->row_ptr.data();
396 MKLDSS_IT* get_mkldss_col_idx(
void* core)
399 return reinterpret_cast<MKLDSS_Core*
>(core)->col_idx.data();
402 MKLDSS_DT* get_mkldss_mat_val(
void* core)
405 return reinterpret_cast<MKLDSS_Core*
>(core)->mat_val.data();
408 MKLDSS_DT* get_mkldss_rhs_val(
void* core)
411 return reinterpret_cast<MKLDSS_Core*
>(core)->rhs_val.data();
414 MKLDSS_DT* get_mkldss_sol_val(
void* core)
417 return reinterpret_cast<MKLDSS_Core*
>(core)->sol_val.data();
420 void init_mkldss_symbolic(
void* core)
423 reinterpret_cast<MKLDSS_Core*
>(core)->init_symbolic();
426 void init_mkldss_numeric(
void* core)
429 reinterpret_cast<MKLDSS_Core*
>(core)->init_numeric();
432 void solve_mkldss(
void* core)
435 reinterpret_cast<MKLDSS_Core*
>(core)->
solve();
438 std::int64_t get_peak_mem_mkldss(
void* core)
441 return reinterpret_cast<MKLDSS_Core*
>(core)->get_peak_mem();
449void feat_direct_sparse_solver_mkldss_dummy()
#define XASSERT(expr)
Assertion macro definition.
Status solve(SolverBase< Vector_ > &solver, Vector_ &vec_sol, const Vector_ &vec_rhs, const Matrix_ &matrix, const Filter_ &filter)
Solve linear system with initial solution guess.