Amesos2 - Direct Sparse Solver Interfaces Version of the Day
Amesos2_PardisoMKL_def.hpp
Go to the documentation of this file.
1// @HEADER
2// *****************************************************************************
3// Amesos2: Templated Direct Sparse Solver Package
4//
5// Copyright 2011 NTESS and the Amesos2 contributors.
6// SPDX-License-Identifier: BSD-3-Clause
7// *****************************************************************************
8// @HEADER
9
10
19#ifndef AMESOS2_PARDISOMKL_DEF_HPP
20#define AMESOS2_PARDISOMKL_DEF_HPP
21
22#include <map>
23
24#include <Teuchos_Tuple.hpp>
25#include <Teuchos_toString.hpp>
26#include <Teuchos_StandardParameterEntryValidators.hpp>
27
30
31
32namespace Amesos2 {
33
34 namespace PMKL {
35# include <mkl.h>
36# include <mkl_pardiso.h>
37 }
38
39 template <class Matrix, class Vector>
40 PardisoMKL<Matrix,Vector>::PardisoMKL(Teuchos::RCP<const Matrix> A,
41 Teuchos::RCP<Vector> X,
42 Teuchos::RCP<const Vector> B)
43 : SolverCore<Amesos2::PardisoMKL,Matrix,Vector>(A, X, B) // instantiate superclass
44 , n_(Teuchos::as<int_t>(this->globalNumRows_))
45 , perm_(this->globalNumRows_)
46 , nrhs_(0)
47 , pardiso_initialized_(false)
48 , is_contiguous_(true)
49 , msglvl_(0)
50 , debug_level_(0)
51 {
52 // set the default matrix type
54
55 PMKL::_INTEGER_t iparm_temp[64];
56 PMKL::_INTEGER_t mtype_temp = mtype_;
57 PMKL::pardisoinit(pt_, &mtype_temp, iparm_temp);
58
59 for( int i = 0; i < 64; ++i ){
60 iparm_[i] = iparm_temp[i];
61 }
62
63 // set single or double precision
64 if constexpr ( std::is_same_v<solver_magnitude_type, PMKL::_REAL_t> ) {
65 iparm_[27] = 1; // single-precision
66 } else {
67 iparm_[27] = 0; // double-precision
68 }
69
70 // Reset some of the default parameters
71 iparm_[34] = 1; // Use zero-based indexing
72#ifdef HAVE_AMESOS2_DEBUG
73 iparm_[26] = 1; // turn the Pardiso matrix checker on
74#endif
75 }
76
77
78 template <class Matrix, class Vector>
80 {
81 /*
82 * Free any memory allocated by the PardisoMKL library functions
83 */
84 int_t error = 0;
85 void *bdummy, *xdummy;
86
87 if( this->root_ && pardiso_initialized_){
88 int_t phase = -1; // release all internal solver memory
89 function_map::pardiso( pt_, const_cast<int_t*>(&maxfct_),
90 const_cast<int_t*>(&mnum_), &mtype_, &phase, &n_,
91 nzvals_view_.data(), rowptr_view_.data(),
92 colind_view_.data(), perm_.getRawPtr(), &nrhs_, iparm_,
93 const_cast<int_t*>(&msglvl_), &bdummy, &xdummy, &error );
94 pardiso_initialized_ = false;
95 }
96
97 check_pardiso_mkl_error(Amesos2::CLEAN, error);
98 }
99
100
101 template<class Matrix, class Vector>
102 int
104 {
105 // preOrdering done in PardisoMKL during "Analysis" (aka symbolic
106 // factorization) phase
107
108 return(0);
109 }
110
111
112 template <class Matrix, class Vector>
113 int
115 {
116 int_t error = 0;
117
118 if( this->root_ ){
119#ifdef HAVE_AMESOS2_TIMERS
120 Teuchos::TimeMonitor symbFactTimer( this->timers_.symFactTime_ );
121#endif
122 void *bdummy, *xdummy;
123
124 if( pardiso_initialized_){
125 int_t phase = -1; // release all internal solver memory
126 function_map::pardiso( pt_, const_cast<int_t*>(&maxfct_),
127 const_cast<int_t*>(&mnum_), &mtype_, &phase, &n_,
128 nzvals_view_.data(), rowptr_view_.data(),
129 colind_view_.data(), perm_.getRawPtr(), &nrhs_, iparm_,
130 const_cast<int_t*>(&msglvl_), &bdummy, &xdummy, &error );
131 if (msglvl_ > 0 && error != 0) {
132 std::cout << " PardisoMKL::symbolicFactorization: clean-up failed with " << error << std::endl;
133 }
134 pardiso_initialized_ = false;
135 }
136
137 int_t phase = 11;
138 function_map::pardiso( pt_, const_cast<int_t*>(&maxfct_),
139 const_cast<int_t*>(&mnum_), &mtype_, &phase, &n_,
140 nzvals_view_.data(), rowptr_view_.data(),
141 colind_view_.data(), perm_.getRawPtr(), &nrhs_, iparm_,
142 const_cast<int_t*>(&msglvl_), &bdummy, &xdummy, &error );
143 pardiso_initialized_ = true;
144 }
145 check_pardiso_mkl_error(Amesos2::SYMBFACT, error);
146
147 if (msglvl_ > 0 && this->root_) {
148 std::cout << " PardisoMKL::symbolicFactorization done:" << std::endl;
149#ifdef HAVE_AMESOS2_TIMERS
150 std::cout << " * Time : " << this->timers_.symFactTime_.totalElapsedTime() << std::endl;
151#else
152 std::cout << " * Time : not enabled" << std::endl;
153#endif
154 }
155
156 // Pardiso only lets you retrieve the total number of factor
157 // non-zeros, not for each individually. We should document how
158 // such a situation is reported.
159 this->setNnzLU(iparm_[17]);
160
161 return(0);
162 }
163
164
165 template <class Matrix, class Vector>
166 int
168 {
169 int_t error = 0;
170
171 if( this->root_ ){
172#ifdef HAVE_AMESOS2_TIMERS
173 Teuchos::TimeMonitor numFactTimer( this->timers_.numFactTime_ );
174#endif
175
176 int_t phase = 22;
177 void *bdummy, *xdummy;
178 function_map::pardiso( pt_, const_cast<int_t*>(&maxfct_),
179 const_cast<int_t*>(&mnum_), &mtype_, &phase, &n_,
180 nzvals_view_.data(), rowptr_view_.data(),
181 colind_view_.data(), perm_.getRawPtr(), &nrhs_, iparm_,
182 const_cast<int_t*>(&msglvl_), &bdummy, &xdummy, &error );
183 }
184 check_pardiso_mkl_error(Amesos2::NUMFACT, error);
185
186 if (msglvl_ > 0 && this->root_) {
187 std::cout << " PardisoMKL::numericFactorization done:" << std::endl;
188#ifdef HAVE_AMESOS2_TIMERS
189 std::cout << " * Time : " << this->timers_.numFactTime_.totalElapsedTime() << std::endl;
190#else
191 std::cout << " * Time : not enabled" << std::endl;
192#endif
193 }
194
195 return( 0 );
196 }
197
198
199 template <class Matrix, class Vector>
200 int
202 const Teuchos::Ptr<const MultiVecAdapter<Vector> > B) const
203 {
204 using Teuchos::as;
205
206 int_t error = 0;
207
208 // Get B data
209 const global_size_type ld_rhs = this->root_ ? X->getGlobalLength() : 0;
210 nrhs_ = as<int_t>(X->getGlobalNumVectors());
211 if (debug_level_ > 0) {
212 if (this->root_) std::cout << "\n == Amesos2_PardisoMKL::solve_impl ==" << std::endl;
213 if (debug_level_ == 1) {
214 B->description();
215 } else {
216 Teuchos::RCP<Teuchos::FancyOStream> fancy = Teuchos::fancyOStream(Teuchos::rcpFromRef(std::cout));
217 if (!is_null(B->getMap())) B->getMap()->describe(*fancy, Teuchos::VERB_EXTREME);
218 std::cout << std::endl;
219 B->describe(*fancy, Teuchos::VERB_EXTREME);
220 }
221 }
222
223 const size_t val_store_size = as<size_t>(ld_rhs * nrhs_);
224 xvals_.resize(val_store_size);
225 bvals_.resize(val_store_size);
226
227 { // Get values from RHS B
228#ifdef HAVE_AMESOS2_TIMERS
229 Teuchos::TimeMonitor mvConvTimer( this->timers_.vecConvTime_ );
230 Teuchos::TimeMonitor redistTimer( this->timers_.vecRedistTime_ );
231#endif
232
235 solver_scalar_type>::do_get(B, bvals_(),
236 as<size_t>(ld_rhs),
237 (is_contiguous_ == true) ? ROOTED : CONTIGUOUS_AND_ROOTED,
238 this->rowIndexBase_);
239 }
240
241 if( this->root_ ){
242#ifdef HAVE_AMESOS2_TIMERS
243 Teuchos::TimeMonitor solveTimer( this->timers_.solveTime_ );
244#endif
245
246 const int_t phase = 33;
247 function_map::pardiso( pt_,
248 const_cast<int_t*>(&maxfct_),
249 const_cast<int_t*>(&mnum_),
250 const_cast<int_t*>(&mtype_),
251 const_cast<int_t*>(&phase),
252 const_cast<int_t*>(&n_),
253 const_cast<solver_scalar_type*>(nzvals_view_.data()),
254 const_cast<int_t*>(rowptr_view_.data()),
255 const_cast<int_t*>(colind_view_.data()),
256 const_cast<int_t*>(perm_.getRawPtr()),
257 &nrhs_,
258 const_cast<int_t*>(iparm_),
259 const_cast<int_t*>(&msglvl_),
260 as<void*>(bvals_.getRawPtr()),
261 as<void*>(xvals_.getRawPtr()), &error );
262 }
263
264 check_pardiso_mkl_error(Amesos2::SOLVE, error);
265
266 /* Export X from root to the global space */
267 {
268#ifdef HAVE_AMESOS2_TIMERS
269 Teuchos::TimeMonitor redistTimer(this->timers_.vecRedistTime_);
270#endif
271
274 solver_scalar_type>::do_put(X, xvals_(),
275 as<size_t>(ld_rhs),
276 (is_contiguous_ == true) ? ROOTED : CONTIGUOUS_AND_ROOTED);
277 }
278 if (debug_level_ > 0) {
279 if (debug_level_ == 1) {
280 X->description();
281 } else {
282 Teuchos::RCP<Teuchos::FancyOStream> fancy = Teuchos::fancyOStream(Teuchos::rcpFromRef(std::cout));
283 if (!is_null(X->getMap())) X->getMap()->describe(*fancy, Teuchos::VERB_EXTREME);
284 std::cout << std::endl;
285 X->describe(*fancy, Teuchos::VERB_EXTREME);
286 }
287 }
288 if (msglvl_ > 0 && this->root_) {
289 std::cout << " PardisoMKL::solve done:" << std::endl;
290#ifdef HAVE_AMESOS2_TIMERS
291 std::cout << " * Time : " << this->timers_.vecRedistTime_.totalElapsedTime()
292 << " + " << this->timers_.solveTime_.totalElapsedTime() << std::endl;
293#else
294 std::cout << " * Time : not enabled" << std::endl;
295#endif
296 }
297
298 return( 0 );
299}
300
301
302 template <class Matrix, class Vector>
303 bool
305 {
306 // PardisoMKL supports square matrices
307 return( this->globalNumRows_ == this->globalNumCols_ );
308 }
309
310
311 template <class Matrix, class Vector>
312 void
313 PardisoMKL<Matrix,Vector>::setParameters_impl(const Teuchos::RCP<Teuchos::ParameterList> & parameterList )
314 {
315 using Teuchos::RCP;
316 using Teuchos::getIntegralValue;
317 using Teuchos::ParameterEntryValidator;
318
319 RCP<const Teuchos::ParameterList> valid_params = getValidParameters_impl();
320
321 // Fill-in reordering: 0 = minimum degree, 2 = METIS 4.0.1 (default), 3 = METIS 5.1, 4 = AMD,
322 if( parameterList->isParameter("IPARM(2)") )
323 {
324 RCP<const ParameterEntryValidator> fillin_validator = valid_params->getEntry("IPARM(2)").validator();
325 parameterList->getEntry("IPARM(2)").setValidator(fillin_validator);
326 iparm_[1] = getIntegralValue<int>(*parameterList, "IPARM(2)");
327 }
328
329 // Iterative-direct algorithm
330 if( parameterList->isParameter("IPARM(4)") )
331 {
332 RCP<const ParameterEntryValidator> prec_validator = valid_params->getEntry("IPARM(4)").validator();
333 parameterList->getEntry("IPARM(4)").setValidator(prec_validator);
334 iparm_[3] = getIntegralValue<int>(*parameterList, "IPARM(4)");
335 }
336
337 // Max numbers of iterative refinement steps
338 if( parameterList->isParameter("IPARM(8)") )
339 {
340 RCP<const ParameterEntryValidator> refine_validator = valid_params->getEntry("IPARM(8)").validator();
341 parameterList->getEntry("IPARM(8)").setValidator(refine_validator);
342 iparm_[7] = getIntegralValue<int>(*parameterList, "IPARM(8)");
343 }
344
345 // Perturb the pivot elements
346 if( parameterList->isParameter("IPARM(10)") )
347 {
348 RCP<const ParameterEntryValidator> pivot_perturb_validator = valid_params->getEntry("IPARM(10)").validator();
349 parameterList->getEntry("IPARM(10)").setValidator(pivot_perturb_validator);
350 iparm_[9] = getIntegralValue<int>(*parameterList, "IPARM(10)");
351 }
352
353 // First check if the control object requests a transpose solve.
354 // Then solver specific options can override this.
355 iparm_[11] = this->control_.useTranspose_ ? 2 : 0;
356
357 // Normal solve (0), or a transpose solve (1)
358 if( parameterList->isParameter("IPARM(12)") )
359 {
360 RCP<const ParameterEntryValidator> trans_validator = valid_params->getEntry("IPARM(12)").validator();
361 parameterList->getEntry("IPARM(12)").setValidator(trans_validator);
362 iparm_[11] = getIntegralValue<int>(*parameterList, "IPARM(12)");
363 }
364
365 // (Non-)symmetric matchings : detault 1 for nonsymmetric and 0 for symmetric matrix (default is nonsymmetric)
366 if( parameterList->isParameter("IPARM(13)") )
367 {
368 RCP<const ParameterEntryValidator> trans_validator = valid_params->getEntry("IPARM(13)").validator();
369 parameterList->getEntry("IPARM(13)").setValidator(trans_validator);
370 iparm_[12] = getIntegralValue<int>(*parameterList, "IPARM(13)");
371 }
372
373 // Output: Number of nonzeros in the factor LU
374 if( parameterList->isParameter("IPARM(18)") )
375 {
376 RCP<const ParameterEntryValidator> report_validator = valid_params->getEntry("IPARM(18)").validator();
377 parameterList->getEntry("IPARM(18)").setValidator(report_validator);
378 iparm_[17] = getIntegralValue<int>(*parameterList, "IPARM(18)");
379 }
380
381 // Scheduling method for the parallel numerical factorization
382 if( parameterList->isParameter("IPARM(24)") )
383 {
384 RCP<const ParameterEntryValidator> par_fact_validator = valid_params->getEntry("IPARM(24)").validator();
385 parameterList->getEntry("IPARM(24)").setValidator(par_fact_validator);
386 iparm_[23] = getIntegralValue<int>(*parameterList, "IPARM(24)");
387 }
388
389 // Parallelization scheme for the forward and backward solv
390 if( parameterList->isParameter("IPARM(25)") )
391 {
392 RCP<const ParameterEntryValidator> par_fbsolve_validator = valid_params->getEntry("IPARM(25)").validator();
393 parameterList->getEntry("IPARM(25)").setValidator(par_fbsolve_validator);
394 iparm_[24] = getIntegralValue<int>(*parameterList, "IPARM(25)");
395 }
396
397 // Graph compression scheme for METIS.
398 if( parameterList->isParameter("IPARM(60)") )
399 {
400 RCP<const ParameterEntryValidator> ooc_validator = valid_params->getEntry("IPARM(60)").validator();
401 parameterList->getEntry("IPARM(60)").setValidator(ooc_validator);
402 iparm_[59] = getIntegralValue<int>(*parameterList, "IPARM(60)");
403 }
404
405 if( parameterList->isParameter("IsContiguous") ){
406 is_contiguous_ = parameterList->get<bool>("IsContiguous");
407 }
408 if( parameterList->isParameter("MessageLevel") ){
409 msglvl_ = parameterList->get<int>("MessageLevel");
410 }
411 if( parameterList->isParameter("DebugLevel") ){
412 debug_level_ = parameterList->get<int>("DebugLevel");
413 }
414 }
415
416
417/*
418 * TODO: It would be nice if the parameters could be expressed as
419 * either all string or as all integers. I see no way of doing this
420 * at present with the standard validators. However, we could create
421 * our own validators or kindly ask the Teuchos team to add some
422 * features for use.
423 *
424 * The issue is that with the current validators we cannot specify
425 * arbitrary sets of numbers that are the only allowed parameters.
426 * For example the IPARM(2) parameter can take only the values 0, 2,
427 * and 3. The EnhancedNumberValidator can take a min value, and max
428 * value, and a step size, but with those options there is no way to
429 * specify the needed set.
430 *
431 * Another missing feature is the ability to give docstrings for such
432 * numbers. For example IPARM(25) can take on the values 0 and 1.
433 * This would be easy enough to accomplish with just a number
434 * validator, but then have no way to document the effect of each
435 * value.
436 */
437template <class Matrix, class Vector>
438Teuchos::RCP<const Teuchos::ParameterList>
440{
441 using std::string;
442 using Teuchos::as;
443 using Teuchos::RCP;
444 using Teuchos::tuple;
445 using Teuchos::toString;
446 using Teuchos::EnhancedNumberValidator;
447 using Teuchos::setStringToIntegralParameter;
448 using Teuchos::anyNumberParameterEntryValidator;
449
450 static Teuchos::RCP<const Teuchos::ParameterList> valid_params;
451
452 if( is_null(valid_params) ){
453 Teuchos::RCP<Teuchos::ParameterList> pl = Teuchos::parameterList();
454
455 // Use pardisoinit to get some default values;
456 void *pt_dummy[64];
457 PMKL::_INTEGER_t mtype_temp = mtype_;
458 PMKL::_INTEGER_t iparm_temp[64];
459 PMKL::pardisoinit(pt_dummy,
460 const_cast<PMKL::_INTEGER_t*>(&mtype_temp),
461 const_cast<PMKL::_INTEGER_t*>(iparm_temp));
462
463 setStringToIntegralParameter<int>("IPARM(2)", toString(iparm_temp[1]),
464 "Fill-in reducing ordering for the input matrix",
465 tuple<string>("0", "2", "3"),
466 tuple<string>("The minimum degree algorithm",
467 "Nested dissection algorithm from METIS",
468 "OpenMP parallel nested dissection algorithm"),
469 tuple<int>(0, 2, 3),
470 pl.getRawPtr());
471
472 Teuchos::RCP<EnhancedNumberValidator<int> > iparm_4_validator
473 = Teuchos::rcp( new EnhancedNumberValidator<int>() );
474 iparm_4_validator->setMin(0);
475 pl->set("IPARM(4)" , as<int>(iparm_temp[3]) , "Preconditioned CGS/CG",
476 iparm_4_validator);
477
478 setStringToIntegralParameter<int>("IPARM(12)", toString(iparm_temp[11]),
479 "Solve with transposed or conjugate transposed matrix A",
480 tuple<string>("0", "1", "2"),
481 tuple<string>("Non-transposed",
482 "Conjugate-transposed",
483 "Transposed"),
484 tuple<int>(0, 1, 2),
485 pl.getRawPtr());
486
487 setStringToIntegralParameter<int>("IPARM(13)", toString(iparm_temp[12]),
488 "Use weighted matching",
489 tuple<string>("0", "1"),
490 tuple<string>("No matching", "Use matching"),
491 tuple<int>(0, 1),
492 pl.getRawPtr());
493
494 setStringToIntegralParameter<int>("IPARM(24)", toString(iparm_temp[23]),
495 "Parallel factorization control",
496 tuple<string>("0", "1"),
497 tuple<string>("PARDISO uses the previous algorithm for factorization",
498 "PARDISO uses the new two-level factorization algorithm"),
499 tuple<int>(0, 1),
500 pl.getRawPtr());
501
502 setStringToIntegralParameter<int>("IPARM(25)", toString(iparm_temp[24]),
503 "Parallel forward/backward solve control",
504 tuple<string>("0", "1"),
505 tuple<string>("PARDISO uses the parallel algorithm for the solve step",
506 "PARDISO uses the sequential forward and backward solve"),
507 tuple<int>(0, 1),
508 pl.getRawPtr());
509
510 setStringToIntegralParameter<int>("IPARM(60)", toString(iparm_temp[59]),
511 "PARDISO mode (OOC mode)",
512 tuple<string>("0", "2"),
513 tuple<string>("In-core PARDISO",
514 "Out-of-core PARDISO. The OOC PARDISO can solve very "
515 "large problems by holding the matrix factors in files "
516 "on the disk. Hence the amount of RAM required by OOC "
517 "PARDISO is significantly reduced."),
518 tuple<int>(0, 2),
519 pl.getRawPtr());
520
521 Teuchos::AnyNumberParameterEntryValidator::EPreferredType preferred_int =
522 Teuchos::AnyNumberParameterEntryValidator::PREFER_INT;
523
524 Teuchos::AnyNumberParameterEntryValidator::AcceptedTypes accept_int( false );
525 accept_int.allowInt( true );
526
527 pl->set("IPARM(8)" , as<int>(iparm_temp[7]) , "Iterative refinement step",
528 anyNumberParameterEntryValidator(preferred_int, accept_int));
529
530 pl->set("IPARM(10)", as<int>(iparm_temp[9]) , "Pivoting perturbation",
531 anyNumberParameterEntryValidator(preferred_int, accept_int));
532
533 pl->set("IPARM(18)", as<int>(iparm_temp[17]), "Report the number of non-zero elements in the factors",
534 anyNumberParameterEntryValidator(preferred_int, accept_int));
535
536 pl->set("IsContiguous", true, "Whether GIDs contiguous");
537 pl->set("MessageLevel", 0, "PardisoMKL message level (0 to turn off message, and 1 to turn on message");
538 pl->set("DebugLevel", 0, "Debug message level (0 for no message, and >0 for more message");
539
540 valid_params = pl;
541 }
542
543 return valid_params;
544}
545
546
547
548template <class Matrix, class Vector>
549bool
551{
552#ifdef HAVE_AMESOS2_TIMERS
553 Teuchos::TimeMonitor convTimer(this->timers_.mtxConvTime_);
554#endif
555 if (debug_level_ > 0) {
556 if (this->root_) {
557 std::cout << "\n == Amesos2_PardisoMKL::loadA_impl";
558 if (current_phase == PREORDERING) std::cout << "(PreOrder)";
559 if (current_phase == SYMBFACT) std::cout << "(SymFact)";
560 if (current_phase == NUMFACT) std::cout << "(NumFact)";
561 std::cout << " ==" << std::endl;
562 }
563 Teuchos::RCP<Teuchos::FancyOStream> fancy = Teuchos::fancyOStream(Teuchos::rcpFromRef(std::cout));
564 this->matrixA_->describe(*fancy, (debug_level_ == 1 ? Teuchos::VERB_LOW : Teuchos::VERB_EXTREME));
565 }
566
567 // PardisoMKL does not need matrix data in the pre-ordering phase
568 if( current_phase == PREORDERING ) return( false );
569
570 if( this->root_ ){
571 Kokkos::resize(nzvals_view_, this->globalNumNonZeros_);
572 Kokkos::resize(colind_view_, this->globalNumNonZeros_);
573 Kokkos::resize(rowptr_view_, this->globalNumRows_ + 1);
574 }
575 {
576#ifdef HAVE_AMESOS2_TIMERS
577 Teuchos::TimeMonitor mtxRedistTimer( this->timers_.mtxRedistTime_ );
578#endif
579
580 int_t nnz_ret = 0;
583 host_value_type_array, host_ordinal_type_array, host_size_type_array>::do_get(
584 this->matrixA_.ptr(),
585 nzvals_view_, colind_view_, rowptr_view_, nnz_ret,
586 (is_contiguous_ == true) ? ROOTED : CONTIGUOUS_AND_ROOTED,
588 this->rowIndexBase_);
589 }
590
591 return( true );
592}
593
594
595template <class Matrix, class Vector>
596void
598 int_t error) const
599{
600 int error_i = error;
601 Teuchos::broadcast(*(this->getComm()), 0, &error_i); // We only care about root's value
602
603 if( error == 0 ) return; // No error
604
605 std::string errmsg = "Other error";
606 switch( error ){
607 case -1:
608 errmsg = "PardisoMKL reported error: 'Input inconsistent'";
609 break;
610 case -2:
611 errmsg = "PardisoMKL reported error: 'Not enough memory'";
612 break;
613 case -3:
614 errmsg = "PardisoMKL reported error: 'Reordering problem'";
615 break;
616 case -4:
617 errmsg =
618 "PardisoMKL reported error: 'Zero pivot, numerical "
619 "factorization or iterative refinement problem'";
620 break;
621 case -5:
622 errmsg = "PardisoMKL reported error: 'Unclassified (internal) error'";
623 break;
624 case -6:
625 errmsg = "PardisoMKL reported error: 'Reordering failed'";
626 break;
627 case -7:
628 errmsg = "PardisoMKL reported error: 'Diagonal matrix is singular'";
629 break;
630 case -8:
631 errmsg = "PardisoMKL reported error: '32-bit integer overflow problem'";
632 break;
633 case -9:
634 errmsg = "PardisoMKL reported error: 'Not enough memory for OOC'";
635 break;
636 case -10:
637 errmsg = "PardisoMKL reported error: 'Problems with opening OOC temporary files'";
638 break;
639 case -11:
640 errmsg = "PardisoMKL reported error: 'Read/write problem with OOC data file'";
641 break;
642 }
643
644 TEUCHOS_TEST_FOR_EXCEPTION( true, std::runtime_error, errmsg );
645}
646
647
648template <class Matrix, class Vector>
649void
651{
652 if( mtype == 0 ){
653 if( complex_ ){
654 mtype_ = 13; // complex, unsymmetric
655 } else {
656 mtype_ = 11; // real, unsymmetric
657 }
658 } else {
659 switch( mtype ){
660 case 11:
661 TEUCHOS_TEST_FOR_EXCEPTION( complex_,
662 std::invalid_argument,
663 "Cannot set a real Pardiso matrix type with scalar type complex" );
664 mtype_ = 11; break;
665 case 13:
666 TEUCHOS_TEST_FOR_EXCEPTION( !complex_,
667 std::invalid_argument,
668 "Cannot set a complex Pardiso matrix type with non-complex scalars" );
669 mtype_ = 13; break;
670 default:
671 TEUCHOS_TEST_FOR_EXCEPTION( true,
672 std::invalid_argument,
673 "Symmetric matrices are not yet supported by the Amesos2 interface" );
674 }
675 }
676}
677
678
679template <class Matrix, class Vector>
680const char* PardisoMKL<Matrix,Vector>::name = "PARDISOMKL";
681
682template <class Matrix, class Vector>
683const typename PardisoMKL<Matrix,Vector>::int_t
685
686template <class Matrix, class Vector>
687const typename PardisoMKL<Matrix,Vector>::int_t
689
690} // end namespace Amesos
691
692#endif // AMESOS2_PARDISOMKL_DEF_HPP
A template class that does nothing useful besides show developers what, in general,...
@ ROOTED
Definition Amesos2_TypeDecl.hpp:93
@ CONTIGUOUS_AND_ROOTED
Definition Amesos2_TypeDecl.hpp:94
@ SORTED_INDICES
Definition Amesos2_TypeDecl.hpp:108
A Matrix adapter interface for Amesos2.
Definition Amesos2_MatrixAdapter_decl.hpp:42
Amesos2 interface to the PardisoMKL package.
Definition Amesos2_PardisoMKL_decl.hpp:50
Teuchos::RCP< const Teuchos::ParameterList > getValidParameters_impl() const
Definition Amesos2_PardisoMKL_def.hpp:439
void setParameters_impl(const Teuchos::RCP< Teuchos::ParameterList > &parameterList)
Definition Amesos2_PardisoMKL_def.hpp:313
~PardisoMKL()
Destructor.
Definition Amesos2_PardisoMKL_def.hpp:79
int_t mtype_
The matrix type. We deal only with unsymmetrix matrices.
Definition Amesos2_PardisoMKL_decl.hpp:257
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
int_t iparm_[64]
Definition Amesos2_PardisoMKL_decl.hpp:267
int numericFactorization_impl()
PardisoMKL specific numeric factorization.
Definition Amesos2_PardisoMKL_def.hpp:167
bool matrixShapeOK_impl() const
Determines whether the shape of the matrix is OK for this solver.
Definition Amesos2_PardisoMKL_def.hpp:304
bool loadA_impl(EPhase current_phase)
Reads matrix data into internal structures.
Definition Amesos2_PardisoMKL_def.hpp:550
void set_pardiso_mkl_matrix_type(int_t mtype=0)
Definition Amesos2_PardisoMKL_def.hpp:650
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:201
int preOrdering_impl()
Performs pre-ordering on the matrix to increase efficiency.
Definition Amesos2_PardisoMKL_def.hpp:103
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:597
void * pt_[64]
PardisoMKL internal data address pointer.
Definition Amesos2_PardisoMKL_decl.hpp:255
int symbolicFactorization_impl()
Perform symbolic factorization of the matrix using PardisoMKL.
Definition Amesos2_PardisoMKL_def.hpp:114
Amesos2::SolverCore: A templated interface for interaction with third-party direct sparse solvers.
Definition Amesos2_SolverCore_decl.hpp:72
EPhase
Used to indicate a phase in the direct solution.
Definition Amesos2_TypeDecl.hpp:31
A templated MultiVector class adapter for Amesos2.
Definition Amesos2_MultiVecAdapter_decl.hpp:142
Helper class for getting 1-D copies of multivectors.
Definition Amesos2_MultiVecAdapter_decl.hpp:233
Similar to get_ccs_helper , but used to get a CRS representation of the given matrix.
Definition Amesos2_Util.hpp:600
Helper class for putting 1-D data arrays into multivectors.
Definition Amesos2_MultiVecAdapter_decl.hpp:339