Amesos2 - Direct Sparse Solver Interfaces  Version of the Day
Amesos2_Superlu_def.hpp
Go to the documentation of this file.
1 // @HEADER
2 //
3 // ***********************************************************************
4 //
5 // Amesos2: Templated Direct Sparse Solver Package
6 // Copyright 2011 Sandia Corporation
7 //
8 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
9 // the U.S. Government retains certain rights in this software.
10 //
11 // Redistribution and use in source and binary forms, with or without
12 // modification, are permitted provided that the following conditions are
13 // met:
14 //
15 // 1. Redistributions of source code must retain the above copyright
16 // notice, this list of conditions and the following disclaimer.
17 //
18 // 2. Redistributions in binary form must reproduce the above copyright
19 // notice, this list of conditions and the following disclaimer in the
20 // documentation and/or other materials provided with the distribution.
21 //
22 // 3. Neither the name of the Corporation nor the names of the
23 // contributors may be used to endorse or promote products derived from
24 // this software without specific prior written permission.
25 //
26 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
27 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
30 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 //
38 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
39 //
40 // ***********************************************************************
41 //
42 // @HEADER
43 
53 #ifndef AMESOS2_SUPERLU_DEF_HPP
54 #define AMESOS2_SUPERLU_DEF_HPP
55 
56 #include <Teuchos_Tuple.hpp>
57 #include <Teuchos_ParameterList.hpp>
58 #include <Teuchos_StandardParameterEntryValidators.hpp>
59 
61 #include "Amesos2_Superlu_decl.hpp"
62 
63 namespace Amesos2 {
64 
65 
66 template <class Matrix, class Vector>
68  Teuchos::RCP<const Matrix> A,
69  Teuchos::RCP<Vector> X,
70  Teuchos::RCP<const Vector> B )
71  : SolverCore<Amesos2::Superlu,Matrix,Vector>(A, X, B)
72  , nzvals_() // initialize to empty arrays
73  , rowind_()
74  , colptr_()
75 {
76  // ilu_set_default_options is called later in set parameter list if required.
77  // This is not the ideal way, but the other option to always call
78  // ilu_set_default_options here and assuming it won't have any side effect
79  // in the TPL is more dangerous. It is not a good idea to rely on external
80  // libraries' internal "features".
81  SLU::set_default_options(&(data_.options));
82  // Override some default options
83  data_.options.PrintStat = SLU::NO;
84 
85  SLU::StatInit(&(data_.stat));
86 
87  data_.perm_r.resize(this->globalNumRows_);
88  data_.perm_c.resize(this->globalNumCols_);
89  data_.etree.resize(this->globalNumCols_);
90  data_.R.resize(this->globalNumRows_);
91  data_.C.resize(this->globalNumCols_);
92 
93  data_.relax = SLU::sp_ienv(2); // Query optimal relax param from superlu
94  data_.panel_size = SLU::sp_ienv(1); // Query optimal panel size
95 
96  data_.equed = 'N'; // No equilibration
97  data_.A.Store = NULL;
98  data_.L.Store = NULL;
99  data_.U.Store = NULL;
100  data_.X.Store = NULL;
101  data_.B.Store = NULL;
102 
103  ILU_Flag_=false; // default: turn off ILU
104 }
105 
106 
107 template <class Matrix, class Vector>
109 {
110  /* Free Superlu data_types
111  * - Matrices
112  * - Vectors
113  * - Stat object
114  */
115  SLU::StatFree( &(data_.stat) ) ;
116 
117  // Storage is initialized in numericFactorization_impl()
118  if ( data_.A.Store != NULL ){
119  SLU::Destroy_SuperMatrix_Store( &(data_.A) );
120  }
121 
122  // only root allocated these SuperMatrices.
123  if ( data_.L.Store != NULL ){ // will only be true for this->root_
124  SLU::Destroy_SuperNode_Matrix( &(data_.L) );
125  SLU::Destroy_CompCol_Matrix( &(data_.U) );
126  }
127 }
128 
129 template <class Matrix, class Vector>
130 std::string
132 {
133  std::ostringstream oss;
134  oss << "SuperLU solver interface";
135  if (ILU_Flag_) {
136  oss << ", \"ILUTP\" : {";
137  oss << "drop tol = " << data_.options.ILU_DropTol;
138  oss << ", fill factor = " << data_.options.ILU_FillFactor;
139  oss << ", fill tol = " << data_.options.ILU_FillTol;
140  switch(data_.options.ILU_MILU) {
141  case SLU::SMILU_1 :
142  oss << ", MILU 1";
143  break;
144  case SLU::SMILU_2 :
145  oss << ", MILU 2";
146  break;
147  case SLU::SMILU_3 :
148  oss << ", MILU 3";
149  break;
150  case SLU::SILU :
151  default:
152  oss << ", regular ILU";
153  }
154  switch(data_.options.ILU_Norm) {
155  case SLU::ONE_NORM :
156  oss << ", 1-norm";
157  break;
158  case SLU::TWO_NORM :
159  oss << ", 2-norm";
160  break;
161  case SLU::INF_NORM :
162  default:
163  oss << ", infinity-norm";
164  }
165  oss << "}";
166  } else {
167  oss << ", direct solve";
168  }
169  return oss.str();
170  /*
171 
172  // ILU parameters
173  if( parameterList->isParameter("RowPerm") ){
174  RCP<const ParameterEntryValidator> rowperm_validator = valid_params->getEntry("RowPerm").validator();
175  parameterList->getEntry("RowPerm").setValidator(rowperm_validator);
176  data_.options.RowPerm = getIntegralValue<SLU::rowperm_t>(*parameterList, "RowPerm");
177  }
178 
179 
180  */
181 }
182 
183 template<class Matrix, class Vector>
184 int
186 {
187  /*
188  * Get column permutation vector perm_c[], according to permc_spec:
189  * permc_spec = NATURAL: natural ordering
190  * permc_spec = MMD_AT_PLUS_A: minimum degree on structure of A'+A
191  * permc_spec = MMD_ATA: minimum degree on structure of A'*A
192  * permc_spec = COLAMD: approximate minimum degree column ordering
193  * permc_spec = MY_PERMC: the ordering already supplied in perm_c[]
194  */
195  int permc_spec = data_.options.ColPerm;
196  if ( permc_spec != SLU::MY_PERMC && this->root_ ){
197 #ifdef HAVE_AMESOS2_TIMERS
198  Teuchos::TimeMonitor preOrderTimer(this->timers_.preOrderTime_);
199 #endif
200 
201  SLU::get_perm_c(permc_spec, &(data_.A), data_.perm_c.getRawPtr());
202  }
203 
204  return(0);
205 }
206 
207 
208 template <class Matrix, class Vector>
209 int
211 {
212  /*
213  * SuperLU performs symbolic factorization and numeric factorization
214  * together, but does leave some options for reusing symbolic
215  * structures that have been created on previous factorizations. If
216  * our Amesos2 user calls this function, that is an indication that
217  * the symbolic structure of the matrix is no longer valid, and
218  * SuperLU should do the factorization from scratch.
219  *
220  * This can be accomplished by setting the options.Fact flag to
221  * DOFACT, as well as setting our own internal flag to false.
222  */
223  same_symbolic_ = false;
224  data_.options.Fact = SLU::DOFACT;
225 
226  return(0);
227 }
228 
229 
230 template <class Matrix, class Vector>
231 int
233 {
234  using Teuchos::as;
235 
236  // Cleanup old L and U matrices if we are not reusing a symbolic
237  // factorization. Stores and other data will be allocated in gstrf.
238  // Only rank 0 has valid pointers
239  if ( !same_symbolic_ && data_.L.Store != NULL ){
240  SLU::Destroy_SuperNode_Matrix( &(data_.L) );
241  SLU::Destroy_CompCol_Matrix( &(data_.U) );
242  data_.L.Store = NULL;
243  data_.U.Store = NULL;
244  }
245 
246  if( same_symbolic_ ) data_.options.Fact = SLU::SamePattern_SameRowPerm;
247 
248  int info = 0;
249  if ( this->root_ ){
250 
251 #ifdef HAVE_AMESOS2_DEBUG
252  TEUCHOS_TEST_FOR_EXCEPTION( data_.A.ncol != as<int>(this->globalNumCols_),
253  std::runtime_error,
254  "Error in converting to SuperLU SuperMatrix: wrong number of global columns." );
255  TEUCHOS_TEST_FOR_EXCEPTION( data_.A.nrow != as<int>(this->globalNumRows_),
256  std::runtime_error,
257  "Error in converting to SuperLU SuperMatrix: wrong number of global rows." );
258 #endif
259 
260  if( data_.options.Equil == SLU::YES ){
261  magnitude_type rowcnd, colcnd, amax;
262  int info2 = 0;
263 
264  // calculate row and column scalings
265  function_map::gsequ(&(data_.A), data_.R.getRawPtr(),
266  data_.C.getRawPtr(), &rowcnd, &colcnd,
267  &amax, &info2);
268  TEUCHOS_TEST_FOR_EXCEPTION( info2 != 0,
269  std::runtime_error,
270  "SuperLU gsequ returned with status " << info2 );
271 
272  // apply row and column scalings if necessary
273  function_map::laqgs(&(data_.A), data_.R.getRawPtr(),
274  data_.C.getRawPtr(), rowcnd, colcnd,
275  amax, &(data_.equed));
276 
277  // // check what types of equilibration was actually done
278  // data_.rowequ = (data_.equed == 'R') || (data_.equed == 'B');
279  // data_.colequ = (data_.equed == 'C') || (data_.equed == 'B');
280  }
281 
282  // Apply the column permutation computed in preOrdering. Place the
283  // column-permuted matrix in AC
284  SLU::sp_preorder(&(data_.options), &(data_.A), data_.perm_c.getRawPtr(),
285  data_.etree.getRawPtr(), &(data_.AC));
286 
287  { // Do factorization
288 #ifdef HAVE_AMESOS2_TIMERS
289  Teuchos::TimeMonitor numFactTimer(this->timers_.numFactTime_);
290 #endif
291 
292 #ifdef HAVE_AMESOS2_VERBOSE_DEBUG
293  std::cout << "Superlu:: Before numeric factorization" << std::endl;
294  std::cout << "nzvals_ : " << nzvals_.toString() << std::endl;
295  std::cout << "rowind_ : " << rowind_.toString() << std::endl;
296  std::cout << "colptr_ : " << colptr_.toString() << std::endl;
297 #endif
298 
299  if(ILU_Flag_==false) {
300  function_map::gstrf(&(data_.options), &(data_.AC),
301  data_.relax, data_.panel_size, data_.etree.getRawPtr(),
302  NULL, 0, data_.perm_c.getRawPtr(), data_.perm_r.getRawPtr(),
303  &(data_.L), &(data_.U), &(data_.stat), &info);
304  }
305  else {
306  function_map::gsitrf(&(data_.options), &(data_.AC),
307  data_.relax, data_.panel_size, data_.etree.getRawPtr(),
308  NULL, 0, data_.perm_c.getRawPtr(), data_.perm_r.getRawPtr(),
309  &(data_.L), &(data_.U), &(data_.stat), &info);
310  }
311 
312  }
313  // Cleanup. AC data will be alloc'd again for next factorization (if at all)
314  SLU::Destroy_CompCol_Permuted( &(data_.AC) );
315 
316  // Set the number of non-zero values in the L and U factors
317  this->setNnzLU( as<size_t>(((SLU::SCformat*)data_.L.Store)->nnz +
318  ((SLU::NCformat*)data_.U.Store)->nnz) );
319  }
320 
321  /* All processes should have the same error code */
322  Teuchos::broadcast(*(this->matrixA_->getComm()), 0, &info);
323 
324  global_size_type info_st = as<global_size_type>(info);
325  TEUCHOS_TEST_FOR_EXCEPTION( (info_st > 0) && (info_st <= this->globalNumCols_),
326  std::runtime_error,
327  "Factorization complete, but matrix is singular. Division by zero eminent");
328  TEUCHOS_TEST_FOR_EXCEPTION( (info_st > 0) && (info_st > this->globalNumCols_),
329  std::runtime_error,
330  "Memory allocation failure in Superlu factorization");
331 
332  data_.options.Fact = SLU::FACTORED;
333  same_symbolic_ = true;
334 
335  return(info);
336 }
337 
338 
339 template <class Matrix, class Vector>
340 int
342  const Teuchos::Ptr<const MultiVecAdapter<Vector> > B) const
343 {
344  using Teuchos::as;
345 
346  const global_size_type ld_rhs = this->root_ ? X->getGlobalLength() : 0;
347  const size_t nrhs = X->getGlobalNumVectors();
348 
349  const size_t val_store_size = as<size_t>(ld_rhs * nrhs);
350  Teuchos::Array<slu_type> xValues(val_store_size);
351  Teuchos::Array<slu_type> bValues(val_store_size);
352 
353  { // Get values from RHS B
354 #ifdef HAVE_AMESOS2_TIMERS
355  Teuchos::TimeMonitor mvConvTimer(this->timers_.vecConvTime_);
356  Teuchos::TimeMonitor redistTimer( this->timers_.vecRedistTime_ );
357 #endif
359  slu_type>::do_get(B, bValues(),
360  as<size_t>(ld_rhs),
361  ROOTED, this->rowIndexBase_);
362  }
363 
364  int ierr = 0; // returned error code
365 
366  magnitude_type rpg, rcond;
367  if ( this->root_ ) {
368  data_.ferr.resize(nrhs);
369  data_.berr.resize(nrhs);
370 
371  {
372 #ifdef HAVE_AMESOS2_TIMERS
373  Teuchos::TimeMonitor mvConvTimer(this->timers_.vecConvTime_);
374 #endif
375  SLU::Dtype_t dtype = type_map::dtype;
376  int i_ld_rhs = as<int>(ld_rhs);
377  function_map::create_Dense_Matrix(&(data_.B), i_ld_rhs, as<int>(nrhs),
378  bValues.getRawPtr(), i_ld_rhs,
379  SLU::SLU_DN, dtype, SLU::SLU_GE);
380  function_map::create_Dense_Matrix(&(data_.X), i_ld_rhs, as<int>(nrhs),
381  xValues.getRawPtr(), i_ld_rhs,
382  SLU::SLU_DN, dtype, SLU::SLU_GE);
383  }
384 
385  // Note: the values of B and X (after solution) are adjusted
386  // appropriately within gssvx for row and column scalings.
387 
388  { // Do solve!
389 #ifdef HAVE_AMESOS2_TIMERS
390  Teuchos::TimeMonitor solveTimer(this->timers_.solveTime_);
391 #endif
392 
393  if(ILU_Flag_==false) {
394  function_map::gssvx(&(data_.options), &(data_.A),
395  data_.perm_c.getRawPtr(), data_.perm_r.getRawPtr(),
396  data_.etree.getRawPtr(), &(data_.equed), data_.R.getRawPtr(),
397  data_.C.getRawPtr(), &(data_.L), &(data_.U), NULL, 0, &(data_.B),
398  &(data_.X), &rpg, &rcond, data_.ferr.getRawPtr(),
399  data_.berr.getRawPtr(), &(data_.mem_usage), &(data_.stat), &ierr);
400  }
401  else {
402  function_map::gsisx(&(data_.options), &(data_.A),
403  data_.perm_c.getRawPtr(), data_.perm_r.getRawPtr(),
404  data_.etree.getRawPtr(), &(data_.equed), data_.R.getRawPtr(),
405  data_.C.getRawPtr(), &(data_.L), &(data_.U), NULL, 0, &(data_.B),
406  &(data_.X), &rpg, &rcond, &(data_.mem_usage), &(data_.stat), &ierr);
407  }
408 
409  }
410 
411  // Cleanup X and B stores
412  SLU::Destroy_SuperMatrix_Store( &(data_.X) );
413  SLU::Destroy_SuperMatrix_Store( &(data_.B) );
414  data_.X.Store = NULL;
415  data_.B.Store = NULL;
416  }
417 
418  /* All processes should have the same error code */
419  Teuchos::broadcast(*(this->getComm()), 0, &ierr);
420 
421  global_size_type ierr_st = as<global_size_type>(ierr);
422  TEUCHOS_TEST_FOR_EXCEPTION( ierr < 0,
423  std::invalid_argument,
424  "Argument " << -ierr << " to SuperLU xgssvx had illegal value" );
425  TEUCHOS_TEST_FOR_EXCEPTION( ierr > 0 && ierr_st <= this->globalNumCols_,
426  std::runtime_error,
427  "Factorization complete, but U is exactly singular" );
428  TEUCHOS_TEST_FOR_EXCEPTION( ierr > 0 && ierr_st > this->globalNumCols_ + 1,
429  std::runtime_error,
430  "SuperLU allocated " << ierr - this->globalNumCols_ << " bytes of "
431  "memory before allocation failure occured." );
432 
433  /* Update X's global values */
434  {
435 #ifdef HAVE_AMESOS2_TIMERS
436  Teuchos::TimeMonitor redistTimer(this->timers_.vecRedistTime_);
437 #endif
438 
440  MultiVecAdapter<Vector>,slu_type>::do_put(X, xValues(),
441  as<size_t>(ld_rhs),
442  ROOTED, this->rowIndexBase_);
443  }
444 
445 
446  return(ierr);
447 }
448 
449 
450 template <class Matrix, class Vector>
451 bool
453 {
454  // The Superlu factorization routines can handle square as well as
455  // rectangular matrices, but Superlu can only apply the solve routines to
456  // square matrices, so we check the matrix for squareness.
457  return( this->matrixA_->getGlobalNumRows() == this->matrixA_->getGlobalNumCols() );
458 }
459 
460 
461 template <class Matrix, class Vector>
462 void
463 Superlu<Matrix,Vector>::setParameters_impl(const Teuchos::RCP<Teuchos::ParameterList> & parameterList )
464 {
465  using Teuchos::RCP;
466  using Teuchos::getIntegralValue;
467  using Teuchos::ParameterEntryValidator;
468 
469  RCP<const Teuchos::ParameterList> valid_params = getValidParameters_impl();
470 
471  ILU_Flag_ = parameterList->get<bool>("ILU_Flag",false);
472  if (ILU_Flag_) {
473  SLU::ilu_set_default_options(&(data_.options));
474  // Override some default options
475  data_.options.PrintStat = SLU::NO;
476  }
477 
478  data_.options.Trans = this->control_.useTranspose_ ? SLU::TRANS : SLU::NOTRANS;
479  // The SuperLU transpose option can override the Amesos2 option
480  if( parameterList->isParameter("Trans") ){
481  RCP<const ParameterEntryValidator> trans_validator = valid_params->getEntry("Trans").validator();
482  parameterList->getEntry("Trans").setValidator(trans_validator);
483 
484  data_.options.Trans = getIntegralValue<SLU::trans_t>(*parameterList, "Trans");
485  }
486 
487  if( parameterList->isParameter("IterRefine") ){
488  RCP<const ParameterEntryValidator> refine_validator = valid_params->getEntry("IterRefine").validator();
489  parameterList->getEntry("IterRefine").setValidator(refine_validator);
490 
491  data_.options.IterRefine = getIntegralValue<SLU::IterRefine_t>(*parameterList, "IterRefine");
492  }
493 
494  if( parameterList->isParameter("ColPerm") ){
495  RCP<const ParameterEntryValidator> colperm_validator = valid_params->getEntry("ColPerm").validator();
496  parameterList->getEntry("ColPerm").setValidator(colperm_validator);
497 
498  data_.options.ColPerm = getIntegralValue<SLU::colperm_t>(*parameterList, "ColPerm");
499  }
500 
501  data_.options.DiagPivotThresh = parameterList->get<double>("DiagPivotThresh", 1.0);
502 
503  bool equil = parameterList->get<bool>("Equil", true);
504  data_.options.Equil = equil ? SLU::YES : SLU::NO;
505 
506  bool symmetric_mode = parameterList->get<bool>("SymmetricMode", false);
507  data_.options.SymmetricMode = symmetric_mode ? SLU::YES : SLU::NO;
508 
509  // ILU parameters
510  if( parameterList->isParameter("RowPerm") ){
511  RCP<const ParameterEntryValidator> rowperm_validator = valid_params->getEntry("RowPerm").validator();
512  parameterList->getEntry("RowPerm").setValidator(rowperm_validator);
513  data_.options.RowPerm = getIntegralValue<SLU::rowperm_t>(*parameterList, "RowPerm");
514  }
515 
516  /*if( parameterList->isParameter("ILU_DropRule") ) {
517  RCP<const ParameterEntryValidator> droprule_validator = valid_params->getEntry("ILU_DropRule").validator();
518  parameterList->getEntry("ILU_DropRule").setValidator(droprule_validator);
519  data_.options.ILU_DropRule = getIntegralValue<SLU::rule_t>(*parameterList, "ILU_DropRule");
520  }*/
521 
522  data_.options.ILU_DropTol = parameterList->get<double>("ILU_DropTol", 0.0001);
523 
524  data_.options.ILU_FillFactor = parameterList->get<double>("ILU_FillFactor", 10.0);
525 
526  if( parameterList->isParameter("ILU_Norm") ) {
527  RCP<const ParameterEntryValidator> norm_validator = valid_params->getEntry("ILU_Norm").validator();
528  parameterList->getEntry("ILU_Norm").setValidator(norm_validator);
529  data_.options.ILU_Norm = getIntegralValue<SLU::norm_t>(*parameterList, "ILU_Norm");
530  }
531 
532  if( parameterList->isParameter("ILU_MILU") ) {
533  RCP<const ParameterEntryValidator> milu_validator = valid_params->getEntry("ILU_MILU").validator();
534  parameterList->getEntry("ILU_MILU").setValidator(milu_validator);
535  data_.options.ILU_MILU = getIntegralValue<SLU::milu_t>(*parameterList, "ILU_MILU");
536  }
537 
538  data_.options.ILU_FillTol = parameterList->get<double>("ILU_FillTol", 0.01);
539 
540 }
541 
542 
543 template <class Matrix, class Vector>
544 Teuchos::RCP<const Teuchos::ParameterList>
546 {
547  using std::string;
548  using Teuchos::tuple;
549  using Teuchos::ParameterList;
550  using Teuchos::EnhancedNumberValidator;
551  using Teuchos::setStringToIntegralParameter;
552  using Teuchos::stringToIntegralParameterEntryValidator;
553 
554  static Teuchos::RCP<const Teuchos::ParameterList> valid_params;
555 
556  if( is_null(valid_params) ){
557  Teuchos::RCP<Teuchos::ParameterList> pl = Teuchos::parameterList();
558 
559  setStringToIntegralParameter<SLU::trans_t>("Trans", "NOTRANS",
560  "Solve for the transpose system or not",
561  tuple<string>("TRANS","NOTRANS","CONJ"),
562  tuple<string>("Solve with transpose",
563  "Do not solve with transpose",
564  "Solve with the conjugate transpose"),
565  tuple<SLU::trans_t>(SLU::TRANS,
566  SLU::NOTRANS,
567  SLU::CONJ),
568  pl.getRawPtr());
569 
570  setStringToIntegralParameter<SLU::IterRefine_t>("IterRefine", "NOREFINE",
571  "Type of iterative refinement to use",
572  tuple<string>("NOREFINE", "SLU_SINGLE", "SLU_DOUBLE"),
573  tuple<string>("Do not use iterative refinement",
574  "Do single iterative refinement",
575  "Do double iterative refinement"),
576  tuple<SLU::IterRefine_t>(SLU::NOREFINE,
577  SLU::SLU_SINGLE,
578  SLU::SLU_DOUBLE),
579  pl.getRawPtr());
580 
581  // Note: MY_PERMC not yet supported
582  setStringToIntegralParameter<SLU::colperm_t>("ColPerm", "COLAMD",
583  "Specifies how to permute the columns of the "
584  "matrix for sparsity preservation",
585  tuple<string>("NATURAL", "MMD_AT_PLUS_A",
586  "MMD_ATA", "COLAMD"),
587  tuple<string>("Natural ordering",
588  "Minimum degree ordering on A^T + A",
589  "Minimum degree ordering on A^T A",
590  "Approximate minimum degree column ordering"),
591  tuple<SLU::colperm_t>(SLU::NATURAL,
592  SLU::MMD_AT_PLUS_A,
593  SLU::MMD_ATA,
594  SLU::COLAMD),
595  pl.getRawPtr());
596 
597  Teuchos::RCP<EnhancedNumberValidator<double> > diag_pivot_thresh_validator
598  = Teuchos::rcp( new EnhancedNumberValidator<double>(0.0, 1.0) );
599  pl->set("DiagPivotThresh", 1.0,
600  "Specifies the threshold used for a diagonal entry to be an acceptable pivot",
601  diag_pivot_thresh_validator); // partial pivoting
602 
603  pl->set("Equil", true, "Whether to equilibrate the system before solve");
604 
605  pl->set("SymmetricMode", false,
606  "Specifies whether to use the symmetric mode. "
607  "Gives preference to diagonal pivots and uses "
608  "an (A^T + A)-based column permutation.");
609 
610  // ILU parameters
611 
612  setStringToIntegralParameter<SLU::rowperm_t>("RowPerm", "LargeDiag",
613  "Type of row permutation strategy to use",
614  tuple<string>("NOROWPERM","LargeDiag","MY_PERMR"),
615  tuple<string>("Use natural ordering",
616  "Use weighted bipartite matching algorithm",
617  "Use the ordering given in perm_r input"),
618  tuple<SLU::rowperm_t>(SLU::NOROWPERM,
619  SLU::LargeDiag,
620  SLU::MY_PERMR),
621  pl.getRawPtr());
622 
623  /*setStringToIntegralParameter<SLU::rule_t>("ILU_DropRule", "DROP_BASIC",
624  "Type of dropping strategy to use",
625  tuple<string>("DROP_BASIC","DROP_PROWS",
626  "DROP_COLUMN","DROP_AREA",
627  "DROP_DYNAMIC","DROP_INTERP"),
628  tuple<string>("ILUTP(t)","ILUTP(p,t)",
629  "Variant of ILUTP(p,t) for j-th column",
630  "Variant of ILUTP to control memory",
631  "Dynamically adjust threshold",
632  "Compute second dropping threshold by interpolation"),
633  tuple<SLU::rule_t>(SLU::DROP_BASIC,SLU::DROP_PROWS,SLU::DROP_COLUMN,
634  SLU::DROP_AREA,SLU::DROP_DYNAMIC,SLU::DROP_INTERP),
635  pl.getRawPtr());*/
636 
637  pl->set("ILU_DropTol", 0.0001, "ILUT drop tolerance");
638 
639  pl->set("ILU_FillFactor", 10.0, "ILUT fill factor");
640 
641  setStringToIntegralParameter<SLU::norm_t>("ILU_Norm", "INF_NORM",
642  "Type of norm to use",
643  tuple<string>("ONE_NORM","TWO_NORM","INF_NORM"),
644  tuple<string>("1-norm","2-norm","inf-norm"),
645  tuple<SLU::norm_t>(SLU::ONE_NORM,SLU::TWO_NORM,SLU::INF_NORM),
646  pl.getRawPtr());
647 
648  setStringToIntegralParameter<SLU::milu_t>("ILU_MILU", "SILU",
649  "Type of modified ILU to use",
650  tuple<string>("SILU","SMILU_1","SMILU_2","SMILU_3"),
651  tuple<string>("Regular ILU","MILU 1","MILU 2","MILU 3"),
652  tuple<SLU::milu_t>(SLU::SILU,SLU::SMILU_1,SLU::SMILU_2,
653  SLU::SMILU_3),
654  pl.getRawPtr());
655 
656  pl->set("ILU_FillTol", 0.01, "ILUT fill tolerance");
657 
658  pl->set("ILU_Flag", false, "ILU flag: if true, run ILU routines");
659 
660  valid_params = pl;
661  }
662 
663  return valid_params;
664 }
665 
666 
667 template <class Matrix, class Vector>
668 bool
670 {
671  using Teuchos::as;
672 
673 #ifdef HAVE_AMESOS2_TIMERS
674  Teuchos::TimeMonitor convTimer(this->timers_.mtxConvTime_);
675 #endif
676 
677  // SuperLU does not need the matrix at symbolicFactorization()
678  if( current_phase == SYMBFACT ) return false;
679 
680  // Cleanup old store memory if it's non-NULL (should only ever be non-NULL at root_)
681  if( data_.A.Store != NULL ){
682  SLU::Destroy_SuperMatrix_Store( &(data_.A) );
683  data_.A.Store = NULL;
684  }
685 
686  // Only the root image needs storage allocated
687  if( this->root_ ){
688  nzvals_.resize(this->globalNumNonZeros_);
689  rowind_.resize(this->globalNumNonZeros_);
690  colptr_.resize(this->globalNumCols_ + 1);
691  }
692 
693  int nnz_ret = 0;
694  {
695 #ifdef HAVE_AMESOS2_TIMERS
696  Teuchos::TimeMonitor mtxRedistTimer( this->timers_.mtxRedistTime_ );
697 #endif
698 
699  TEUCHOS_TEST_FOR_EXCEPTION( this->rowIndexBase_ != this->columnIndexBase_,
700  std::runtime_error,
701  "Row and column maps have different indexbase ");
703  MatrixAdapter<Matrix>,slu_type,int,int>::do_get(this->matrixA_.ptr(),
704  nzvals_(), rowind_(),
705  colptr_(), nnz_ret, ROOTED,
706  ARBITRARY,
707  this->rowIndexBase_);
708  }
709 
710  // Get the SLU data type for this type of matrix
711  SLU::Dtype_t dtype = type_map::dtype;
712 
713  if( this->root_ ){
714  TEUCHOS_TEST_FOR_EXCEPTION( nnz_ret != as<int>(this->globalNumNonZeros_),
715  std::runtime_error,
716  "Did not get the expected number of non-zero vals");
717 
718  function_map::create_CompCol_Matrix( &(data_.A),
719  this->globalNumRows_, this->globalNumCols_,
720  nnz_ret,
721  nzvals_.getRawPtr(),
722  rowind_.getRawPtr(),
723  colptr_.getRawPtr(),
724  SLU::SLU_NC, dtype, SLU::SLU_GE);
725  }
726 
727  return true;
728 }
729 
730 
731 template<class Matrix, class Vector>
732 const char* Superlu<Matrix,Vector>::name = "SuperLU";
733 
734 
735 } // end namespace Amesos2
736 
737 #endif // AMESOS2_SUPERLU_DEF_HPP
Amesos2::SolverCore: A templated interface for interaction with third-party direct sparse solvers...
Definition: Amesos2_SolverCore_decl.hpp:105
Teuchos::Array< slu_type > nzvals_
Stores the values of the nonzero entries for SuperLU.
Definition: Amesos2_Superlu_decl.hpp:259
bool loadA_impl(EPhase current_phase)
Reads matrix data into internal structures.
Definition: Amesos2_Superlu_def.hpp:669
EPhase
Used to indicate a phase in the direct solution.
Definition: Amesos2_TypeDecl.hpp:65
Teuchos::Array< int > colptr_
Stores the row indices of the nonzero entries.
Definition: Amesos2_Superlu_decl.hpp:263
int numericFactorization_impl()
Superlu specific numeric factorization.
Definition: Amesos2_Superlu_def.hpp:232
global_size_type columnIndexBase_
Index base of column map of matrixA_.
Definition: Amesos2_SolverCore_decl.hpp:488
global_size_type globalNumCols_
Number of global columns in matrixA_.
Definition: Amesos2_SolverCore_decl.hpp:479
~Superlu()
Destructor.
Definition: Amesos2_Superlu_def.hpp:108
Teuchos::Array< int > rowind_
Stores the location in Ai_ and Aval_ that starts row j.
Definition: Amesos2_Superlu_decl.hpp:261
bool root_
If true, then this is the root processor.
Definition: Amesos2_SolverCore_decl.hpp:507
global_size_type globalNumRows_
Number of global rows in matrixA_.
Definition: Amesos2_SolverCore_decl.hpp:476
Amesos2 Superlu declarations.
bool matrixShapeOK_impl() const
Determines whether the shape of the matrix is OK for this solver.
Definition: Amesos2_Superlu_def.hpp:452
Helper class for getting 1-D copies of multivectors.
Definition: Amesos2_MultiVecAdapter_decl.hpp:243
Definition: Amesos2_TypeDecl.hpp:142
Superlu(Teuchos::RCP< const Matrix > A, Teuchos::RCP< Vector > X, Teuchos::RCP< const Vector > B)
Initialize from Teuchos::RCP.
Definition: Amesos2_Superlu_def.hpp:67
Control control_
Parameters for solving.
Definition: Amesos2_SolverCore_decl.hpp:495
Teuchos::RCP< const Teuchos::ParameterList > getValidParameters_impl() const
Definition: Amesos2_Superlu_def.hpp:545
Definition: Amesos2_AbstractConcreteMatrixAdapter.hpp:48
A generic helper class for getting a CCS representation of a Matrix.
Definition: Amesos2_Util.hpp:580
int solve_impl(const Teuchos::Ptr< MultiVecAdapter< Vector > > X, const Teuchos::Ptr< const MultiVecAdapter< Vector > > B) const
Superlu specific solve.
Definition: Amesos2_Superlu_def.hpp:341
Teuchos::RCP< const Teuchos::Comm< int > > getComm() const
Returns a pointer to the Teuchos::Comm communicator with this operator.
Definition: Amesos2_SolverCore_decl.hpp:363
A Matrix adapter interface for Amesos2.
Definition: Amesos2_MatrixAdapter_decl.hpp:76
global_size_type globalNumNonZeros_
Number of global non-zero values in matrixA_.
Definition: Amesos2_SolverCore_decl.hpp:482
void setNnzLU(size_t nnz)
Set the number of non-zero values in the and factors.
Definition: Amesos2_SolverCore_decl.hpp:452
Definition: Amesos2_TypeDecl.hpp:127
void setParameters_impl(const Teuchos::RCP< Teuchos::ParameterList > &parameterList)
Definition: Amesos2_Superlu_def.hpp:463
Timers timers_
Various timing statistics.
Definition: Amesos2_SolverCore_decl.hpp:498
int preOrdering_impl()
Performs pre-ordering on the matrix to increase efficiency.
Definition: Amesos2_Superlu_def.hpp:185
Helper class for putting 1-D data arrays into multivectors.
Definition: Amesos2_MultiVecAdapter_decl.hpp:296
A templated MultiVector class adapter for Amesos2.
Definition: Amesos2_MultiVecAdapter_decl.hpp:175
Teuchos::RCP< const MatrixAdapter< Matrix > > matrixA_
The LHS operator.
Definition: Amesos2_SolverCore_decl.hpp:455
std::string description() const
Returns a short description of this Solver.
Definition: Amesos2_Superlu_def.hpp:131
global_size_type rowIndexBase_
Index base of rowmap of matrixA_.
Definition: Amesos2_SolverCore_decl.hpp:485
int symbolicFactorization_impl()
Perform symbolic factorization of the matrix using Superlu.
Definition: Amesos2_Superlu_def.hpp:210
Amesos2 interface to the SuperLU package.
Definition: Amesos2_Superlu_decl.hpp:73