11#ifndef EIGEN_PASTIXSUPPORT_H
12#define EIGEN_PASTIXSUPPORT_H
15#include "./InternalHeaderCheck.h"
20#define PASTIX_COMPLEX COMPLEX
21#define PASTIX_DCOMPLEX DCOMPLEX
23#define PASTIX_COMPLEX std::complex<float>
24#define PASTIX_DCOMPLEX std::complex<double>
35template <
typename MatrixType_,
bool IsStrSym = false>
37template <
typename MatrixType_,
int Options>
39template <
typename MatrixType_,
int Options>
44template <
class Pastix>
47template <
typename MatrixType_>
48struct pastix_traits<PastixLU<MatrixType_> > {
49 typedef MatrixType_ MatrixType;
50 typedef typename MatrixType_::Scalar Scalar;
51 typedef typename MatrixType_::RealScalar RealScalar;
52 typedef typename MatrixType_::StorageIndex StorageIndex;
55template <
typename MatrixType_,
int Options>
56struct pastix_traits<PastixLLT<MatrixType_, Options> > {
57 typedef MatrixType_ MatrixType;
58 typedef typename MatrixType_::Scalar Scalar;
59 typedef typename MatrixType_::RealScalar RealScalar;
60 typedef typename MatrixType_::StorageIndex StorageIndex;
63template <
typename MatrixType_,
int Options>
64struct pastix_traits<PastixLDLT<MatrixType_, Options> > {
65 typedef MatrixType_ MatrixType;
66 typedef typename MatrixType_::Scalar Scalar;
67 typedef typename MatrixType_::RealScalar RealScalar;
68 typedef typename MatrixType_::StorageIndex StorageIndex;
71inline void eigen_pastix(pastix_data_t **pastix_data,
int pastix_comm,
int n,
int *ptr,
int *idx,
float *vals,
72 int *perm,
int *invp,
float *x,
int nbrhs,
int *iparm,
double *dparm) {
82 s_pastix(pastix_data, pastix_comm, n, ptr, idx, vals, perm, invp, x, nbrhs, iparm, dparm);
85inline void eigen_pastix(pastix_data_t **pastix_data,
int pastix_comm,
int n,
int *ptr,
int *idx,
double *vals,
86 int *perm,
int *invp,
double *x,
int nbrhs,
int *iparm,
double *dparm) {
96 d_pastix(pastix_data, pastix_comm, n, ptr, idx, vals, perm, invp, x, nbrhs, iparm, dparm);
99inline void eigen_pastix(pastix_data_t **pastix_data,
int pastix_comm,
int n,
int *ptr,
int *idx,
100 std::complex<float> *vals,
int *perm,
int *invp, std::complex<float> *x,
int nbrhs,
int *iparm,
111 c_pastix(pastix_data, pastix_comm, n, ptr, idx,
reinterpret_cast<PASTIX_COMPLEX *
>(vals), perm, invp,
112 reinterpret_cast<PASTIX_COMPLEX *
>(x), nbrhs, iparm, dparm);
115inline void eigen_pastix(pastix_data_t **pastix_data,
int pastix_comm,
int n,
int *ptr,
int *idx,
116 std::complex<double> *vals,
int *perm,
int *invp, std::complex<double> *x,
int nbrhs,
117 int *iparm,
double *dparm) {
127 z_pastix(pastix_data, pastix_comm, n, ptr, idx,
reinterpret_cast<PASTIX_DCOMPLEX *
>(vals), perm, invp,
128 reinterpret_cast<PASTIX_DCOMPLEX *
>(x), nbrhs, iparm, dparm);
132template <
typename MatrixType>
133void c_to_fortran_numbering(MatrixType &mat) {
134 if (!(mat.outerIndexPtr()[0])) {
136 for (i = 0; i <= mat.rows(); ++i) ++mat.outerIndexPtr()[i];
137 for (i = 0; i < mat.nonZeros(); ++i) ++mat.innerIndexPtr()[i];
144template <
class Derived>
149 using Base::m_isInitialized;
152 using Base::_solve_impl;
154 typedef typename internal::pastix_traits<Derived>::MatrixType MatrixType_;
155 typedef MatrixType_ MatrixType;
156 typedef typename MatrixType::Scalar Scalar;
157 typedef typename MatrixType::RealScalar RealScalar;
158 typedef typename MatrixType::StorageIndex StorageIndex;
159 typedef Matrix<Scalar, Dynamic, 1> Vector;
160 typedef SparseMatrix<Scalar, ColMajor> ColSpMatrix;
161 enum { ColsAtCompileTime = MatrixType::ColsAtCompileTime, MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime };
164 PastixBase() : m_initisOk(false), m_analysisIsOk(false), m_factorizationIsOk(false), m_pastixdata(0), m_size(0) {
168 ~PastixBase() { clean(); }
170 template <
typename Rhs,
typename Dest>
171 bool _solve_impl(
const MatrixBase<Rhs> &b, MatrixBase<Dest> &x)
const;
178 Array<StorageIndex, IPARM_SIZE, 1> &iparm() {
return m_iparm; }
184 int &iparm(
int idxparam) {
return m_iparm(idxparam); }
190 Array<double, DPARM_SIZE, 1> &dparm() {
return m_dparm; }
195 double &dparm(
int idxparam) {
return m_dparm(idxparam); }
197 inline Index cols()
const {
return m_size; }
198 inline Index rows()
const {
return m_size; }
209 eigen_assert(m_isInitialized &&
"Decomposition is not initialized.");
218 void analyzePattern(ColSpMatrix &mat);
221 void factorize(ColSpMatrix &mat);
225 eigen_assert(m_initisOk &&
"The Pastix structure should be allocated first");
226 m_iparm(IPARM_START_TASK) = API_TASK_CLEAN;
227 m_iparm(IPARM_END_TASK) = API_TASK_CLEAN;
228 internal::eigen_pastix(&m_pastixdata, MPI_COMM_WORLD, 0, 0, 0, (Scalar *)0, m_perm.data(), m_invp.data(), 0, 0,
229 m_iparm.data(), m_dparm.data());
232 void compute(ColSpMatrix &mat);
236 int m_factorizationIsOk;
238 mutable pastix_data_t *m_pastixdata;
240 mutable Array<int, IPARM_SIZE, 1> m_iparm;
241 mutable Array<double, DPARM_SIZE, 1> m_dparm;
242 mutable Matrix<StorageIndex, Dynamic, 1> m_perm;
243 mutable Matrix<StorageIndex, Dynamic, 1> m_invp;
251template <
class Derived>
252void PastixBase<Derived>::init() {
254 m_iparm.setZero(IPARM_SIZE);
255 m_dparm.setZero(DPARM_SIZE);
257 m_iparm(IPARM_MODIFY_PARAMETER) = API_NO;
258 pastix(&m_pastixdata, MPI_COMM_WORLD, 0, 0, 0, 0, 0, 0, 0, 1, m_iparm.data(), m_dparm.data());
260 m_iparm[IPARM_MATRIX_VERIFICATION] = API_NO;
261 m_iparm[IPARM_VERBOSE] = API_VERBOSE_NOT;
262 m_iparm[IPARM_ORDERING] = API_ORDER_SCOTCH;
263 m_iparm[IPARM_INCOMPLETE] = API_NO;
264 m_iparm[IPARM_OOC_LIMIT] = 2000;
265 m_iparm[IPARM_RHS_MAKING] = API_RHS_B;
266 m_iparm(IPARM_MATRIX_VERIFICATION) = API_NO;
268 m_iparm(IPARM_START_TASK) = API_TASK_INIT;
269 m_iparm(IPARM_END_TASK) = API_TASK_INIT;
270 internal::eigen_pastix(&m_pastixdata, MPI_COMM_WORLD, 0, 0, 0, (Scalar *)0, 0, 0, 0, 0, m_iparm.data(),
274 if (m_iparm(IPARM_ERROR_NUMBER)) {
283template <
class Derived>
284void PastixBase<Derived>::compute(ColSpMatrix &mat) {
285 eigen_assert(mat.rows() == mat.cols() &&
"The input matrix should be squared");
290 m_iparm(IPARM_MATRIX_VERIFICATION) = API_NO;
293template <
class Derived>
294void PastixBase<Derived>::analyzePattern(ColSpMatrix &mat) {
295 eigen_assert(m_initisOk &&
"The initialization of PaSTiX failed");
298 if (m_size > 0) clean();
300 m_size = internal::convert_index<int>(mat.rows());
301 m_perm.resize(m_size);
302 m_invp.resize(m_size);
304 m_iparm(IPARM_START_TASK) = API_TASK_ORDERING;
305 m_iparm(IPARM_END_TASK) = API_TASK_ANALYSE;
306 internal::eigen_pastix(&m_pastixdata, MPI_COMM_WORLD, m_size, mat.outerIndexPtr(), mat.innerIndexPtr(),
307 mat.valuePtr(), m_perm.data(), m_invp.data(), 0, 0, m_iparm.data(), m_dparm.data());
310 if (m_iparm(IPARM_ERROR_NUMBER)) {
312 m_analysisIsOk =
false;
315 m_analysisIsOk =
true;
319template <
class Derived>
320void PastixBase<Derived>::factorize(ColSpMatrix &mat) {
321 eigen_assert(m_analysisIsOk &&
"The analysis phase should be called before the factorization phase");
322 m_iparm(IPARM_START_TASK) = API_TASK_NUMFACT;
323 m_iparm(IPARM_END_TASK) = API_TASK_NUMFACT;
324 m_size = internal::convert_index<int>(mat.rows());
326 internal::eigen_pastix(&m_pastixdata, MPI_COMM_WORLD, m_size, mat.outerIndexPtr(), mat.innerIndexPtr(),
327 mat.valuePtr(), m_perm.data(), m_invp.data(), 0, 0, m_iparm.data(), m_dparm.data());
330 if (m_iparm(IPARM_ERROR_NUMBER)) {
332 m_factorizationIsOk =
false;
333 m_isInitialized =
false;
336 m_factorizationIsOk =
true;
337 m_isInitialized =
true;
342template <
typename Base>
343template <
typename Rhs,
typename Dest>
345 eigen_assert(m_isInitialized &&
"The matrix should be factorized first");
346 EIGEN_STATIC_ASSERT((Dest::Flags &
RowMajorBit) == 0, THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES);
351 for (
int i = 0; i < b.cols(); i++) {
352 m_iparm[IPARM_START_TASK] = API_TASK_SOLVE;
353 m_iparm[IPARM_END_TASK] = API_TASK_REFINE;
355 internal::eigen_pastix(&m_pastixdata, MPI_COMM_WORLD, internal::convert_index<int>(x.rows()), 0, 0, 0,
356 m_perm.data(), m_invp.data(), &x(0, i), rhs, m_iparm.data(), m_dparm.data());
362 return m_iparm(IPARM_ERROR_NUMBER) == 0;
386template <
typename MatrixType_,
bool IsStrSym>
387class PastixLU :
public PastixBase<PastixLU<MatrixType_> > {
389 typedef MatrixType_ MatrixType;
390 typedef PastixBase<PastixLU<MatrixType> > Base;
391 typedef typename Base::ColSpMatrix ColSpMatrix;
392 typedef typename MatrixType::StorageIndex StorageIndex;
395 PastixLU() : Base() { init(); }
397 explicit PastixLU(
const MatrixType &matrix) : Base() {
407 m_structureIsUptodate =
false;
409 grabMatrix(matrix, temp);
418 m_structureIsUptodate =
false;
420 grabMatrix(matrix, temp);
421 Base::analyzePattern(temp);
431 grabMatrix(matrix, temp);
432 Base::factorize(temp);
437 m_structureIsUptodate =
false;
438 m_iparm(IPARM_SYM) = API_SYM_NO;
439 m_iparm(IPARM_FACTORIZATION) = API_FACT_LU;
442 void grabMatrix(
const MatrixType &matrix, ColSpMatrix &out) {
443 EIGEN_IF_CONSTEXPR (IsStrSym)
446 if (!m_structureIsUptodate) {
448 m_transposedStructure = matrix.transpose();
451 for (Index j = 0; j < m_transposedStructure.
outerSize(); ++j)
452 for (
typename ColSpMatrix::InnerIterator it(m_transposedStructure, j); it; ++it) it.valueRef() = 0.0;
454 m_structureIsUptodate =
true;
457 out = m_transposedStructure + matrix;
459 internal::c_to_fortran_numbering(out);
465 ColSpMatrix m_transposedStructure;
466 bool m_structureIsUptodate;
486template <
typename MatrixType_,
int UpLo_>
487class PastixLLT :
public PastixBase<PastixLLT<MatrixType_, UpLo_> > {
489 typedef MatrixType_ MatrixType;
490 typedef PastixBase<PastixLLT<MatrixType, UpLo_> > Base;
491 typedef typename Base::ColSpMatrix ColSpMatrix;
494 enum { UpLo = UpLo_ };
495 PastixLLT() : Base() { init(); }
497 explicit PastixLLT(
const MatrixType &matrix) : Base() {
507 grabMatrix(matrix, temp);
517 grabMatrix(matrix, temp);
518 Base::analyzePattern(temp);
525 grabMatrix(matrix, temp);
526 Base::factorize(temp);
533 m_iparm(IPARM_SYM) = API_SYM_YES;
534 m_iparm(IPARM_FACTORIZATION) = API_FACT_LLT;
537 void grabMatrix(
const MatrixType &matrix, ColSpMatrix &out) {
538 out.resize(matrix.rows(), matrix.cols());
540 out.template selfadjointView<Lower>() = matrix.template selfadjointView<UpLo>();
541 internal::c_to_fortran_numbering(out);
562template <
typename MatrixType_,
int UpLo_>
563class PastixLDLT :
public PastixBase<PastixLDLT<MatrixType_, UpLo_> > {
565 typedef MatrixType_ MatrixType;
566 typedef PastixBase<PastixLDLT<MatrixType, UpLo_> > Base;
567 typedef typename Base::ColSpMatrix ColSpMatrix;
570 enum { UpLo = UpLo_ };
571 PastixLDLT() : Base() { init(); }
573 explicit PastixLDLT(
const MatrixType &matrix) : Base() {
583 grabMatrix(matrix, temp);
593 grabMatrix(matrix, temp);
594 Base::analyzePattern(temp);
601 grabMatrix(matrix, temp);
602 Base::factorize(temp);
609 m_iparm(IPARM_SYM) = API_SYM_YES;
610 m_iparm(IPARM_FACTORIZATION) = API_FACT_LDLT;
613 void grabMatrix(
const MatrixType &matrix, ColSpMatrix &out) {
615 out.resize(matrix.rows(), matrix.cols());
616 out.template selfadjointView<Lower>() = matrix.template selfadjointView<UpLo>();
617 internal::c_to_fortran_numbering(out);
624#undef PASTIX_DCOMPLEX
Base class for all dense matrices, vectors, and expressions.
Definition MatrixBase.h:53
A sparse direct supernodal Cholesky (LLT) factorization and solver based on the PaStiX library.
Definition PaStiXSupport.h:563
void compute(const MatrixType &matrix)
Definition PaStiXSupport.h:581
void analyzePattern(const MatrixType &matrix)
Definition PaStiXSupport.h:591
void factorize(const MatrixType &matrix)
Definition PaStiXSupport.h:599
A sparse direct supernodal Cholesky (LLT) factorization and solver based on the PaStiX library.
Definition PaStiXSupport.h:487
void compute(const MatrixType &matrix)
Definition PaStiXSupport.h:505
void factorize(const MatrixType &matrix)
Definition PaStiXSupport.h:523
void analyzePattern(const MatrixType &matrix)
Definition PaStiXSupport.h:515
Interface to the PaStix solver.
Definition PaStiXSupport.h:387
void analyzePattern(const MatrixType &matrix)
Definition PaStiXSupport.h:417
void factorize(const MatrixType &matrix)
Definition PaStiXSupport.h:429
void compute(const MatrixType &matrix)
Definition PaStiXSupport.h:406
Index outerSize() const
Definition SparseMatrix.h:167
A base class for sparse solvers.
Definition SparseSolverBase.h:68
SparseSolverBase()=default
ComputationInfo
Definition Constants.h:455
@ NumericalIssue
Definition Constants.h:459
@ InvalidInput
Definition Constants.h:464
@ Success
Definition Constants.h:457
constexpr unsigned int RowMajorBit
Definition Constants.h:71