19 #ifndef AMESOS2_PARDISOMKL_DEF_HPP
20 #define AMESOS2_PARDISOMKL_DEF_HPP
24 #include <Teuchos_Tuple.hpp>
25 #include <Teuchos_toString.hpp>
26 #include <Teuchos_StandardParameterEntryValidators.hpp>
36 # include <mkl_pardiso.h>
39 template <
class Matrix,
class Vector>
41 Teuchos::RCP<Vector> X,
42 Teuchos::RCP<const Vector> B)
44 , n_(Teuchos::as<int_t>(this->globalNumRows_))
45 , perm_(this->globalNumRows_)
47 , is_contiguous_(true)
52 PMKL::_INTEGER_t iparm_temp[64];
53 PMKL::_INTEGER_t mtype_temp =
mtype_;
54 PMKL::pardisoinit(
pt_, &mtype_temp, iparm_temp);
56 for(
int i = 0; i < 64; ++i ){
61 if constexpr ( std::is_same_v<solver_magnitude_type, PMKL::_REAL_t> ) {
69 #ifdef HAVE_AMESOS2_DEBUG
75 template <
class Matrix,
class Vector>
82 void *bdummy, *xdummy;
86 function_map::pardiso( pt_, const_cast<int_t*>(&maxfct_),
87 const_cast<int_t*>(&mnum_), &mtype_, &phase, &n_,
88 nzvals_view_.data(), rowptr_view_.data(),
89 colind_view_.data(), perm_.getRawPtr(), &nrhs_, iparm_,
90 const_cast<int_t*
>(&msglvl_), &bdummy, &xdummy, &error );
93 check_pardiso_mkl_error(Amesos2::CLEAN, error);
97 template<
class Matrix,
class Vector>
108 template <
class Matrix,
class Vector>
115 #ifdef HAVE_AMESOS2_TIMERS
116 Teuchos::TimeMonitor symbFactTimer( this->timers_.symFactTime_ );
120 void *bdummy, *xdummy;
122 function_map::pardiso( pt_, const_cast<int_t*>(&maxfct_),
123 const_cast<int_t*>(&mnum_), &mtype_, &phase, &n_,
124 nzvals_view_.data(), rowptr_view_.data(),
125 colind_view_.data(), perm_.getRawPtr(), &nrhs_, iparm_,
126 const_cast<int_t*
>(&msglvl_), &bdummy, &xdummy, &error );
129 check_pardiso_mkl_error(Amesos2::SYMBFACT, error);
134 this->setNnzLU(iparm_[17]);
140 template <
class Matrix,
class Vector>
147 #ifdef HAVE_AMESOS2_TIMERS
148 Teuchos::TimeMonitor numFactTimer( this->timers_.numFactTime_ );
152 void *bdummy, *xdummy;
154 function_map::pardiso( pt_, const_cast<int_t*>(&maxfct_),
155 const_cast<int_t*>(&mnum_), &mtype_, &phase, &n_,
156 nzvals_view_.data(), rowptr_view_.data(),
157 colind_view_.data(), perm_.getRawPtr(), &nrhs_, iparm_,
158 const_cast<int_t*
>(&msglvl_), &bdummy, &xdummy, &error );
161 check_pardiso_mkl_error(Amesos2::NUMFACT, error);
167 template <
class Matrix,
class Vector>
177 const global_size_type ld_rhs = this->root_ ? X->getGlobalLength() : 0;
178 nrhs_ = as<int_t>(X->getGlobalNumVectors());
180 const size_t val_store_size = as<size_t>(ld_rhs * nrhs_);
181 xvals_.resize(val_store_size);
182 bvals_.resize(val_store_size);
185 #ifdef HAVE_AMESOS2_TIMERS
186 Teuchos::TimeMonitor mvConvTimer( this->timers_.vecConvTime_ );
187 Teuchos::TimeMonitor redistTimer( this->timers_.vecRedistTime_ );
192 solver_scalar_type>::do_get(B, bvals_(),
194 (is_contiguous_ ==
true) ? ROOTED : CONTIGUOUS_AND_ROOTED,
195 this->rowIndexBase_);
199 #ifdef HAVE_AMESOS2_TIMERS
200 Teuchos::TimeMonitor solveTimer( this->timers_.solveTime_ );
203 const int_t phase = 33;
205 function_map::pardiso( pt_,
206 const_cast<int_t*>(&maxfct_),
207 const_cast<int_t*>(&mnum_),
208 const_cast<int_t*>(&mtype_),
209 const_cast<int_t*>(&phase),
210 const_cast<int_t*>(&n_),
211 const_cast<solver_scalar_type*>(nzvals_view_.data()),
212 const_cast<int_t*>(rowptr_view_.data()),
213 const_cast<int_t*>(colind_view_.data()),
214 const_cast<int_t*>(perm_.getRawPtr()),
216 const_cast<int_t*>(iparm_),
217 const_cast<int_t*
>(&msglvl_),
218 as<void*>(bvals_.getRawPtr()),
219 as<void*>(xvals_.getRawPtr()), &error );
222 check_pardiso_mkl_error(Amesos2::SOLVE, error);
226 #ifdef HAVE_AMESOS2_TIMERS
227 Teuchos::TimeMonitor redistTimer(this->timers_.vecRedistTime_);
232 solver_scalar_type>::do_put(X, xvals_(),
234 (is_contiguous_ ==
true) ? ROOTED : CONTIGUOUS_AND_ROOTED);
241 template <
class Matrix,
class Vector>
246 return( this->globalNumRows_ == this->globalNumCols_ );
250 template <
class Matrix,
class Vector>
255 using Teuchos::getIntegralValue;
256 using Teuchos::ParameterEntryValidator;
258 RCP<const Teuchos::ParameterList> valid_params = getValidParameters_impl();
261 if( parameterList->isParameter(
"IPARM(2)") )
263 RCP<const ParameterEntryValidator> fillin_validator = valid_params->getEntry(
"IPARM(2)").validator();
264 parameterList->getEntry(
"IPARM(2)").setValidator(fillin_validator);
265 iparm_[1] = getIntegralValue<int>(*parameterList,
"IPARM(2)");
269 if( parameterList->isParameter(
"IPARM(4)") )
271 RCP<const ParameterEntryValidator> prec_validator = valid_params->getEntry(
"IPARM(4)").validator();
272 parameterList->getEntry(
"IPARM(4)").setValidator(prec_validator);
273 iparm_[3] = getIntegralValue<int>(*parameterList,
"IPARM(4)");
277 if( parameterList->isParameter(
"IPARM(8)") )
279 RCP<const ParameterEntryValidator> refine_validator = valid_params->getEntry(
"IPARM(8)").validator();
280 parameterList->getEntry(
"IPARM(8)").setValidator(refine_validator);
281 iparm_[7] = getIntegralValue<int>(*parameterList,
"IPARM(8)");
285 if( parameterList->isParameter(
"IPARM(10)") )
287 RCP<const ParameterEntryValidator> pivot_perturb_validator = valid_params->getEntry(
"IPARM(10)").validator();
288 parameterList->getEntry(
"IPARM(10)").setValidator(pivot_perturb_validator);
289 iparm_[9] = getIntegralValue<int>(*parameterList,
"IPARM(10)");
294 iparm_[11] = this->control_.useTranspose_ ? 2 : 0;
297 if( parameterList->isParameter(
"IPARM(12)") )
299 RCP<const ParameterEntryValidator> trans_validator = valid_params->getEntry(
"IPARM(12)").validator();
300 parameterList->getEntry(
"IPARM(12)").setValidator(trans_validator);
301 iparm_[11] = getIntegralValue<int>(*parameterList,
"IPARM(12)");
305 if( parameterList->isParameter(
"IPARM(13)") )
307 RCP<const ParameterEntryValidator> trans_validator = valid_params->getEntry(
"IPARM(13)").validator();
308 parameterList->getEntry(
"IPARM(13)").setValidator(trans_validator);
309 iparm_[12] = getIntegralValue<int>(*parameterList,
"IPARM(13)");
313 if( parameterList->isParameter(
"IPARM(18)") )
315 RCP<const ParameterEntryValidator> report_validator = valid_params->getEntry(
"IPARM(18)").validator();
316 parameterList->getEntry(
"IPARM(18)").setValidator(report_validator);
317 iparm_[17] = getIntegralValue<int>(*parameterList,
"IPARM(18)");
321 if( parameterList->isParameter(
"IPARM(24)") )
323 RCP<const ParameterEntryValidator> par_fact_validator = valid_params->getEntry(
"IPARM(24)").validator();
324 parameterList->getEntry(
"IPARM(24)").setValidator(par_fact_validator);
325 iparm_[23] = getIntegralValue<int>(*parameterList,
"IPARM(24)");
329 if( parameterList->isParameter(
"IPARM(25)") )
331 RCP<const ParameterEntryValidator> par_fbsolve_validator = valid_params->getEntry(
"IPARM(25)").validator();
332 parameterList->getEntry(
"IPARM(25)").setValidator(par_fbsolve_validator);
333 iparm_[24] = getIntegralValue<int>(*parameterList,
"IPARM(25)");
337 if( parameterList->isParameter(
"IPARM(60)") )
339 RCP<const ParameterEntryValidator> ooc_validator = valid_params->getEntry(
"IPARM(60)").validator();
340 parameterList->getEntry(
"IPARM(60)").setValidator(ooc_validator);
341 iparm_[59] = getIntegralValue<int>(*parameterList,
"IPARM(60)");
344 if( parameterList->isParameter(
"IsContiguous") ){
345 is_contiguous_ = parameterList->get<
bool>(
"IsContiguous");
370 template <
class Matrix,
class Vector>
371 Teuchos::RCP<const Teuchos::ParameterList>
377 using Teuchos::tuple;
378 using Teuchos::toString;
379 using Teuchos::EnhancedNumberValidator;
380 using Teuchos::setStringToIntegralParameter;
381 using Teuchos::anyNumberParameterEntryValidator;
383 static Teuchos::RCP<const Teuchos::ParameterList> valid_params;
385 if( is_null(valid_params) ){
386 Teuchos::RCP<Teuchos::ParameterList> pl = Teuchos::parameterList();
390 PMKL::_INTEGER_t mtype_temp = mtype_;
391 PMKL::_INTEGER_t iparm_temp[64];
392 PMKL::pardisoinit(pt_dummy,
393 const_cast<PMKL::_INTEGER_t*>(&mtype_temp),
394 const_cast<PMKL::_INTEGER_t*>(iparm_temp));
396 setStringToIntegralParameter<int>(
"IPARM(2)", toString(iparm_temp[1]),
397 "Fill-in reducing ordering for the input matrix",
398 tuple<string>(
"0",
"2",
"3"),
399 tuple<string>(
"The minimum degree algorithm",
400 "Nested dissection algorithm from METIS",
401 "OpenMP parallel nested dissection algorithm"),
405 Teuchos::RCP<EnhancedNumberValidator<int> > iparm_4_validator
406 = Teuchos::rcp(
new EnhancedNumberValidator<int>() );
407 iparm_4_validator->setMin(0);
408 pl->set(
"IPARM(4)" , as<int>(iparm_temp[3]) ,
"Preconditioned CGS/CG",
411 setStringToIntegralParameter<int>(
"IPARM(12)", toString(iparm_temp[11]),
412 "Solve with transposed or conjugate transposed matrix A",
413 tuple<string>(
"0",
"1",
"2"),
414 tuple<string>(
"Non-transposed",
415 "Conjugate-transposed",
420 setStringToIntegralParameter<int>(
"IPARM(13)", toString(iparm_temp[12]),
421 "Use weighted matching",
422 tuple<string>(
"0",
"1"),
423 tuple<string>(
"No matching",
"Use matching"),
427 setStringToIntegralParameter<int>(
"IPARM(24)", toString(iparm_temp[23]),
428 "Parallel factorization control",
429 tuple<string>(
"0",
"1"),
430 tuple<string>(
"PARDISO uses the previous algorithm for factorization",
431 "PARDISO uses the new two-level factorization algorithm"),
435 setStringToIntegralParameter<int>(
"IPARM(25)", toString(iparm_temp[24]),
436 "Parallel forward/backward solve control",
437 tuple<string>(
"0",
"1"),
438 tuple<string>(
"PARDISO uses the parallel algorithm for the solve step",
439 "PARDISO uses the sequential forward and backward solve"),
443 setStringToIntegralParameter<int>(
"IPARM(60)", toString(iparm_temp[59]),
444 "PARDISO mode (OOC mode)",
445 tuple<string>(
"0",
"2"),
446 tuple<string>(
"In-core PARDISO",
447 "Out-of-core PARDISO. The OOC PARDISO can solve very "
448 "large problems by holding the matrix factors in files "
449 "on the disk. Hence the amount of RAM required by OOC "
450 "PARDISO is significantly reduced."),
454 Teuchos::AnyNumberParameterEntryValidator::EPreferredType preferred_int =
455 Teuchos::AnyNumberParameterEntryValidator::PREFER_INT;
457 Teuchos::AnyNumberParameterEntryValidator::AcceptedTypes accept_int(
false );
458 accept_int.allowInt(
true );
460 pl->set(
"IPARM(8)" , as<int>(iparm_temp[7]) ,
"Iterative refinement step",
461 anyNumberParameterEntryValidator(preferred_int, accept_int));
463 pl->set(
"IPARM(10)", as<int>(iparm_temp[9]) ,
"Pivoting perturbation",
464 anyNumberParameterEntryValidator(preferred_int, accept_int));
466 pl->set(
"IPARM(18)", as<int>(iparm_temp[17]),
"Report the number of non-zero elements in the factors",
467 anyNumberParameterEntryValidator(preferred_int, accept_int));
469 pl->set(
"IsContiguous",
true,
"Whether GIDs contiguous");
479 template <
class Matrix,
class Vector>
483 #ifdef HAVE_AMESOS2_TIMERS
484 Teuchos::TimeMonitor convTimer(this->timers_.mtxConvTime_);
488 if( current_phase == PREORDERING )
return(
false );
491 Kokkos::resize(nzvals_view_, this->globalNumNonZeros_);
492 Kokkos::resize(colind_view_, this->globalNumNonZeros_);
493 Kokkos::resize(rowptr_view_, this->globalNumRows_ + 1);
497 #ifdef HAVE_AMESOS2_TIMERS
498 Teuchos::TimeMonitor mtxRedistTimer( this->timers_.mtxRedistTime_ );
504 host_value_type_array, host_ordinal_type_array, host_size_type_array>::do_get(
505 this->matrixA_.ptr(),
506 nzvals_view_, colind_view_, rowptr_view_, nnz_ret,
507 (is_contiguous_ ==
true) ? ROOTED : CONTIGUOUS_AND_ROOTED,
509 this->rowIndexBase_);
516 template <
class Matrix,
class Vector>
522 Teuchos::broadcast(*(this->getComm()), 0, &error_i);
524 if( error == 0 )
return;
526 std::string errmsg =
"Other error";
529 errmsg =
"PardisoMKL reported error: 'Input inconsistent'";
532 errmsg =
"PardisoMKL reported error: 'Not enough memory'";
535 errmsg =
"PardisoMKL reported error: 'Reordering problem'";
539 "PardisoMKL reported error: 'Zero pivot, numerical "
540 "factorization or iterative refinement problem'";
543 errmsg =
"PardisoMKL reported error: 'Unclassified (internal) error'";
546 errmsg =
"PardisoMKL reported error: 'Reordering failed'";
549 errmsg =
"PardisoMKL reported error: 'Diagonal matrix is singular'";
552 errmsg =
"PardisoMKL reported error: '32-bit integer overflow problem'";
555 errmsg =
"PardisoMKL reported error: 'Not enough memory for OOC'";
558 errmsg =
"PardisoMKL reported error: 'Problems with opening OOC temporary files'";
561 errmsg =
"PardisoMKL reported error: 'Read/write problem with OOC data file'";
565 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::runtime_error, errmsg );
569 template <
class Matrix,
class Vector>
582 TEUCHOS_TEST_FOR_EXCEPTION( complex_,
583 std::invalid_argument,
584 "Cannot set a real Pardiso matrix type with scalar type complex" );
587 TEUCHOS_TEST_FOR_EXCEPTION( !complex_,
588 std::invalid_argument,
589 "Cannot set a complex Pardiso matrix type with non-complex scalars" );
592 TEUCHOS_TEST_FOR_EXCEPTION(
true,
593 std::invalid_argument,
594 "Symmetric matrices are not yet supported by the Amesos2 interface" );
600 template <
class Matrix,
class Vector>
603 template <
class Matrix,
class Vector>
604 const typename PardisoMKL<Matrix,Vector>::int_t
607 template <
class Matrix,
class Vector>
608 const typename PardisoMKL<Matrix,Vector>::int_t
611 template <
class Matrix,
class Vector>
612 const typename PardisoMKL<Matrix,Vector>::int_t
618 #endif // AMESOS2_PARDISOMKL_DEF_HPP
Amesos2::SolverCore: A templated interface for interaction with third-party direct sparse solvers...
Definition: Amesos2_SolverCore_decl.hpp:71
~PardisoMKL()
Destructor.
Definition: Amesos2_PardisoMKL_def.hpp:76
PardisoMKL(Teuchos::RCP< const Matrix > A, Teuchos::RCP< Vector > X, Teuchos::RCP< const Vector > B)
Initialize from Teuchos::RCP.
Definition: Amesos2_PardisoMKL_def.hpp:40
EPhase
Used to indicate a phase in the direct solution.
Definition: Amesos2_TypeDecl.hpp:31
void set_pardiso_mkl_matrix_type(int_t mtype=0)
Definition: Amesos2_PardisoMKL_def.hpp:571
Helper class for getting 1-D copies of multivectors.
Definition: Amesos2_MultiVecAdapter_decl.hpp:233
void * pt_[64]
PardisoMKL internal data address pointer.
Definition: Amesos2_PardisoMKL_decl.hpp:255
A template class that does nothing useful besides show developers what, in general, needs to be done to add a new solver interface to the Amesos2 collection.
Amesos2 interface to the PardisoMKL package.
Definition: Amesos2_PardisoMKL_decl.hpp:49
int numericFactorization_impl()
PardisoMKL specific numeric factorization.
Definition: Amesos2_PardisoMKL_def.hpp:142
int symbolicFactorization_impl()
Perform symbolic factorization of the matrix using PardisoMKL.
Definition: Amesos2_PardisoMKL_def.hpp:110
A Matrix adapter interface for Amesos2.
Definition: Amesos2_MatrixAdapter_decl.hpp:42
bool loadA_impl(EPhase current_phase)
Reads matrix data into internal structures.
Definition: Amesos2_PardisoMKL_def.hpp:481
Similar to get_ccs_helper , but used to get a CRS representation of the given matrix.
Definition: Amesos2_Util.hpp:625
void setParameters_impl(const Teuchos::RCP< Teuchos::ParameterList > ¶meterList)
Definition: Amesos2_PardisoMKL_def.hpp:252
int solve_impl(const Teuchos::Ptr< MultiVecAdapter< Vector > > X, const Teuchos::Ptr< const MultiVecAdapter< Vector > > B) const
PardisoMKL specific solve.
Definition: Amesos2_PardisoMKL_def.hpp:169
void check_pardiso_mkl_error(EPhase phase, int_t error) const
Throws an appropriate runtime error in the event that error < 0 .
Definition: Amesos2_PardisoMKL_def.hpp:518
Helper class for putting 1-D data arrays into multivectors.
Definition: Amesos2_MultiVecAdapter_decl.hpp:339
A templated MultiVector class adapter for Amesos2.
Definition: Amesos2_MultiVecAdapter_decl.hpp:142
Teuchos::RCP< const Teuchos::ParameterList > getValidParameters_impl() const
Definition: Amesos2_PardisoMKL_def.hpp:372
bool matrixShapeOK_impl() const
Determines whether the shape of the matrix is OK for this solver.
Definition: Amesos2_PardisoMKL_def.hpp:243
int_t mtype_
The matrix type. We deal only with unsymmetrix matrices.
Definition: Amesos2_PardisoMKL_decl.hpp:257
int_t iparm_[64]
Definition: Amesos2_PardisoMKL_decl.hpp:267
int preOrdering_impl()
Performs pre-ordering on the matrix to increase efficiency.
Definition: Amesos2_PardisoMKL_def.hpp:99