Amesos2 - Direct Sparse Solver Interfaces Version of the Day
Amesos2_KLU2_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
18#ifndef AMESOS2_KLU2_DEF_HPP
19#define AMESOS2_KLU2_DEF_HPP
20
21#include <Teuchos_Tuple.hpp>
22#include <Teuchos_ParameterList.hpp>
23#include <Teuchos_StandardParameterEntryValidators.hpp>
24
26#include "Amesos2_KLU2_decl.hpp"
27
28namespace Amesos2 {
29
30
31template <class Matrix, class Vector>
33 Teuchos::RCP<const Matrix> A,
34 Teuchos::RCP<Vector> X,
35 Teuchos::RCP<const Vector> B )
36 : SolverCore<Amesos2::KLU2,Matrix,Vector>(A, X, B)
37 , transFlag_(0)
38 , is_contiguous_(true)
39 , use_gather_(true)
40 , debug_level_(0)
41{
42 ::KLU2::klu_defaults<klu2_dtype, local_ordinal_type> (&(data_.common_)) ;
43 data_.symbolic_ = NULL;
44 data_.numeric_ = NULL;
45
46 // Override some default options
47 // TODO: use data_ here to init
48}
49
50
51template <class Matrix, class Vector>
53{
54 /* Free KLU2 data_types
55 * - Matrices
56 * - Vectors
57 * - Other data
58 */
59 if (data_.symbolic_ != NULL)
60 ::KLU2::klu_free_symbolic<klu2_dtype, local_ordinal_type>
61 (&(data_.symbolic_), &(data_.common_)) ;
62 if (data_.numeric_ != NULL)
63 ::KLU2::klu_free_numeric<klu2_dtype, local_ordinal_type>
64 (&(data_.numeric_), &(data_.common_)) ;
65
66 // Storage is initialized in numericFactorization_impl()
67 //if ( data_.A.Store != NULL ){
68 // destoy
69 //}
70
71 // only root allocated these SuperMatrices.
72 //if ( data_.L.Store != NULL ){ // will only be true for this->root_
73 // destroy ..
74 //}
75}
76
77template <class Matrix, class Vector>
78bool
80 return (this->root_ && (this->matrixA_->getComm()->getSize() == 1) && is_contiguous_);
81}
82
83template<class Matrix, class Vector>
84int
86{
87 /* TODO: Define what it means for KLU2
88 */
89#ifdef HAVE_AMESOS2_TIMERS
90 Teuchos::TimeMonitor preOrderTimer(this->timers_.preOrderTime_);
91#endif
92
93 return(0);
94}
95
96
97template <class Matrix, class Vector>
98int
100{
101 if (data_.symbolic_ != NULL) {
102 ::KLU2::klu_free_symbolic<klu2_dtype, local_ordinal_type>
103 (&(data_.symbolic_), &(data_.common_)) ;
104 }
105
106 if ( single_proc_optimization() ) {
107 host_ordinal_type_array host_row_ptr_view;
108 host_ordinal_type_array host_cols_view;
109 this->matrixA_->returnRowPtr_kokkos_view(host_row_ptr_view);
110 this->matrixA_->returnColInd_kokkos_view(host_cols_view);
111 data_.symbolic_ = ::KLU2::klu_analyze<klu2_dtype, local_ordinal_type>
112 ((local_ordinal_type)this->globalNumCols_, host_row_ptr_view.data(),
113 host_cols_view.data(), &(data_.common_)) ;
114 }
115 else
116 {
117 data_.symbolic_ = ::KLU2::klu_analyze<klu2_dtype, local_ordinal_type>
118 ((local_ordinal_type)this->globalNumCols_, host_col_ptr_view_.data(),
119 host_rows_view_.data(), &(data_.common_)) ;
120
121 } //end single_process_optim_check = false
122
123 return(0);
124}
125
126
127template <class Matrix, class Vector>
128int
130{
131 using Teuchos::as;
132
133 // Cleanup old L and U matrices if we are not reusing a symbolic
134 // factorization. Stores and other data will be allocated in gstrf.
135 // Only rank 0 has valid pointers, TODO: for KLU2
136
137 int info = 0;
138 if ( this->root_ ) {
139
140 { // Do factorization
141#ifdef HAVE_AMESOS2_TIMERS
142 Teuchos::TimeMonitor numFactTimer(this->timers_.numFactTime_);
143#endif
144
145 if (data_.numeric_ != NULL) {
146 ::KLU2::klu_free_numeric<klu2_dtype, local_ordinal_type>
147 (&(data_.numeric_), &(data_.common_));
148 }
149
150 if ( single_proc_optimization() ) {
151 host_ordinal_type_array host_row_ptr_view;
152 host_ordinal_type_array host_cols_view;
153 this->matrixA_->returnRowPtr_kokkos_view(host_row_ptr_view);
154 this->matrixA_->returnColInd_kokkos_view(host_cols_view);
155 this->matrixA_->returnValues_kokkos_view(host_nzvals_view_);
156 klu2_dtype * pValues = function_map::convert_scalar(host_nzvals_view_.data());
157 data_.numeric_ = ::KLU2::klu_factor<klu2_dtype, local_ordinal_type>
158 (host_row_ptr_view.data(), host_cols_view.data(), pValues,
159 data_.symbolic_, &(data_.common_));
160 }
161 else {
162 klu2_dtype * pValues = function_map::convert_scalar(host_nzvals_view_.data());
163 data_.numeric_ = ::KLU2::klu_factor<klu2_dtype, local_ordinal_type>
164 (host_col_ptr_view_.data(), host_rows_view_.data(), pValues,
165 data_.symbolic_, &(data_.common_));
166 } //end single_process_optim_check = false
167
168 // To have a test which confirms a throw, we need MPI to throw on all the
169 // ranks. So we delay and broadcast first. Others throws in Amesos2 which
170 // happen on just the root rank would also have the same problem if we
171 // tested them but we decided to fix just this one for the present. This
172 // is the only error/throw we currently have a unit test for.
173 if(data_.numeric_ == nullptr) {
174 info = 1;
175 if(debug_level_ > 0) {
176 std::cout << " ** Amesos2::KLU2::numericFactorization failed with status = ";
177 if(data_.common_.status == KLU_OK)
178 std::cout << "KLU_OK **\n";
179 else if (data_.common_.status == KLU_SINGULAR)
180 std::cout << "KLU_SINGULAR **\n";
181 else if (data_.common_.status == KLU_OUT_OF_MEMORY)
182 std::cout << "KLU_OUT_OF_MEMORY **\n";
183 else if (data_.common_.status == KLU_INVALID)
184 std::cout << "KLU_INVALID **\n";
185 else if (data_.common_.status == KLU_TOO_LARGE)
186 std::cout << "KLU_TOO_LARGE **\n";
187 }
188 }
189
190 // This is set after numeric factorization complete as pivoting can be used;
191 // In this case, a discrepancy between symbolic and numeric nnz total can occur.
192 if(info == 0) { // skip if error code so we don't segfault - will throw
193 this->setNnzLU( as<size_t>((data_.numeric_)->lnz) + as<size_t>((data_.numeric_)->unz) );
194 }
195 } // end scope
196
197 } // end this->root_
198
199 /* All processes should have the same error code */
200 Teuchos::broadcast(*(this->matrixA_->getComm()), 0, &info);
201
202 TEUCHOS_TEST_FOR_EXCEPTION(info > 0, std::runtime_error,
203 "KLU2 numeric factorization failed(info="+std::to_string(info)+")");
204
205 return(info);
206}
207
208template <class Matrix, class Vector>
209int
211 const Teuchos::Ptr<MultiVecAdapter<Vector> > X,
212 const Teuchos::Ptr<const MultiVecAdapter<Vector> > B) const
213{
214 using Teuchos::as;
215 int ierr = 0; // returned error code
216
217 const global_size_type ld_rhs = this->root_ ? X->getGlobalLength() : 0;
218 const size_t nrhs = X->getGlobalNumVectors();
219 if (debug_level_ > 0) {
220 if (this->root_) std::cout << "\n == Amesos2_KLU2::solve_impl ==" << std::endl;
221 if (debug_level_ == 1) {
222 B->description();
223 } else {
224 Teuchos::RCP<Teuchos::FancyOStream> fancy = Teuchos::fancyOStream(Teuchos::rcpFromRef(std::cout));
225 if (!is_null(B->getMap())) B->getMap()->describe(*fancy, Teuchos::VERB_EXTREME);
226 std::cout << std::endl;
227 B->describe(*fancy, Teuchos::VERB_EXTREME);
228 }
229 }
230
231 bool bDidAssignX;
232 bool bDidAssignB;
233 bool use_gather = use_gather_; // user param
234 use_gather = (use_gather && this->matrixA_->getComm()->getSize() > 1); // only with multiple MPIs
235 use_gather = (use_gather && (std::is_same<vector_scalar_type, float>::value ||
236 std::is_same<vector_scalar_type, double>::value)); // only for double or float vectors
237 {
238#ifdef HAVE_AMESOS2_TIMERS
239 Teuchos::TimeMonitor mvConvTimer(this->timers_.vecConvTime_);
240#endif
241 const bool initialize_data = true;
242 const bool do_not_initialize_data = false;
243 if ( single_proc_optimization() && nrhs == 1 ) {
244 // no msp creation
245 bDidAssignB = Util::get_1d_copy_helper_kokkos_view<MultiVecAdapter<Vector>,
246 host_solve_array_t>::do_get(initialize_data, B, bValues_, as<size_t>(ld_rhs));
247
248 bDidAssignX = Util::get_1d_copy_helper_kokkos_view<MultiVecAdapter<Vector>,
249 host_solve_array_t>::do_get(do_not_initialize_data, X, xValues_, as<size_t>(ld_rhs));
250 }
251 else {
252 if (use_gather) {
253 int rval = B->gather(bValues_, this->perm_g2l, this->recvCountRows, this->recvDisplRows,
254 (is_contiguous_ == true) ? ROOTED : CONTIGUOUS_AND_ROOTED);
255 if (rval == 0) {
256 X->gather(xValues_, this->perm_g2l, this->recvCountRows, this->recvDisplRows,
257 (is_contiguous_ == true) ? ROOTED : CONTIGUOUS_AND_ROOTED);
258 bDidAssignB = true; // TODO : find when we can avoid deep-copy
259 bDidAssignX = false; // TODO : find when we can avoid scatter
260 } else {
261 use_gather = false;
262 }
263 }
264 if (!use_gather) {
265 bDidAssignB = Util::get_1d_copy_helper_kokkos_view<MultiVecAdapter<Vector>,
266 host_solve_array_t>::do_get(initialize_data, B, bValues_,
267 as<size_t>(ld_rhs),
268 (is_contiguous_ == true) ? ROOTED : CONTIGUOUS_AND_ROOTED,
269 this->rowIndexBase_);
270 // see Amesos2_Tacho_def.hpp for an explanation of why we 'get' X
271 bDidAssignX = Util::get_1d_copy_helper_kokkos_view<MultiVecAdapter<Vector>,
272 host_solve_array_t>::do_get(do_not_initialize_data, X, xValues_,
273 as<size_t>(ld_rhs),
274 (is_contiguous_ == true) ? ROOTED : CONTIGUOUS_AND_ROOTED,
275 this->rowIndexBase_);
276 }
277
278 // klu_tsolve is going to put the solution x into the input b.
279 // Copy b to x then solve in x.
280 // We do not want to solve in b, then copy to x, because if b was assigned
281 // then the solve will change b permanently and mess up the next test cycle.
282 // However if b was actually a copy (bDidAssignB = false) then we can avoid
283 // this deep_copy and just assign xValues_ = bValues_.
284 if(bDidAssignB) {
285 Kokkos::deep_copy(xValues_, bValues_); // need deep_copy or solve will change adapter's b memory which should never happen
286 }
287 else {
288 xValues_ = bValues_; // safe because bValues_ does not point straight to adapter's memory space
289 }
290 }
291 }
292
293 klu2_dtype * pxValues = function_map::convert_scalar(xValues_.data());
294 klu2_dtype * pbValues = function_map::convert_scalar(bValues_.data());
295
296 // can be null for non root
297 if( this->root_) {
298 TEUCHOS_TEST_FOR_EXCEPTION(pbValues == nullptr,
299 std::runtime_error, "Amesos2 Runtime Error: b_vector returned null ");
300
301 TEUCHOS_TEST_FOR_EXCEPTION(pxValues == nullptr,
302 std::runtime_error, "Amesos2 Runtime Error: x_vector returned null ");
303 }
304
305 if ( single_proc_optimization() && nrhs == 1 ) {
306#ifdef HAVE_AMESOS2_TIMERS
307 Teuchos::TimeMonitor solveTimer(this->timers_.solveTime_);
308#endif
309
310 // For this case, Crs matrix raw pointers were used, so the non-transpose default solve
311 // is actually the transpose solve as klu_solve expects Ccs matrix pointers
312 // Thus, if the transFlag_ is true, the non-transpose solve should be used
313 if (transFlag_ == 0)
314 {
315 ::KLU2::klu_tsolve2<klu2_dtype, local_ordinal_type>
316 (data_.symbolic_, data_.numeric_,
317 (local_ordinal_type)this->globalNumCols_,
318 (local_ordinal_type)nrhs,
319 pbValues, pxValues, &(data_.common_)) ;
320 }
321 else {
322 ::KLU2::klu_solve2<klu2_dtype, local_ordinal_type>
323 (data_.symbolic_, data_.numeric_,
324 (local_ordinal_type)this->globalNumCols_,
325 (local_ordinal_type)nrhs,
326 pbValues, pxValues, &(data_.common_)) ;
327 }
328
329 /* All processes should have the same error code */
330 // Teuchos::broadcast(*(this->getComm()), 0, &ierr);
331
332 } // end single_process_optim_check && nrhs == 1
333 else // single proc optimizations but nrhs > 1,
334 // or distributed over processes case
335 {
336 if ( this->root_ ) {
337#ifdef HAVE_AMESOS2_TIMERS
338 Teuchos::TimeMonitor solveTimer(this->timers_.solveTime_);
339#endif
340 if (transFlag_ == 0)
341 {
342 // For this case, Crs matrix raw pointers were used, so the non-transpose default solve
343 // is actually the transpose solve as klu_solve expects Ccs matrix pointers
344 // Thus, if the transFlag_ is true, the non-transpose solve should be used
345 if ( single_proc_optimization() ) {
346 ::KLU2::klu_tsolve<klu2_dtype, local_ordinal_type>
347 (data_.symbolic_, data_.numeric_,
348 (local_ordinal_type)this->globalNumCols_,
349 (local_ordinal_type)nrhs,
350 pxValues, &(data_.common_)) ;
351 }
352 else {
353 ::KLU2::klu_solve<klu2_dtype, local_ordinal_type>
354 (data_.symbolic_, data_.numeric_,
355 (local_ordinal_type)this->globalNumCols_,
356 (local_ordinal_type)nrhs,
357 pxValues, &(data_.common_)) ;
358 }
359 }
360 else
361 {
362 // For this case, Crs matrix raw pointers were used, so the non-transpose default solve
363 // is actually the transpose solve as klu_solve expects Ccs matrix pointers
364 // Thus, if the transFlag_ is true, the non- transpose solve should be used
365 if ( single_proc_optimization() ) {
366 ::KLU2::klu_solve<klu2_dtype, local_ordinal_type>
367 (data_.symbolic_, data_.numeric_,
368 (local_ordinal_type)this->globalNumCols_,
369 (local_ordinal_type)nrhs,
370 pxValues, &(data_.common_)) ;
371 }
372 else {
373 ::KLU2::klu_tsolve<klu2_dtype, local_ordinal_type>
374 (data_.symbolic_, data_.numeric_,
375 (local_ordinal_type)this->globalNumCols_,
376 (local_ordinal_type)nrhs,
377 pxValues, &(data_.common_)) ;
378 }
379 }
380 } // end root_
381 } //end else
382
383 // if bDidAssignX, then we solved straight to the adapter's X memory space without
384 // requiring additional memory allocation, so the x data is already in place.
385 if(!bDidAssignX) {
386#ifdef HAVE_AMESOS2_TIMERS
387 Teuchos::TimeMonitor redistTimer( this->timers_.vecRedistTime_ );
388#endif
389 if (use_gather) {
390 int rval = X->scatter(xValues_, this->perm_g2l, this->recvCountRows, this->recvDisplRows,
391 (is_contiguous_ == true) ? ROOTED : CONTIGUOUS_AND_ROOTED);
392 if (rval != 0) use_gather = false;
393 }
394 if (!use_gather) {
395 Util::put_1d_data_helper_kokkos_view<
396 MultiVecAdapter<Vector>,host_solve_array_t>::do_put(X, xValues_,
397 as<size_t>(ld_rhs),
398 (is_contiguous_ == true) ? ROOTED : CONTIGUOUS_AND_ROOTED,
399 this->rowIndexBase_);
400 }
401 }
402 if (debug_level_ > 0) {
403 if (debug_level_ == 1) {
404 X->description();
405 } else {
406 Teuchos::RCP<Teuchos::FancyOStream> fancy = Teuchos::fancyOStream(Teuchos::rcpFromRef(std::cout));
407 if (!is_null(X->getMap())) X->getMap()->describe(*fancy, Teuchos::VERB_EXTREME);
408 std::cout << std::endl;
409 X->describe(*fancy, Teuchos::VERB_EXTREME);
410 }
411 }
412 return(ierr);
413}
414
415
416template <class Matrix, class Vector>
417bool
419{
420 // The KLU2 factorization routines can handle square as well as
421 // rectangular matrices, but KLU2 can only apply the solve routines to
422 // square matrices, so we check the matrix for squareness.
423 return( this->matrixA_->getGlobalNumRows() == this->matrixA_->getGlobalNumCols() );
424}
425
426
427template <class Matrix, class Vector>
428void
429KLU2<Matrix,Vector>::setParameters_impl(const Teuchos::RCP<Teuchos::ParameterList> & parameterList )
430{
431 using Teuchos::RCP;
432 using Teuchos::getIntegralValue;
433 using Teuchos::ParameterEntryValidator;
434
435 RCP<const Teuchos::ParameterList> valid_params = getValidParameters_impl();
436
437 transFlag_ = this->control_.useTranspose_ ? 1: 0;
438 // The KLU2 transpose option can override the Amesos2 option
439 if( parameterList->isParameter("Trans") ){
440 RCP<const ParameterEntryValidator> trans_validator = valid_params->getEntry("Trans").validator();
441 parameterList->getEntry("Trans").setValidator(trans_validator);
442
443 transFlag_ = getIntegralValue<int>(*parameterList, "Trans");
444 }
445
446 if( parameterList->isParameter("IsContiguous") ){
447 is_contiguous_ = parameterList->get<bool>("IsContiguous");
448 }
449 if( parameterList->isParameter("UseCustomGather") ){
450 use_gather_ = parameterList->get<bool>("UseCustomGather");
451 }
452
453 if( parameterList->isParameter("DebugLevel") ){
454 debug_level_ = parameterList->get<int>("DebugLevel");
455 }
456}
457
458
459template <class Matrix, class Vector>
460Teuchos::RCP<const Teuchos::ParameterList>
462{
463 using std::string;
464 using Teuchos::tuple;
465 using Teuchos::ParameterList;
466 using Teuchos::setStringToIntegralParameter;
467
468 static Teuchos::RCP<const Teuchos::ParameterList> valid_params;
469
470 if( is_null(valid_params) )
471 {
472 Teuchos::RCP<Teuchos::ParameterList> pl = Teuchos::parameterList();
473
474 pl->set("Equil", true, "Whether to equilibrate the system before solve, does nothing now");
475 pl->set("IsContiguous", true, "Whether GIDs contiguous");
476 pl->set("UseCustomGather", true, "Whether to use new matrix-gather routine");
477 pl->set("DebugLevel", 0, "Debug message level (0 for no message, and >0 for more message");
478
479 setStringToIntegralParameter<int>("Trans", "NOTRANS",
480 "Solve for the transpose system or not",
481 tuple<string>("NOTRANS","TRANS","CONJ"),
482 tuple<string>("Solve with transpose",
483 "Do not solve with transpose",
484 "Solve with the conjugate transpose"),
485 tuple<int>(0, 1, 2),
486 pl.getRawPtr());
487 valid_params = pl;
488 }
489
490 return valid_params;
491}
492
493
494template <class Matrix, class Vector>
495bool
497{
498 using Teuchos::as;
499#ifdef HAVE_AMESOS2_TIMERS
500 Teuchos::TimeMonitor convTimer(this->timers_.mtxConvTime_);
501#endif
502
503 if(current_phase == SOLVE)return(false);
504 if (debug_level_ > 0 && current_phase == NUMFACT) {
505 if (this->root_) {
506 std::cout << "\n == Amesos2_KLU2::loadA_impl";
507 if (current_phase == PREORDERING) std::cout << "(PreOrder)";
508 if (current_phase == SYMBFACT) std::cout << "(SymFact)";
509 if (current_phase == NUMFACT) std::cout << "(NumFact)";
510 std::cout << " ==" << std::endl;
511 }
512 Teuchos::RCP<Teuchos::FancyOStream> fancy = Teuchos::fancyOStream(Teuchos::rcpFromRef(std::cout));
513 this->matrixA_->describe(*fancy, (debug_level_ == 1 ? Teuchos::VERB_LOW : Teuchos::VERB_EXTREME));
514 }
515
516 if ( single_proc_optimization() ) {
517 // Do nothing in this case - Crs raw pointers will be used
518 }
519 else
520 {
521 // Only the root image needs storage allocated
522 if( this->root_ ) {
523 if (host_nzvals_view_.extent(0) != this->globalNumNonZeros_)
524 Kokkos::resize(host_nzvals_view_, this->globalNumNonZeros_);
525 if (host_rows_view_.extent(0) != this->globalNumNonZeros_)
526 Kokkos::resize(host_rows_view_, this->globalNumNonZeros_);
527 if (host_col_ptr_view_.extent(0) != (this->globalNumRows_ + 1))
528 Kokkos::resize(host_col_ptr_view_, this->globalNumRows_ + 1);
529 }
530 local_ordinal_type nnz_ret = -1;
531 bool use_gather = use_gather_; // user param
532 use_gather = (use_gather && this->matrixA_->getComm()->getSize() > 1); // only with multiple MPIs
533 use_gather = (use_gather && (std::is_same<scalar_type, float>::value || std::is_same<scalar_type, double>::value)); // only for double or float
534 {
535#ifdef HAVE_AMESOS2_TIMERS
536 Teuchos::TimeMonitor mtxRedistTimer( this->timers_.mtxRedistTime_ );
537#endif
538 if (use_gather) {
539 bool column_major = true;
540 if (!is_contiguous_) {
541 auto contig_mat = this->matrixA_->reindex(this->contig_rowmap_, this->contig_colmap_, current_phase);
542 nnz_ret = contig_mat->gather(host_nzvals_view_, host_rows_view_, host_col_ptr_view_, this->perm_g2l, this->recvCountRows, this->recvDisplRows, this->recvCounts, this->recvDispls,
543 this->transpose_map, this->nzvals_t, column_major, current_phase);
544 } else {
545 nnz_ret = this->matrixA_->gather(host_nzvals_view_, host_rows_view_, host_col_ptr_view_, this->perm_g2l, this->recvCountRows, this->recvDisplRows, this->recvCounts, this->recvDispls,
546 this->transpose_map, this->nzvals_t, column_major, current_phase);
547 }
548 // gather failed (e.g., not implemened for KokkosCrsMatrix)
549 // in case of the failure, it falls back to the original "do_get"
550 if (nnz_ret < 0) use_gather = false;
551 }
552 if (!use_gather) {
554 MatrixAdapter<Matrix>,host_value_type_array,host_ordinal_type_array,host_ordinal_type_array>
555 ::do_get(this->matrixA_.ptr(), host_nzvals_view_, host_rows_view_, host_col_ptr_view_, nnz_ret,
556 (is_contiguous_ == true) ? ROOTED : CONTIGUOUS_AND_ROOTED,
557 ARBITRARY,
558 this->rowIndexBase_);
559 }
560 }
561
562 // gather return the total nnz_ret on every MPI process
563 if (use_gather || this->root_) {
564 TEUCHOS_TEST_FOR_EXCEPTION( nnz_ret != as<local_ordinal_type>(this->globalNumNonZeros_),
565 std::runtime_error,
566 "Amesos2_KLU2 loadA_impl: Did not get the expected number of non-zero vals("
567 +std::to_string(nnz_ret)+" vs "+std::to_string(this->globalNumNonZeros_)+")");
568 }
569 } //end else single_process_optim_check = false
570
571 return true;
572}
573
574
575template<class Matrix, class Vector>
576const char* KLU2<Matrix,Vector>::name = "KLU2";
577
578
579} // end namespace Amesos2
580
581#endif // AMESOS2_KLU2_DEF_HPP
Amesos2 KLU2 declarations.
@ ROOTED
Definition Amesos2_TypeDecl.hpp:93
@ CONTIGUOUS_AND_ROOTED
Definition Amesos2_TypeDecl.hpp:94
@ ARBITRARY
Definition Amesos2_TypeDecl.hpp:109
Amesos2 interface to the KLU2 package.
Definition Amesos2_KLU2_decl.hpp:39
KLU2(Teuchos::RCP< const Matrix > A, Teuchos::RCP< Vector > X, Teuchos::RCP< const Vector > B)
Initialize from Teuchos::RCP.
Definition Amesos2_KLU2_def.hpp:32
Teuchos::RCP< const Teuchos::ParameterList > getValidParameters_impl() const
Definition Amesos2_KLU2_def.hpp:461
bool single_proc_optimization() const
can we optimize size_type and ordinal_type for straight pass through, also check that is_contiguous_ ...
Definition Amesos2_KLU2_def.hpp:79
bool matrixShapeOK_impl() const
Determines whether the shape of the matrix is OK for this solver.
Definition Amesos2_KLU2_def.hpp:418
int symbolicFactorization_impl()
Perform symbolic factorization of the matrix using KLU2.
Definition Amesos2_KLU2_def.hpp:99
int preOrdering_impl()
Performs pre-ordering on the matrix to increase efficiency.
Definition Amesos2_KLU2_def.hpp:85
int solve_impl(const Teuchos::Ptr< MultiVecAdapter< Vector > > X, const Teuchos::Ptr< const MultiVecAdapter< Vector > > B) const
KLU2 specific solve.
Definition Amesos2_KLU2_def.hpp:210
~KLU2()
Destructor.
Definition Amesos2_KLU2_def.hpp:52
bool loadA_impl(EPhase current_phase)
Reads matrix data into internal structures.
Definition Amesos2_KLU2_def.hpp:496
int numericFactorization_impl()
KLU2 specific numeric factorization.
Definition Amesos2_KLU2_def.hpp:129
void setParameters_impl(const Teuchos::RCP< Teuchos::ParameterList > &parameterList)
Definition Amesos2_KLU2_def.hpp:429
A Matrix adapter interface for Amesos2.
Definition Amesos2_MatrixAdapter_decl.hpp:42
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
A generic helper class for getting a CCS representation of a Matrix.
Definition Amesos2_Util.hpp:589