19 #ifndef AMESOS2_CSSMKL_DEF_HPP
20 #define AMESOS2_CSSMKL_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 , css_initialized_(false)
48 , is_contiguous_(true)
52 set_css_mkl_default_parameters(
pt_,
iparm_);
55 const global_ordinal_type indexBase = this->
matrixA_->getRowMap ()->getIndexBase ();
56 iparm_[34] = (indexBase == 0 ? 1 : 0);
58 auto frow = this->
matrixA_->getRowMap()->getMinGlobalIndex();
59 auto nrows = this->
matrixA_->getLocalNumRows();
65 Teuchos::RCP<const Teuchos::Comm<int> > matComm = this->
matrixA_->getComm ();
66 TEUCHOS_TEST_FOR_EXCEPTION(
67 matComm.is_null (), std::logic_error,
"Amesos2::CssMKL "
68 "constructor: The matrix's communicator is null!");
69 Teuchos::RCP<const Teuchos::MpiComm<int> > matMpiComm =
70 Teuchos::rcp_dynamic_cast<
const Teuchos::MpiComm<int> > (matComm);
71 TEUCHOS_TEST_FOR_EXCEPTION(
72 matMpiComm.is_null (), std::logic_error,
"Amesos2::CssMKL "
73 "constructor: The matrix's communicator is not an MpiComm!");
74 TEUCHOS_TEST_FOR_EXCEPTION(
75 matMpiComm->getRawMpiComm ().is_null (), std::logic_error,
"Amesos2::"
76 "CssMKL constructor: The matrix's communicator claims to be a "
77 "Teuchos::MpiComm<int>, but its getRawPtrComm() method returns "
78 "Teuchos::null! This means that the underlying MPI_Comm doesn't even "
79 "exist, which likely implies that the Teuchos::MpiComm was constructed "
80 "incorrectly. It means something different than if the MPI_Comm were "
82 MPI_Comm CssComm = *(matMpiComm->getRawMpiComm ());
83 CssComm_ = MPI_Comm_c2f(CssComm);
87 Teuchos::rcp (
new map_type (this->
globalNumRows_, nrows, indexBase, matComm));
91 template <
class Matrix,
class Vector>
101 void *bdummy, *xdummy;
102 const MPI_Fint CssComm = CssComm_;
103 function_map::cluster_sparse_solver( pt_, const_cast<int_t*>(&maxfct_),
104 const_cast<int_t*>(&mnum_), &mtype_, &phase, &n_,
105 nzvals_view_.data(), rowptr_view_.data(),
106 colind_view_.data(), perm_.getRawPtr(), &nrhs_, iparm_,
107 const_cast<int_t*
>(&msglvl_), &bdummy, &xdummy, &CssComm, &error );
108 css_initialized_ =
false;
110 check_css_mkl_error(Amesos2::CLEAN, error);
114 template<
class Matrix,
class Vector>
124 template <
class Matrix,
class Vector>
130 #ifdef HAVE_AMESOS2_TIMERS
131 Teuchos::TimeMonitor symbFactTimer( this->timers_.symFactTime_ );
135 void *bdummy, *xdummy;
136 const MPI_Fint CssComm = CssComm_;
137 function_map::cluster_sparse_solver( pt_, const_cast<int_t*>(&maxfct_),
138 const_cast<int_t*>(&mnum_), &mtype_, &phase, &n_,
139 nzvals_view_.data(), rowptr_view_.data(),
140 colind_view_.data(), perm_.getRawPtr(), &nrhs_, iparm_,
141 const_cast<int_t*
>(&msglvl_), &bdummy, &xdummy, &CssComm, &error );
143 check_css_mkl_error(Amesos2::SYMBFACT, error);
148 this->setNnzLU(iparm_[17]);
149 css_initialized_ =
true;
155 template <
class Matrix,
class Vector>
161 #ifdef HAVE_AMESOS2_TIMERS
162 Teuchos::TimeMonitor numFactTimer( this->timers_.numFactTime_ );
167 void *bdummy, *xdummy;
168 const MPI_Fint CssComm = CssComm_;
169 function_map::cluster_sparse_solver( pt_, const_cast<int_t*>(&maxfct_),
170 const_cast<int_t*>(&mnum_), &mtype_, &phase, &n_,
171 nzvals_view_.data(), rowptr_view_.data(),
172 colind_view_.data(), perm_.getRawPtr(), &nrhs_, iparm_,
173 const_cast<int_t*
>(&msglvl_), &bdummy, &xdummy, &CssComm, &error );
175 check_css_mkl_error(Amesos2::NUMFACT, error);
181 template <
class Matrix,
class Vector>
189 const local_ordinal_type ld_rhs = this->matrixA_->getLocalNumRows();
190 nrhs_ = as<int_t>(X->getGlobalNumVectors());
192 const size_t val_store_size = as<size_t>(ld_rhs * nrhs_);
193 xvals_.resize(val_store_size);
194 bvals_.resize(val_store_size);
196 #ifdef HAVE_AMESOS2_TIMERS
197 Teuchos::TimeMonitor mvConvTimer( this->timers_.vecConvTime_ );
198 Teuchos::TimeMonitor redistTimer( this->timers_.vecRedistTime_ );
203 solver_scalar_type>::do_get(B, bvals_(),
205 DISTRIBUTED_NO_OVERLAP,
206 this->rowIndexBase_);
211 #ifdef HAVE_AMESOS2_TIMERS
212 Teuchos::TimeMonitor solveTimer( this->timers_.solveTime_ );
215 const int_t phase = 33;
216 const MPI_Fint CssComm = CssComm_;
217 function_map::cluster_sparse_solver( pt_,
218 const_cast<int_t*>(&maxfct_),
219 const_cast<int_t*>(&mnum_),
220 const_cast<int_t*>(&mtype_),
221 const_cast<int_t*>(&phase),
222 const_cast<int_t*>(&n_),
223 const_cast<solver_scalar_type*>(nzvals_view_.data()),
224 const_cast<int_t*>(rowptr_view_.data()),
225 const_cast<int_t*>(colind_view_.data()),
226 const_cast<int_t*>(perm_.getRawPtr()),
228 const_cast<int_t*>(iparm_),
229 const_cast<int_t*
>(&msglvl_),
230 as<void*>(bvals_.getRawPtr()),
231 as<void*>(xvals_.getRawPtr()), &CssComm, &error );
233 check_css_mkl_error(Amesos2::SOLVE, error);
237 #ifdef HAVE_AMESOS2_TIMERS
238 Teuchos::TimeMonitor redistTimer(this->timers_.vecRedistTime_);
243 solver_scalar_type>::do_put(X, xvals_(),
245 DISTRIBUTED_NO_OVERLAP);
252 template <
class Matrix,
class Vector>
257 return( this->globalNumRows_ == this->globalNumCols_ );
261 template <
class Matrix,
class Vector>
266 using Teuchos::getIntegralValue;
267 using Teuchos::ParameterEntryValidator;
269 RCP<const Teuchos::ParameterList> valid_params = getValidParameters_impl();
272 if( parameterList->isParameter(
"IPARM(2)") )
274 RCP<const ParameterEntryValidator> fillin_validator = valid_params->getEntry(
"IPARM(2)").validator();
275 parameterList->getEntry(
"IPARM(2)").setValidator(fillin_validator);
276 iparm_[1] = getIntegralValue<int>(*parameterList,
"IPARM(2)");
280 if( parameterList->isParameter(
"IPARM(8)") )
282 RCP<const ParameterEntryValidator> refine_validator = valid_params->getEntry(
"IPARM(8)").validator();
283 parameterList->getEntry(
"IPARM(8)").setValidator(refine_validator);
284 iparm_[7] = getIntegralValue<int>(*parameterList,
"IPARM(8)");
288 if( parameterList->isParameter(
"IPARM(10)") )
290 RCP<const ParameterEntryValidator> pivot_perturb_validator = valid_params->getEntry(
"IPARM(10)").validator();
291 parameterList->getEntry(
"IPARM(10)").setValidator(pivot_perturb_validator);
292 iparm_[9] = getIntegralValue<int>(*parameterList,
"IPARM(10)");
297 iparm_[11] = this->control_.useTranspose_ ? 2 : 0;
299 if( parameterList->isParameter(
"IPARM(12)") )
301 RCP<const ParameterEntryValidator> trans_validator = valid_params->getEntry(
"IPARM(12)").validator();
302 parameterList->getEntry(
"IPARM(12)").setValidator(trans_validator);
303 iparm_[11] = getIntegralValue<int>(*parameterList,
"IPARM(12)");
307 if( parameterList->isParameter(
"IPARM(13)") )
309 RCP<const ParameterEntryValidator> trans_validator = valid_params->getEntry(
"IPARM(13)").validator();
310 parameterList->getEntry(
"IPARM(13)").setValidator(trans_validator);
311 iparm_[12] = getIntegralValue<int>(*parameterList,
"IPARM(13)");
315 if( parameterList->isParameter(
"IPARM(18)") )
317 RCP<const ParameterEntryValidator> report_validator = valid_params->getEntry(
"IPARM(18)").validator();
318 parameterList->getEntry(
"IPARM(18)").setValidator(report_validator);
319 iparm_[17] = getIntegralValue<int>(*parameterList,
"IPARM(18)");
322 if( parameterList->isParameter(
"IsContiguous") ){
323 is_contiguous_ = parameterList->get<
bool>(
"IsContiguous");
348 template <
class Matrix,
class Vector>
349 Teuchos::RCP<const Teuchos::ParameterList>
355 using Teuchos::tuple;
356 using Teuchos::toString;
357 using Teuchos::EnhancedNumberValidator;
358 using Teuchos::setStringToIntegralParameter;
359 using Teuchos::anyNumberParameterEntryValidator;
361 static Teuchos::RCP<const Teuchos::ParameterList> valid_params;
363 if( is_null(valid_params) ){
364 Teuchos::RCP<Teuchos::ParameterList> pl = Teuchos::parameterList();
367 int_t iparm_temp[64];
368 set_css_mkl_default_parameters(pt_temp, iparm_temp);
369 setStringToIntegralParameter<int>(
"IPARM(2)", toString(iparm_temp[1]),
370 "Fill-in reducing ordering for the input matrix",
371 tuple<string>(
"2",
"3",
"10"),
372 tuple<string>(
"Nested dissection algorithm from METIS",
373 "Parallel version of the nested dissection algorithm",
374 "MPI version of the nested dissection and symbolic factorization algorithms"),
375 tuple<int>(2, 3, 10),
378 setStringToIntegralParameter<int>(
"IPARM(12)", toString(iparm_temp[11]),
379 "Solve with transposed or conjugate transposed matrix A",
380 tuple<string>(
"0",
"1",
"2"),
381 tuple<string>(
"Non-transposed",
382 "Conjugate-transposed",
387 setStringToIntegralParameter<int>(
"IPARM(13)", toString(iparm_temp[12]),
388 "Use weighted matching",
389 tuple<string>(
"0",
"1"),
390 tuple<string>(
"No matching",
"Use matching"),
394 Teuchos::AnyNumberParameterEntryValidator::EPreferredType preferred_int =
395 Teuchos::AnyNumberParameterEntryValidator::PREFER_INT;
397 Teuchos::AnyNumberParameterEntryValidator::AcceptedTypes accept_int(
false );
398 accept_int.allowInt(
true );
400 pl->set(
"IPARM(8)" , as<int>(iparm_temp[7]) ,
"Iterative refinement step",
401 anyNumberParameterEntryValidator(preferred_int, accept_int));
403 pl->set(
"IPARM(10)", as<int>(iparm_temp[9]) ,
"Pivoting perturbation",
404 anyNumberParameterEntryValidator(preferred_int, accept_int));
406 pl->set(
"IPARM(18)", as<int>(iparm_temp[17]),
"Report the number of non-zero elements in the factors",
407 anyNumberParameterEntryValidator(preferred_int, accept_int));
409 pl->set(
"IsContiguous",
true,
"Whether GIDs contiguous");
419 template <
class Matrix,
class Vector>
423 #ifdef HAVE_AMESOS2_TIMERS
424 Teuchos::TimeMonitor convTimer(this->timers_.mtxConvTime_);
428 if( current_phase == PREORDERING )
return(
false );
430 EDistribution dist_option = (iparm_[39] != 0 ? DISTRIBUTED_NO_OVERLAP : ((is_contiguous_ ==
true) ? ROOTED : CONTIGUOUS_AND_ROOTED));
431 if (current_phase == SYMBFACT) {
432 if (dist_option == DISTRIBUTED_NO_OVERLAP) {
433 Kokkos::resize(nzvals_temp_, this->matrixA_->getLocalNNZ());
434 Kokkos::resize(nzvals_view_, this->matrixA_->getLocalNNZ());
435 Kokkos::resize(colind_view_, this->matrixA_->getLocalNNZ());
436 Kokkos::resize(rowptr_view_, this->matrixA_->getLocalNumRows() + 1);
439 Kokkos::resize(nzvals_temp_, this->matrixA_->getGlobalNNZ());
440 Kokkos::resize(nzvals_view_, this->matrixA_->getGlobalNNZ());
441 Kokkos::resize(colind_view_, this->matrixA_->getGlobalNNZ());
442 Kokkos::resize(rowptr_view_, this->matrixA_->getGlobalNumRows() + 1);
444 Kokkos::resize(nzvals_temp_, 0);
445 Kokkos::resize(nzvals_view_, 0);
446 Kokkos::resize(colind_view_, 0);
447 Kokkos::resize(rowptr_view_, 0);
453 #ifdef HAVE_AMESOS2_TIMERS
454 Teuchos::TimeMonitor mtxRedistTimer( this->timers_.mtxRedistTime_ );
458 host_value_type_array,host_ordinal_type_array, host_size_type_array >::do_get(
459 this->matrixA_.ptr(),
460 nzvals_temp_, colind_view_, rowptr_view_,
462 Teuchos::ptrInArg(*css_rowmap_),
465 Kokkos::deep_copy(nzvals_view_, nzvals_temp_);
471 template <
class Matrix,
class Vector>
477 Teuchos::broadcast(*(this->getComm()), 0, &error_i);
479 if( error == 0 )
return;
481 std::string errmsg =
"Other error";
484 errmsg =
"CssMKL reported error: 'Input inconsistent'";
487 errmsg =
"CssMKL reported error: 'Not enough memory'";
490 errmsg =
"CssMKL reported error: 'Reordering problem'";
494 "CssMKL reported error: 'Zero pivot, numerical "
495 "factorization or iterative refinement problem'";
498 errmsg =
"CssMKL reported error: 'Unclassified (internal) error'";
501 errmsg =
"CssMKL reported error: 'Reordering failed'";
504 errmsg =
"CssMKL reported error: 'Diagonal matrix is singular'";
507 errmsg =
"CssMKL reported error: '32-bit integer overflow problem'";
510 errmsg =
"CssMKL reported error: 'Not enough memory for OOC'";
513 errmsg =
"CssMKL reported error: 'Problems with opening OOC temporary files'";
516 errmsg =
"CssMKL reported error: 'Read/write problem with OOC data file'";
519 errmsg += (
" at phase = "+std::to_string(phase));
521 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::runtime_error, errmsg );
525 template <
class Matrix,
class Vector>
538 TEUCHOS_TEST_FOR_EXCEPTION( complex_,
539 std::invalid_argument,
540 "Cannot set a real Pardiso matrix type with scalar type complex" );
543 TEUCHOS_TEST_FOR_EXCEPTION( !complex_,
544 std::invalid_argument,
545 "Cannot set a complex Pardiso matrix type with non-complex scalars" );
548 TEUCHOS_TEST_FOR_EXCEPTION(
true,
549 std::invalid_argument,
550 "Symmetric matrices are not yet supported by the Amesos2 interface" );
555 template <
class Matrix,
class Vector>
559 for(
int i = 0; i < 64; ++i ){
576 if constexpr ( std::is_same_v<solver_magnitude_type, PMKL::_REAL_t> ) {
584 template <
class Matrix,
class Vector>
585 const char* CssMKL<Matrix,Vector>::name =
"CSSMKL";
587 template <
class Matrix,
class Vector>
588 const typename CssMKL<Matrix,Vector>::int_t
589 CssMKL<Matrix,Vector>::msglvl_ = 0;
591 template <
class Matrix,
class Vector>
592 const typename CssMKL<Matrix,Vector>::int_t
593 CssMKL<Matrix,Vector>::maxfct_ = 1;
595 template <
class Matrix,
class Vector>
596 const typename CssMKL<Matrix,Vector>::int_t
597 CssMKL<Matrix,Vector>::mnum_ = 1;
602 #endif // AMESOS2_CSSMKL_DEF_HPP
Amesos2::SolverCore: A templated interface for interaction with third-party direct sparse solvers...
Definition: Amesos2_SolverCore_decl.hpp:71
EPhase
Used to indicate a phase in the direct solution.
Definition: Amesos2_TypeDecl.hpp:31
void check_css_mkl_error(EPhase phase, int_t error) const
Throws an appropriate runtime error in the event that error < 0 .
Definition: Amesos2_CssMKL_def.hpp:473
Amesos2 interface to the CssMKL package.
Definition: Amesos2_CssMKL_decl.hpp:49
~CssMKL()
Destructor.
Definition: Amesos2_CssMKL_def.hpp:92
global_size_type globalNumRows_
Number of global rows in matrixA_.
Definition: Amesos2_SolverCore_decl.hpp:442
int_t iparm_[64]
Definition: Amesos2_CssMKL_decl.hpp:276
Helper class for getting 1-D copies of multivectors.
Definition: Amesos2_MultiVecAdapter_decl.hpp:233
int preOrdering_impl()
Performs pre-ordering on the matrix to increase efficiency.
Definition: Amesos2_CssMKL_def.hpp:116
CssMKL(Teuchos::RCP< const Matrix > A, Teuchos::RCP< Vector > X, Teuchos::RCP< const Vector > B)
Initialize from Teuchos::RCP.
Definition: Amesos2_CssMKL_def.hpp:40
void set_css_mkl_matrix_type(int_t mtype=0)
Definition: Amesos2_CssMKL_def.hpp:527
bool loadA_impl(EPhase current_phase)
Reads matrix data into internal structures.
Definition: Amesos2_CssMKL_def.hpp:421
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.
int numericFactorization_impl()
CssMKL specific numeric factorization.
Definition: Amesos2_CssMKL_def.hpp:157
bool matrixShapeOK_impl() const
Determines whether the shape of the matrix is OK for this solver.
Definition: Amesos2_CssMKL_def.hpp:254
int solve_impl(const Teuchos::Ptr< MultiVecAdapter< Vector > > X, const Teuchos::Ptr< const MultiVecAdapter< Vector > > B) const
CssMKL specific solve.
Definition: Amesos2_CssMKL_def.hpp:183
void * pt_[64]
CssMKL internal data address pointer.
Definition: Amesos2_CssMKL_decl.hpp:261
Teuchos::RCP< const Teuchos::ParameterList > getValidParameters_impl() const
Definition: Amesos2_CssMKL_def.hpp:350
Similar to get_ccs_helper , but used to get a CRS representation of the given matrix.
Definition: Amesos2_Util.hpp:625
int symbolicFactorization_impl()
Perform symbolic factorization of the matrix using CssMKL.
Definition: Amesos2_CssMKL_def.hpp:126
void setParameters_impl(const Teuchos::RCP< Teuchos::ParameterList > ¶meterList)
Definition: Amesos2_CssMKL_def.hpp:263
EDistribution
Definition: Amesos2_TypeDecl.hpp:89
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 MatrixAdapter< Matrix > > matrixA_
The LHS operator.
Definition: Amesos2_SolverCore_decl.hpp:421