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 Teuchos::RCP<const Teuchos::Comm<int> > matComm = this->
matrixA_->getComm ();
53 const global_ordinal_type indexBase = this->
matrixA_->getRowMap ()->getIndexBase ();
54 const local_ordinal_type nrows = this->
matrixA_->getLocalNumRows();
58 Teuchos::rcp (
new map_type (this->
globalNumRows_, nrows, indexBase, matComm));
59 css_contig_rowmap_ = Teuchos::rcp (
new map_type (0, 0, indexBase, matComm));
60 css_contig_colmap_ = Teuchos::rcp (
new map_type (0, 0, indexBase, matComm));
64 set_css_mkl_default_parameters(
pt_,
iparm_);
67 iparm_[34] = (indexBase == 0 ? 1 : 0);
69 auto frow = css_rowmap_->getMinGlobalIndex();
75 TEUCHOS_TEST_FOR_EXCEPTION(
76 matComm.is_null (), std::logic_error,
"Amesos2::CssMKL "
77 "constructor: The matrix's communicator is null!");
78 Teuchos::RCP<const Teuchos::MpiComm<int> > matMpiComm =
79 Teuchos::rcp_dynamic_cast<
const Teuchos::MpiComm<int> > (matComm);
80 TEUCHOS_TEST_FOR_EXCEPTION(
81 matMpiComm.is_null (), std::logic_error,
"Amesos2::CssMKL "
82 "constructor: The matrix's communicator is not an MpiComm!");
83 TEUCHOS_TEST_FOR_EXCEPTION(
84 matMpiComm->getRawMpiComm ().is_null (), std::logic_error,
"Amesos2::"
85 "CssMKL constructor: The matrix's communicator claims to be a "
86 "Teuchos::MpiComm<int>, but its getRawPtrComm() method returns "
87 "Teuchos::null! This means that the underlying MPI_Comm doesn't even "
88 "exist, which likely implies that the Teuchos::MpiComm was constructed "
89 "incorrectly. It means something different than if the MPI_Comm were "
91 MPI_Comm CssComm = *(matMpiComm->getRawMpiComm ());
92 CssComm_ = MPI_Comm_c2f(CssComm);
96 template <
class Matrix,
class Vector>
103 if (css_initialized_)
106 void *bdummy, *xdummy;
107 const MPI_Fint CssComm = CssComm_;
108 function_map::cluster_sparse_solver( pt_, const_cast<int_t*>(&maxfct_),
109 const_cast<int_t*>(&mnum_), &mtype_, &phase, &n_,
110 nzvals_view_.data(), rowptr_view_.data(),
111 colind_view_.data(), perm_.getRawPtr(), &nrhs_, iparm_,
112 const_cast<int_t*
>(&msglvl_), &bdummy, &xdummy, &CssComm, &error );
113 css_initialized_ =
false;
115 check_css_mkl_error(Amesos2::CLEAN, error);
119 template<
class Matrix,
class Vector>
129 template <
class Matrix,
class Vector>
133 if (msglvl_ > 0 && this->matrixA_->getComm()->getRank() == 0) {
134 std::cout <<
" CssMKL::symbolicFactorization:\n" << std::endl;
135 for (
int i=0; i < 64; i++) std::cout <<
" * IPARM[" << i <<
"] = " << iparm_[i] << std::endl;
139 #ifdef HAVE_AMESOS2_TIMERS
140 Teuchos::TimeMonitor symbFactTimer( this->timers_.symFactTime_ );
144 void *bdummy, *xdummy;
145 const MPI_Fint CssComm = CssComm_;
146 function_map::cluster_sparse_solver( pt_, const_cast<int_t*>(&maxfct_),
147 const_cast<int_t*>(&mnum_), &mtype_, &phase, &n_,
148 nzvals_view_.data(), rowptr_view_.data(),
149 colind_view_.data(), perm_.getRawPtr(), &nrhs_, iparm_,
150 const_cast<int_t*
>(&msglvl_), &bdummy, &xdummy, &CssComm, &error );
152 check_css_mkl_error(Amesos2::SYMBFACT, error);
153 if (msglvl_ > 0 && this->matrixA_->getComm()->getRank() == 0) {
154 std::cout <<
" CssMKL::symbolicFactorization done:" << std::endl;
155 std::cout <<
" * Time : " << this->timers_.symFactTime_.totalElapsedTime() << std::endl;
161 this->setNnzLU(iparm_[17]);
162 css_initialized_ =
true;
167 template <
class Matrix,
class Vector>
171 if (msglvl_ > 0 && this->matrixA_->getComm()->getRank() == 0) {
172 std::cout <<
" CssMKL::numericFactorization:\n" << std::endl;
176 #ifdef HAVE_AMESOS2_TIMERS
177 Teuchos::TimeMonitor numFactTimer( this->timers_.numFactTime_ );
182 void *bdummy, *xdummy;
183 const MPI_Fint CssComm = CssComm_;
184 function_map::cluster_sparse_solver( pt_, const_cast<int_t*>(&maxfct_),
185 const_cast<int_t*>(&mnum_), &mtype_, &phase, &n_,
186 nzvals_view_.data(), rowptr_view_.data(),
187 colind_view_.data(), perm_.getRawPtr(), &nrhs_, iparm_,
188 const_cast<int_t*
>(&msglvl_), &bdummy, &xdummy, &CssComm, &error );
190 check_css_mkl_error(Amesos2::NUMFACT, error);
191 if (msglvl_ > 0 && this->matrixA_->getComm()->getRank() == 0) {
192 std::cout <<
" CssMKL::numericFactorization done:" << std::endl;
193 std::cout <<
" Time : " << this->timers_.numFactTime_.totalElapsedTime() << std::endl;
200 template <
class Matrix,
class Vector>
208 const local_ordinal_type ld_rhs = this->matrixA_->getLocalNumRows();
209 nrhs_ = as<int_t>(X->getGlobalNumVectors());
211 const size_t val_store_size = as<size_t>(ld_rhs * nrhs_);
212 xvals_.resize(val_store_size);
213 bvals_.resize(val_store_size);
215 #ifdef HAVE_AMESOS2_TIMERS
216 Teuchos::TimeMonitor mvConvTimer( this->timers_.vecConvTime_ );
217 Teuchos::TimeMonitor redistTimer( this->timers_.vecRedistTime_ );
222 solver_scalar_type>::do_get(B, bvals_(),
224 Teuchos::ptrInArg(*css_rowmap_));
229 #ifdef HAVE_AMESOS2_TIMERS
230 Teuchos::TimeMonitor solveTimer( this->timers_.solveTime_ );
233 const int_t phase = 33;
234 const MPI_Fint CssComm = CssComm_;
235 function_map::cluster_sparse_solver( pt_,
236 const_cast<int_t*>(&maxfct_),
237 const_cast<int_t*>(&mnum_),
238 const_cast<int_t*>(&mtype_),
239 const_cast<int_t*>(&phase),
240 const_cast<int_t*>(&n_),
241 const_cast<solver_scalar_type*>(nzvals_view_.data()),
242 const_cast<int_t*>(rowptr_view_.data()),
243 const_cast<int_t*>(colind_view_.data()),
244 const_cast<int_t*>(perm_.getRawPtr()),
246 const_cast<int_t*>(iparm_),
247 const_cast<int_t*
>(&msglvl_),
248 as<void*>(bvals_.getRawPtr()),
249 as<void*>(xvals_.getRawPtr()), &CssComm, &error );
251 check_css_mkl_error(Amesos2::SOLVE, error);
255 #ifdef HAVE_AMESOS2_TIMERS
256 Teuchos::TimeMonitor redistTimer(this->timers_.vecRedistTime_);
261 solver_scalar_type>::do_put(X, xvals_(),
263 Teuchos::ptrInArg(*css_rowmap_));
270 template <
class Matrix,
class Vector>
275 return( this->globalNumRows_ == this->globalNumCols_ );
279 template <
class Matrix,
class Vector>
284 using Teuchos::getIntegralValue;
285 using Teuchos::ParameterEntryValidator;
287 RCP<const Teuchos::ParameterList> valid_params = getValidParameters_impl();
290 if( parameterList->isParameter(
"IPARM(2)") )
292 RCP<const ParameterEntryValidator> fillin_validator = valid_params->getEntry(
"IPARM(2)").validator();
293 parameterList->getEntry(
"IPARM(2)").setValidator(fillin_validator);
294 iparm_[1] = getIntegralValue<int>(*parameterList,
"IPARM(2)");
298 if( parameterList->isParameter(
"IPARM(8)") )
300 RCP<const ParameterEntryValidator> refine_validator = valid_params->getEntry(
"IPARM(8)").validator();
301 parameterList->getEntry(
"IPARM(8)").setValidator(refine_validator);
302 iparm_[7] = getIntegralValue<int>(*parameterList,
"IPARM(8)");
306 if( parameterList->isParameter(
"IPARM(10)") )
308 RCP<const ParameterEntryValidator> pivot_perturb_validator = valid_params->getEntry(
"IPARM(10)").validator();
309 parameterList->getEntry(
"IPARM(10)").setValidator(pivot_perturb_validator);
310 iparm_[9] = getIntegralValue<int>(*parameterList,
"IPARM(10)");
315 iparm_[11] = this->control_.useTranspose_ ? 2 : 0;
317 if( parameterList->isParameter(
"IPARM(12)") )
319 RCP<const ParameterEntryValidator> trans_validator = valid_params->getEntry(
"IPARM(12)").validator();
320 parameterList->getEntry(
"IPARM(12)").setValidator(trans_validator);
321 iparm_[11] = getIntegralValue<int>(*parameterList,
"IPARM(12)");
325 if( parameterList->isParameter(
"IPARM(13)") )
327 RCP<const ParameterEntryValidator> trans_validator = valid_params->getEntry(
"IPARM(13)").validator();
328 parameterList->getEntry(
"IPARM(13)").setValidator(trans_validator);
329 iparm_[12] = getIntegralValue<int>(*parameterList,
"IPARM(13)");
333 if( parameterList->isParameter(
"IPARM(18)") )
335 RCP<const ParameterEntryValidator> report_validator = valid_params->getEntry(
"IPARM(18)").validator();
336 parameterList->getEntry(
"IPARM(18)").setValidator(report_validator);
337 iparm_[17] = getIntegralValue<int>(*parameterList,
"IPARM(18)");
341 if( parameterList->isParameter(
"IPARM(28)") )
343 RCP<const ParameterEntryValidator> report_validator = valid_params->getEntry(
"IPARM(28)").validator();
344 parameterList->getEntry(
"IPARM(28)").setValidator(report_validator);
345 iparm_[27] = getIntegralValue<int>(*parameterList,
"IPARM(28)");
348 if( parameterList->isParameter(
"IsContiguous") ){
349 is_contiguous_ = parameterList->get<
bool>(
"IsContiguous");
352 if( parameterList->isParameter(
"verbose") ){
353 msglvl_ = parameterList->get<
int>(
"verbose");
378 template <
class Matrix,
class Vector>
379 Teuchos::RCP<const Teuchos::ParameterList>
385 using Teuchos::tuple;
386 using Teuchos::toString;
387 using Teuchos::EnhancedNumberValidator;
388 using Teuchos::setStringToIntegralParameter;
389 using Teuchos::anyNumberParameterEntryValidator;
391 static Teuchos::RCP<const Teuchos::ParameterList> valid_params;
393 if( is_null(valid_params) ){
394 Teuchos::RCP<Teuchos::ParameterList> pl = Teuchos::parameterList();
397 int_t iparm_temp[64];
398 set_css_mkl_default_parameters(pt_temp, iparm_temp);
399 setStringToIntegralParameter<int>(
"IPARM(2)", toString(iparm_temp[1]),
400 "Fill-in reducing ordering for the input matrix",
401 tuple<string>(
"2",
"3",
"10"),
402 tuple<string>(
"Nested dissection algorithm from METIS",
403 "Parallel version of the nested dissection algorithm",
404 "MPI version of the nested dissection and symbolic factorization algorithms"),
405 tuple<int>(2, 3, 10),
408 setStringToIntegralParameter<int>(
"IPARM(12)", toString(iparm_temp[11]),
409 "Solve with transposed or conjugate transposed matrix A",
410 tuple<string>(
"0",
"1",
"2"),
411 tuple<string>(
"Non-transposed",
412 "Conjugate-transposed",
417 setStringToIntegralParameter<int>(
"IPARM(13)", toString(iparm_temp[12]),
418 "Use weighted matching",
419 tuple<string>(
"0",
"1"),
420 tuple<string>(
"No matching",
"Use matching"),
424 Teuchos::AnyNumberParameterEntryValidator::EPreferredType preferred_int =
425 Teuchos::AnyNumberParameterEntryValidator::PREFER_INT;
427 Teuchos::AnyNumberParameterEntryValidator::AcceptedTypes accept_int(
false );
428 accept_int.allowInt(
true );
430 pl->set(
"IPARM(8)" , as<int>(iparm_temp[7]) ,
"Iterative refinement step",
431 anyNumberParameterEntryValidator(preferred_int, accept_int));
433 pl->set(
"IPARM(10)", as<int>(iparm_temp[9]) ,
"Pivoting perturbation",
434 anyNumberParameterEntryValidator(preferred_int, accept_int));
436 pl->set(
"IPARM(18)", as<int>(iparm_temp[17]),
"Report the number of non-zero elements in the factors",
437 anyNumberParameterEntryValidator(preferred_int, accept_int));
439 pl->set(
"IPARM(28)", as<int>(iparm_temp[27]),
"Check input matrix is sorted",
440 anyNumberParameterEntryValidator(preferred_int, accept_int));
442 pl->set(
"IsContiguous",
true,
"Whether GIDs contiguous");
444 pl->set(
"verbose", 0,
"Verbosity Message Level");
454 template <
class Matrix,
class Vector>
458 #ifdef HAVE_AMESOS2_TIMERS
459 Teuchos::TimeMonitor convTimer(this->timers_.mtxConvTime_);
463 if( current_phase == PREORDERING )
return(
false );
467 EDistribution dist_option = (iparm_[39] != 0 ? DISTRIBUTED_NO_OVERLAP : ((is_contiguous_ ==
true) ? ROOTED : CONTIGUOUS_AND_ROOTED));
468 if (dist_option == DISTRIBUTED_NO_OVERLAP && !is_contiguous_) {
472 css_rowmap_ = this->matrixA_->getRowMap();
473 Teuchos::RCP<const MatrixAdapter<Matrix> > contig_mat = this->matrixA_->reindex(css_contig_rowmap_, css_contig_colmap_);
476 Teuchos::RCP<const MatrixAdapter<Matrix> > contig_mat = this->matrixA_->get(ptrInArg(*css_rowmap_));
480 if (current_phase == SYMBFACT) {
481 Kokkos::resize(nzvals_temp_, contig_mat->getLocalNNZ());
482 Kokkos::resize(nzvals_view_, contig_mat->getLocalNNZ());
483 Kokkos::resize(colind_view_, contig_mat->getLocalNNZ());
484 Kokkos::resize(rowptr_view_, contig_mat->getLocalNumRows() + 1);
488 #ifdef HAVE_AMESOS2_TIMERS
489 Teuchos::TimeMonitor mtxRedistTimer( this->timers_.mtxRedistTime_ );
492 host_value_type_array,host_ordinal_type_array, host_size_type_array >::do_get(
494 nzvals_temp_, colind_view_, rowptr_view_,
496 ptrInArg(*(contig_mat->getRowMap())),
498 DISTRIBUTED_NO_OVERLAP,
503 Kokkos::deep_copy(nzvals_view_, nzvals_temp_);
506 if (current_phase == SYMBFACT) {
507 if (dist_option == DISTRIBUTED_NO_OVERLAP) {
508 Kokkos::resize(nzvals_temp_, this->matrixA_->getLocalNNZ());
509 Kokkos::resize(nzvals_view_, this->matrixA_->getLocalNNZ());
510 Kokkos::resize(colind_view_, this->matrixA_->getLocalNNZ());
511 Kokkos::resize(rowptr_view_, this->matrixA_->getLocalNumRows() + 1);
514 Kokkos::resize(nzvals_temp_, this->matrixA_->getGlobalNNZ());
515 Kokkos::resize(nzvals_view_, this->matrixA_->getGlobalNNZ());
516 Kokkos::resize(colind_view_, this->matrixA_->getGlobalNNZ());
517 Kokkos::resize(rowptr_view_, this->matrixA_->getGlobalNumRows() + 1);
519 Kokkos::resize(nzvals_temp_, 0);
520 Kokkos::resize(nzvals_view_, 0);
521 Kokkos::resize(colind_view_, 0);
522 Kokkos::resize(rowptr_view_, 0);
528 #ifdef HAVE_AMESOS2_TIMERS
529 Teuchos::TimeMonitor mtxRedistTimer( this->timers_.mtxRedistTime_ );
532 host_value_type_array,host_ordinal_type_array, host_size_type_array >::do_get(
533 this->matrixA_.ptr(),
534 nzvals_temp_, colind_view_, rowptr_view_,
536 ptrInArg(*(this->matrixA_->getRowMap())),
539 Kokkos::deep_copy(nzvals_view_, nzvals_temp_);
546 template <
class Matrix,
class Vector>
552 Teuchos::broadcast(*(this->getComm()), 0, &error_i);
554 if( error == 0 )
return;
556 std::string errmsg =
"Other error";
559 errmsg =
"CssMKL reported error: 'Input inconsistent'";
562 errmsg =
"CssMKL reported error: 'Not enough memory'";
565 errmsg =
"CssMKL reported error: 'Reordering problem'";
569 "CssMKL reported error: 'Zero pivot, numerical "
570 "factorization or iterative refinement problem'";
573 errmsg =
"CssMKL reported error: 'Unclassified (internal) error'";
576 errmsg =
"CssMKL reported error: 'Reordering failed'";
579 errmsg =
"CssMKL reported error: 'Diagonal matrix is singular'";
582 errmsg =
"CssMKL reported error: '32-bit integer overflow problem'";
585 errmsg =
"CssMKL reported error: 'Not enough memory for OOC'";
588 errmsg =
"CssMKL reported error: 'Problems with opening OOC temporary files'";
591 errmsg =
"CssMKL reported error: 'Read/write problem with OOC data file'";
594 errmsg += (
" at phase = "+std::to_string(phase));
596 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::runtime_error, errmsg );
600 template <
class Matrix,
class Vector>
613 TEUCHOS_TEST_FOR_EXCEPTION( complex_,
614 std::invalid_argument,
615 "Cannot set a real Pardiso matrix type with scalar type complex" );
618 TEUCHOS_TEST_FOR_EXCEPTION( !complex_,
619 std::invalid_argument,
620 "Cannot set a complex Pardiso matrix type with non-complex scalars" );
623 TEUCHOS_TEST_FOR_EXCEPTION(
true,
624 std::invalid_argument,
625 "Symmetric matrices are not yet supported by the Amesos2 interface" );
630 template <
class Matrix,
class Vector>
634 for(
int i = 0; i < 64; ++i ){
650 if (mtype_ == -2 || mtype_ == -4) {
659 if constexpr ( std::is_same_v<solver_magnitude_type, PMKL::_REAL_t> ) {
668 template <
class Matrix,
class Vector>
669 const char* CssMKL<Matrix,Vector>::name =
"CSSMKL";
671 template <
class Matrix,
class Vector>
672 const typename CssMKL<Matrix,Vector>::int_t
673 CssMKL<Matrix,Vector>::maxfct_ = 1;
675 template <
class Matrix,
class Vector>
676 const typename CssMKL<Matrix,Vector>::int_t
677 CssMKL<Matrix,Vector>::mnum_ = 1;
682 #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:548
Amesos2 interface to the CssMKL package.
Definition: Amesos2_CssMKL_decl.hpp:49
~CssMKL()
Destructor.
Definition: Amesos2_CssMKL_def.hpp:97
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:279
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:121
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:602
bool loadA_impl(EPhase current_phase)
Reads matrix data into internal structures.
Definition: Amesos2_CssMKL_def.hpp:456
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:169
bool matrixShapeOK_impl() const
Determines whether the shape of the matrix is OK for this solver.
Definition: Amesos2_CssMKL_def.hpp:272
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:202
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:380
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:131
void setParameters_impl(const Teuchos::RCP< Teuchos::ParameterList > ¶meterList)
Definition: Amesos2_CssMKL_def.hpp:281
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