9#include <kernel/solver/mkl_dss.hpp>
20 _system_matrix(system_matrix),
21 _mkl_dss_handle(nullptr)
29 void MKLDSS::init_symbolic()
31 BaseClass::init_symbolic();
32 XASSERT(_mkl_dss_handle ==
nullptr);
36 MKL_INT neq =
static_cast<MKL_INT
>(_system_matrix.rows());
37 MKL_INT nze =
static_cast<MKL_INT
>(_system_matrix.used_elements());
40 opt = MKL_DSS_TERM_LVL_ERROR + MKL_DSS_ZERO_BASED_INDEXING;
42 opt += MKL_DSS_MSG_LVL_WARNING;
44 ret = ::dss_create(_mkl_dss_handle, opt);
50 case MKL_DSS_OUT_OF_MEMORY:
51 throw SolverException(
"MKL DSS: out of memory");
53 throw SolverException(
"MKL DSS: unknown error");
57 std::vector<MKL_INT> row_ptr_v, col_idx_v;
58 const Index* a_row_ptr = _system_matrix.row_ptr();
59 const Index* a_col_idx = _system_matrix.col_ind();
60 const MKL_INT* row_ptr =
nullptr;
61 const MKL_INT* col_idx =
nullptr;
62 if constexpr(
sizeof(
Index) ==
sizeof(MKL_INT))
64 row_ptr =
reinterpret_cast<const MKL_INT*
>(a_row_ptr);
65 col_idx =
reinterpret_cast<const MKL_INT*
>(a_col_idx);
69 row_ptr_v.resize(std::size_t(neq+1u));
70 col_idx_v.resize(std::size_t(nze));
71 for(Index i(0); i <=
Index(neq); ++i)
72 row_ptr_v[i] =
static_cast<MKL_INT
>(a_row_ptr[i]);
73 for(Index i(0); i <
Index(nze); ++i)
74 col_idx_v[i] =
static_cast<MKL_INT
>(a_col_idx[i]);
75 row_ptr = row_ptr_v.data();
76 col_idx = col_idx_v.data();
81 for(Index i(0); i <
Index(neq); ++i)
83 bool have_diag =
false;
84 for(Index j =
Index(row_ptr[i]); j <
Index(row_ptr[i+1u]); ++j)
86 have_diag = have_diag || (
Index(col_idx[j]) == i);
87 if((j+1u <
Index(row_ptr[i+1u])) && (col_idx[j+1u] <= col_idx[j]))
88 throw InvalidMatrixStructureException(
"MKL DSS: non-ascending column indices detected");
91 throw InvalidMatrixStructureException(
"MKL DSS: missing main diagonal entry");
96 opt = MKL_DSS_NON_SYMMETRIC;
97 ret = ::dss_define_structure(_mkl_dss_handle, opt, row_ptr, neq, neq, col_idx, nze);
101 case MKL_DSS_SUCCESS:
103 case MKL_DSS_OUT_OF_MEMORY:
104 throw SolverException(
"MKL DSS: out of memory");
105 case MKL_DSS_STRUCTURE_ERR:
106 throw InvalidMatrixStructureException(
"MKL DSS: invalid matrix structure");
108 throw SolverException(
"MKL DSS: unknown error");
112 opt = MKL_DSS_AUTO_ORDER;
113 ret = ::dss_reorder(_mkl_dss_handle, opt,
nullptr);
117 case MKL_DSS_SUCCESS:
119 case MKL_DSS_OUT_OF_MEMORY:
120 throw SolverException(
"MKL DSS: out of memory");
122 throw SolverException(
"MKL DSS: unknown error");
126 void MKLDSS::done_symbolic()
130 MKL_INT opt = MKL_DSS_TERM_LVL_ERROR;
132 opt += MKL_DSS_MSG_LVL_WARNING;
134 ::dss_delete(_mkl_dss_handle, opt);
135 _mkl_dss_handle =
nullptr;
137 BaseClass::done_symbolic();
140 void MKLDSS::init_numeric()
142 BaseClass::init_numeric();
143 XASSERT(_mkl_dss_handle !=
nullptr);
146 MKL_INT opt = MKL_DSS_INDEFINITE;
148 ret = ::dss_factor_real(_mkl_dss_handle, opt, _system_matrix.val());
152 case MKL_DSS_SUCCESS:
154 case MKL_DSS_OUT_OF_MEMORY:
155 throw SolverException(
"MKL DSS: out of memory");
156 case MKL_DSS_ZERO_PIVOT:
157 throw SingularMatrixException(
"MKL DSS: zero pivot encountered");
159 throw SolverException(
"MKL DSS: unknown error");
163 void MKLDSS::done_numeric()
166 BaseClass::done_numeric();
169 Status MKLDSS::apply(VectorType& vec_sol,
const VectorType& vec_rhs)
173 MKL_INT ret = ::dss_solve_real(_mkl_dss_handle, opt, vec_rhs.elements(), nrhs, vec_sol.elements());
174 return (ret == MKL_DSS_SUCCESS ? Status::success : Status::aborted);
180void dummy_function_mkldss() {}
#define XASSERT(expr)
Assertion macro definition.
MKLDSS(const MatrixType &system_matrix)
Constructor.
Status
Solver status return codes enumeration.
std::uint64_t Index
Index data type.