33#ifndef EIGEN_PARDISOSUPPORT_H
34#define EIGEN_PARDISOSUPPORT_H
37#include "./InternalHeaderCheck.h"
41template <
typename MatrixType_>
43template <
typename MatrixType_,
int Options = Upper>
45template <
typename MatrixType_,
int Options = Upper>
49template <
typename IndexType>
50struct pardiso_run_selector {
51 static IndexType run(_MKL_DSS_HANDLE_t pt, IndexType maxfct, IndexType mnum, IndexType type, IndexType phase,
52 IndexType n,
void* a, IndexType* ia, IndexType* ja, IndexType* perm, IndexType nrhs,
53 IndexType* iparm, IndexType msglvl,
void* b,
void* x) {
55 ::pardiso(pt, &maxfct, &mnum, &type, &phase, &n, a, ia, ja, perm, &nrhs, iparm, &msglvl, b, x, &error);
60struct pardiso_run_selector<long long int> {
61 typedef long long int IndexType;
62 static IndexType run(_MKL_DSS_HANDLE_t pt, IndexType maxfct, IndexType mnum, IndexType type, IndexType phase,
63 IndexType n,
void* a, IndexType* ia, IndexType* ja, IndexType* perm, IndexType nrhs,
64 IndexType* iparm, IndexType msglvl,
void* b,
void* x) {
66 ::pardiso_64(pt, &maxfct, &mnum, &type, &phase, &n, a, ia, ja, perm, &nrhs, iparm, &msglvl, b, x, &error);
71template <
class Pardiso>
74template <
typename MatrixType_>
75struct pardiso_traits<PardisoLU<MatrixType_> > {
76 typedef MatrixType_ MatrixType;
77 typedef typename MatrixType_::Scalar Scalar;
78 typedef typename MatrixType_::RealScalar RealScalar;
79 typedef typename MatrixType_::StorageIndex StorageIndex;
82template <
typename MatrixType_,
int Options>
83struct pardiso_traits<PardisoLLT<MatrixType_, Options> > {
84 typedef MatrixType_ MatrixType;
85 typedef typename MatrixType_::Scalar Scalar;
86 typedef typename MatrixType_::RealScalar RealScalar;
87 typedef typename MatrixType_::StorageIndex StorageIndex;
90template <
typename MatrixType_,
int Options>
91struct pardiso_traits<PardisoLDLT<MatrixType_, Options> > {
92 typedef MatrixType_ MatrixType;
93 typedef typename MatrixType_::Scalar Scalar;
94 typedef typename MatrixType_::RealScalar RealScalar;
95 typedef typename MatrixType_::StorageIndex StorageIndex;
100template <
class Derived>
105 using Base::m_isInitialized;
107 typedef internal::pardiso_traits<Derived> Traits;
110 using Base::_solve_impl;
112 typedef typename Traits::MatrixType MatrixType;
113 typedef typename Traits::Scalar Scalar;
114 typedef typename Traits::RealScalar RealScalar;
115 typedef typename Traits::StorageIndex StorageIndex;
116 typedef SparseMatrix<Scalar, RowMajor, StorageIndex> SparseMatrixType;
117 typedef Matrix<Scalar, Dynamic, 1> VectorType;
118 typedef Matrix<StorageIndex, 1, MatrixType::ColsAtCompileTime> IntRowVectorType;
119 typedef Matrix<StorageIndex, MatrixType::RowsAtCompileTime, 1> IntColVectorType;
120 typedef Array<StorageIndex, 64, 1, DontAlign> ParameterType;
121 enum { ScalarIsComplex = NumTraits<Scalar>::IsComplex, ColsAtCompileTime = Dynamic, MaxColsAtCompileTime = Dynamic };
123 PardisoImpl() : m_analysisIsOk(false), m_factorizationIsOk(false) {
124 eigen_assert((
sizeof(StorageIndex) >=
sizeof(_INTEGER_t) &&
sizeof(StorageIndex) <= 8) &&
125 "Non-supported index type");
128 m_isInitialized =
false;
131 ~PardisoImpl() { pardisoRelease(); }
133 inline Index cols()
const {
return m_size; }
134 inline Index rows()
const {
return m_size; }
142 eigen_assert(m_isInitialized &&
"Decomposition is not initialized.");
149 ParameterType& pardisoParameterArray() {
return m_iparm; }
157 Derived& analyzePattern(
const MatrixType& matrix);
166 Derived& factorize(
const MatrixType& matrix);
168 Derived& compute(
const MatrixType& matrix);
170 template <
typename Rhs,
typename Dest>
171 void _solve_impl(
const MatrixBase<Rhs>& b, MatrixBase<Dest>& dest)
const;
174 void pardisoRelease() {
177 internal::pardiso_run_selector<StorageIndex>::run(m_pt, 1, 1, m_type, -1,
178 internal::convert_index<StorageIndex>(m_size), 0, 0, 0,
179 m_perm.data(), 0, m_iparm.data(), m_msglvl,
nullptr,
nullptr);
180 m_isInitialized =
false;
184 void pardisoInit(
int type) {
186 bool symmetric = numext::abs(m_type) < 10;
197 m_iparm[10] = symmetric ? 0 : 1;
199 m_iparm[12] = symmetric ? 0 : 1;
211 m_iparm[27] = (
sizeof(RealScalar) == 4) ? 1 : 0;
216 memset(m_pt, 0,
sizeof(m_pt));
222 void manageErrorCode(Index error)
const {
236 mutable SparseMatrixType m_matrix;
238 bool m_analysisIsOk, m_factorizationIsOk;
239 StorageIndex m_type, m_msglvl;
240 mutable void* m_pt[64];
241 mutable ParameterType m_iparm;
242 mutable IntColVectorType m_perm;
246template <
class Derived>
247Derived& PardisoImpl<Derived>::compute(
const MatrixType& a) {
249 eigen_assert(a.rows() == a.cols());
252 m_perm.setZero(m_size);
253 derived().getMatrix(a);
256 error = internal::pardiso_run_selector<StorageIndex>::run(
257 m_pt, 1, 1, m_type, 12, internal::convert_index<StorageIndex>(m_size), m_matrix.valuePtr(),
258 m_matrix.outerIndexPtr(), m_matrix.innerIndexPtr(), m_perm.data(), 0, m_iparm.data(), m_msglvl,
nullptr,
nullptr);
259 manageErrorCode(error);
262 m_isInitialized =
true;
266template <
class Derived>
267Derived& PardisoImpl<Derived>::analyzePattern(
const MatrixType& a) {
269 eigen_assert(m_size == a.cols());
272 m_perm.setZero(m_size);
273 derived().getMatrix(a);
276 error = internal::pardiso_run_selector<StorageIndex>::run(
277 m_pt, 1, 1, m_type, 11, internal::convert_index<StorageIndex>(m_size), m_matrix.valuePtr(),
278 m_matrix.outerIndexPtr(), m_matrix.innerIndexPtr(), m_perm.data(), 0, m_iparm.data(), m_msglvl,
nullptr,
nullptr);
280 manageErrorCode(error);
282 m_factorizationIsOk =
false;
283 m_isInitialized =
true;
287template <
class Derived>
288Derived& PardisoImpl<Derived>::factorize(
const MatrixType& a) {
289 eigen_assert(m_analysisIsOk &&
"You must first call analyzePattern()");
290 eigen_assert(m_size == a.rows() && m_size == a.cols());
292 derived().getMatrix(a);
295 error = internal::pardiso_run_selector<StorageIndex>::run(
296 m_pt, 1, 1, m_type, 22, internal::convert_index<StorageIndex>(m_size), m_matrix.valuePtr(),
297 m_matrix.outerIndexPtr(), m_matrix.innerIndexPtr(), m_perm.data(), 0, m_iparm.data(), m_msglvl,
nullptr,
nullptr);
299 manageErrorCode(error);
304template <
class Derived>
305template <
typename BDerived,
typename XDerived>
313 Index nrhs = Index(b.cols());
314 eigen_assert(m_size == b.rows());
316 "Row-major right hand sides are not supported");
318 "Row-major matrices of unknowns are not supported");
319 eigen_assert(((nrhs == 1) || b.outerStride() == b.rows()));
330 Scalar* rhs_ptr =
const_cast<Scalar*
>(b.derived().data());
334 if (rhs_ptr == x.derived().data()) {
336 rhs_ptr = tmp.data();
340 error = internal::pardiso_run_selector<StorageIndex>::run(
341 m_pt, 1, 1, m_type, 33, internal::convert_index<StorageIndex>(m_size), m_matrix.valuePtr(),
342 m_matrix.outerIndexPtr(), m_matrix.innerIndexPtr(), m_perm.data(), internal::convert_index<StorageIndex>(nrhs),
343 m_iparm.data(), m_msglvl, rhs_ptr, x.derived().data());
345 manageErrorCode(error);
365template <
typename MatrixType>
366class PardisoLU :
public PardisoImpl<PardisoLU<MatrixType> > {
368 typedef PardisoImpl<PardisoLU> Base;
369 using Base::m_matrix;
370 using Base::pardisoInit;
371 friend class PardisoImpl<PardisoLU<MatrixType> >;
374 typedef typename Base::Scalar Scalar;
375 typedef typename Base::RealScalar RealScalar;
380 PardisoLU() : Base() { pardisoInit(Base::ScalarIsComplex ? 13 : 11); }
382 explicit PardisoLU(
const MatrixType& matrix) : Base() {
383 pardisoInit(Base::ScalarIsComplex ? 13 : 11);
388 void getMatrix(
const MatrixType& matrix) {
390 m_matrix.makeCompressed();
413template <
typename MatrixType,
int UpLo_>
414class PardisoLLT :
public PardisoImpl<PardisoLLT<MatrixType, UpLo_> > {
416 typedef PardisoImpl<PardisoLLT<MatrixType, UpLo_> > Base;
417 using Base::m_matrix;
418 using Base::pardisoInit;
419 friend class PardisoImpl<PardisoLLT<MatrixType, UpLo_> >;
422 typedef typename Base::Scalar Scalar;
423 typedef typename Base::RealScalar RealScalar;
424 typedef typename Base::StorageIndex StorageIndex;
425 enum { UpLo = UpLo_ };
428 PardisoLLT() : Base() { pardisoInit(Base::ScalarIsComplex ? 4 : 2); }
430 explicit PardisoLLT(
const MatrixType& matrix) : Base() {
431 pardisoInit(Base::ScalarIsComplex ? 4 : 2);
436 void getMatrix(
const MatrixType& matrix) {
439 m_matrix.
resize(matrix.rows(), matrix.cols());
440 m_matrix.template selfadjointView<Upper>() = matrix.template selfadjointView<UpLo>().twistedBy(p_null);
441 m_matrix.makeCompressed();
467template <
typename MatrixType,
int Options>
468class PardisoLDLT :
public PardisoImpl<PardisoLDLT<MatrixType, Options> > {
470 typedef PardisoImpl<PardisoLDLT<MatrixType, Options> > Base;
471 using Base::m_matrix;
472 using Base::pardisoInit;
473 friend class PardisoImpl<PardisoLDLT<MatrixType, Options> >;
476 typedef typename Base::Scalar Scalar;
477 typedef typename Base::RealScalar RealScalar;
478 typedef typename Base::StorageIndex StorageIndex;
482 PardisoLDLT() : Base() { pardisoInit(Base::ScalarIsComplex ? (
bool(Options &
Symmetric) ? 6 : -4) : -2); }
484 explicit PardisoLDLT(
const MatrixType& matrix) : Base() {
485 pardisoInit(Base::ScalarIsComplex ? (
bool(Options &
Symmetric) ? 6 : -4) : -2);
489 void getMatrix(
const MatrixType& matrix) {
492 m_matrix.
resize(matrix.rows(), matrix.cols());
493 m_matrix.template selfadjointView<Upper>() = matrix.template selfadjointView<UpLo>().twistedBy(p_null);
494 m_matrix.makeCompressed();
@ Flags
Definition DenseBase.h:162
Base class for all dense matrices, vectors, and expressions.
Definition MatrixBase.h:53
The matrix class, also used for vectors and row-vectors.
Definition Matrix.h:188
A sparse direct Cholesky (LDLT) factorization and solver based on the PARDISO library.
Definition PardisoSupport.h:468
A sparse direct Cholesky (LLT) factorization and solver based on the PARDISO library.
Definition PardisoSupport.h:414
A sparse direct LU factorization and solver based on the PARDISO library.
Definition PardisoSupport.h:366
void resize(Index newSize)
Definition PermutationMatrix.h:165
Permutation matrix.
Definition PermutationMatrix.h:346
A base class for sparse solvers.
Definition SparseSolverBase.h:68
SparseSolverBase()=default
Solve< Derived, Rhs > solve(const MatrixBase< Rhs > &b) const
Definition SparseSolverBase.h:88
ComputationInfo
Definition Constants.h:455
@ Symmetric
Definition Constants.h:230
@ Lower
Definition Constants.h:212
@ Upper
Definition Constants.h:214
@ NumericalIssue
Definition Constants.h:459
@ InvalidInput
Definition Constants.h:464
@ Success
Definition Constants.h:457
constexpr unsigned int RowMajorBit
Definition Constants.h:71