|
Amesos2 - Direct Sparse Solver Interfaces
Version of the Day
|
00001 // @HEADER 00002 // 00003 // *********************************************************************** 00004 // 00005 // Amesos2: Templated Direct Sparse Solver Package 00006 // Copyright 2011 Sandia Corporation 00007 // 00008 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, 00009 // the U.S. Government retains certain rights in this software. 00010 // 00011 // Redistribution and use in source and binary forms, with or without 00012 // modification, are permitted provided that the following conditions are 00013 // met: 00014 // 00015 // 1. Redistributions of source code must retain the above copyright 00016 // notice, this list of conditions and the following disclaimer. 00017 // 00018 // 2. Redistributions in binary form must reproduce the above copyright 00019 // notice, this list of conditions and the following disclaimer in the 00020 // documentation and/or other materials provided with the distribution. 00021 // 00022 // 3. Neither the name of the Corporation nor the names of the 00023 // contributors may be used to endorse or promote products derived from 00024 // this software without specific prior written permission. 00025 // 00026 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY 00027 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00028 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 00029 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE 00030 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00031 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00032 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00033 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00034 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00035 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00036 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00037 // 00038 // Questions? Contact Michael A. Heroux (maherou@sandia.gov) 00039 // 00040 // *********************************************************************** 00041 // 00042 // @HEADER 00043 00053 #ifndef AMESOS2_SUPERLU_DEF_HPP 00054 #define AMESOS2_SUPERLU_DEF_HPP 00055 00056 #include <Teuchos_Tuple.hpp> 00057 #include <Teuchos_ParameterList.hpp> 00058 #include <Teuchos_StandardParameterEntryValidators.hpp> 00059 00060 #include "Amesos2_SolverCore_def.hpp" 00061 #include "Amesos2_Superlu_decl.hpp" 00062 00063 namespace Amesos2 { 00064 00065 00066 template <class Matrix, class Vector> 00067 Superlu<Matrix,Vector>::Superlu( 00068 Teuchos::RCP<const Matrix> A, 00069 Teuchos::RCP<Vector> X, 00070 Teuchos::RCP<const Vector> B ) 00071 : SolverCore<Amesos2::Superlu,Matrix,Vector>(A, X, B) 00072 , nzvals_() // initialize to empty arrays 00073 , rowind_() 00074 , colptr_() 00075 { 00076 // ilu_set_default_options is called later in set parameter list if required. 00077 // This is not the ideal way, but the other option to always call 00078 // ilu_set_default_options here and assuming it won't have any side effect 00079 // in the TPL is more dangerous. It is not a good idea to rely on external 00080 // libraries' internal "features". 00081 SLU::set_default_options(&(data_.options)); 00082 // Override some default options 00083 data_.options.PrintStat = SLU::NO; 00084 00085 SLU::StatInit(&(data_.stat)); 00086 00087 data_.perm_r.resize(this->globalNumRows_); 00088 data_.perm_c.resize(this->globalNumCols_); 00089 data_.etree.resize(this->globalNumCols_); 00090 data_.R.resize(this->globalNumRows_); 00091 data_.C.resize(this->globalNumCols_); 00092 00093 data_.relax = SLU::sp_ienv(2); // Query optimal relax param from superlu 00094 data_.panel_size = SLU::sp_ienv(1); // Query optimal panel size 00095 00096 data_.equed = 'N'; // No equilibration 00097 data_.A.Store = NULL; 00098 data_.L.Store = NULL; 00099 data_.U.Store = NULL; 00100 data_.X.Store = NULL; 00101 data_.B.Store = NULL; 00102 00103 ILU_Flag_=false; // default: turn off ILU 00104 } 00105 00106 00107 template <class Matrix, class Vector> 00108 Superlu<Matrix,Vector>::~Superlu( ) 00109 { 00110 /* Free Superlu data_types 00111 * - Matrices 00112 * - Vectors 00113 * - Stat object 00114 */ 00115 SLU::StatFree( &(data_.stat) ) ; 00116 00117 // Storage is initialized in numericFactorization_impl() 00118 if ( data_.A.Store != NULL ){ 00119 SLU::Destroy_SuperMatrix_Store( &(data_.A) ); 00120 } 00121 00122 // only root allocated these SuperMatrices. 00123 if ( data_.L.Store != NULL ){ // will only be true for this->root_ 00124 SLU::Destroy_SuperNode_Matrix( &(data_.L) ); 00125 SLU::Destroy_CompCol_Matrix( &(data_.U) ); 00126 } 00127 } 00128 00129 template <class Matrix, class Vector> 00130 std::string 00131 Superlu<Matrix,Vector>::description() const 00132 { 00133 std::ostringstream oss; 00134 oss << "SuperLU solver interface"; 00135 if (ILU_Flag_) { 00136 oss << ", \"ILUTP\" : {"; 00137 oss << "drop tol = " << data_.options.ILU_DropTol; 00138 oss << ", fill factor = " << data_.options.ILU_FillFactor; 00139 oss << ", fill tol = " << data_.options.ILU_FillTol; 00140 switch(data_.options.ILU_MILU) { 00141 case SLU::SMILU_1 : 00142 oss << ", MILU 1"; 00143 break; 00144 case SLU::SMILU_2 : 00145 oss << ", MILU 2"; 00146 break; 00147 case SLU::SMILU_3 : 00148 oss << ", MILU 3"; 00149 break; 00150 case SLU::SILU : 00151 default: 00152 oss << ", regular ILU"; 00153 } 00154 switch(data_.options.ILU_Norm) { 00155 case SLU::ONE_NORM : 00156 oss << ", 1-norm"; 00157 break; 00158 case SLU::TWO_NORM : 00159 oss << ", 2-norm"; 00160 break; 00161 case SLU::INF_NORM : 00162 default: 00163 oss << ", infinity-norm"; 00164 } 00165 oss << "}"; 00166 } else { 00167 oss << ", direct solve"; 00168 } 00169 return oss.str(); 00170 /* 00171 00172 // ILU parameters 00173 if( parameterList->isParameter("RowPerm") ){ 00174 RCP<const ParameterEntryValidator> rowperm_validator = valid_params->getEntry("RowPerm").validator(); 00175 parameterList->getEntry("RowPerm").setValidator(rowperm_validator); 00176 data_.options.RowPerm = getIntegralValue<SLU::rowperm_t>(*parameterList, "RowPerm"); 00177 } 00178 00179 00180 */ 00181 } 00182 00183 template<class Matrix, class Vector> 00184 int 00185 Superlu<Matrix,Vector>::preOrdering_impl() 00186 { 00187 /* 00188 * Get column permutation vector perm_c[], according to permc_spec: 00189 * permc_spec = NATURAL: natural ordering 00190 * permc_spec = MMD_AT_PLUS_A: minimum degree on structure of A'+A 00191 * permc_spec = MMD_ATA: minimum degree on structure of A'*A 00192 * permc_spec = COLAMD: approximate minimum degree column ordering 00193 * permc_spec = MY_PERMC: the ordering already supplied in perm_c[] 00194 */ 00195 int permc_spec = data_.options.ColPerm; 00196 if ( permc_spec != SLU::MY_PERMC && this->root_ ){ 00197 #ifdef HAVE_AMESOS2_TIMERS 00198 Teuchos::TimeMonitor preOrderTimer(this->timers_.preOrderTime_); 00199 #endif 00200 00201 SLU::get_perm_c(permc_spec, &(data_.A), data_.perm_c.getRawPtr()); 00202 } 00203 00204 return(0); 00205 } 00206 00207 00208 template <class Matrix, class Vector> 00209 int 00210 Superlu<Matrix,Vector>::symbolicFactorization_impl() 00211 { 00212 /* 00213 * SuperLU performs symbolic factorization and numeric factorization 00214 * together, but does leave some options for reusing symbolic 00215 * structures that have been created on previous factorizations. If 00216 * our Amesos2 user calls this function, that is an indication that 00217 * the symbolic structure of the matrix is no longer valid, and 00218 * SuperLU should do the factorization from scratch. 00219 * 00220 * This can be accomplished by setting the options.Fact flag to 00221 * DOFACT, as well as setting our own internal flag to false. 00222 */ 00223 same_symbolic_ = false; 00224 data_.options.Fact = SLU::DOFACT; 00225 00226 return(0); 00227 } 00228 00229 00230 template <class Matrix, class Vector> 00231 int 00232 Superlu<Matrix,Vector>::numericFactorization_impl() 00233 { 00234 using Teuchos::as; 00235 00236 // Cleanup old L and U matrices if we are not reusing a symbolic 00237 // factorization. Stores and other data will be allocated in gstrf. 00238 // Only rank 0 has valid pointers 00239 if ( !same_symbolic_ && data_.L.Store != NULL ){ 00240 SLU::Destroy_SuperNode_Matrix( &(data_.L) ); 00241 SLU::Destroy_CompCol_Matrix( &(data_.U) ); 00242 data_.L.Store = NULL; 00243 data_.U.Store = NULL; 00244 } 00245 00246 if( same_symbolic_ ) data_.options.Fact = SLU::SamePattern_SameRowPerm; 00247 00248 int info = 0; 00249 if ( this->root_ ){ 00250 00251 #ifdef HAVE_AMESOS2_DEBUG 00252 TEUCHOS_TEST_FOR_EXCEPTION( data_.A.ncol != as<int>(this->globalNumCols_), 00253 std::runtime_error, 00254 "Error in converting to SuperLU SuperMatrix: wrong number of global columns." ); 00255 TEUCHOS_TEST_FOR_EXCEPTION( data_.A.nrow != as<int>(this->globalNumRows_), 00256 std::runtime_error, 00257 "Error in converting to SuperLU SuperMatrix: wrong number of global rows." ); 00258 #endif 00259 00260 if( data_.options.Equil == SLU::YES ){ 00261 magnitude_type rowcnd, colcnd, amax; 00262 int info2 = 0; 00263 00264 // calculate row and column scalings 00265 function_map::gsequ(&(data_.A), data_.R.getRawPtr(), 00266 data_.C.getRawPtr(), &rowcnd, &colcnd, 00267 &amax, &info2); 00268 TEUCHOS_TEST_FOR_EXCEPTION( info2 != 0, 00269 std::runtime_error, 00270 "SuperLU gsequ returned with status " << info2 ); 00271 00272 // apply row and column scalings if necessary 00273 function_map::laqgs(&(data_.A), data_.R.getRawPtr(), 00274 data_.C.getRawPtr(), rowcnd, colcnd, 00275 amax, &(data_.equed)); 00276 00277 // // check what types of equilibration was actually done 00278 // data_.rowequ = (data_.equed == 'R') || (data_.equed == 'B'); 00279 // data_.colequ = (data_.equed == 'C') || (data_.equed == 'B'); 00280 } 00281 00282 // Apply the column permutation computed in preOrdering. Place the 00283 // column-permuted matrix in AC 00284 SLU::sp_preorder(&(data_.options), &(data_.A), data_.perm_c.getRawPtr(), 00285 data_.etree.getRawPtr(), &(data_.AC)); 00286 00287 { // Do factorization 00288 #ifdef HAVE_AMESOS2_TIMERS 00289 Teuchos::TimeMonitor numFactTimer(this->timers_.numFactTime_); 00290 #endif 00291 00292 #ifdef HAVE_AMESOS2_VERBOSE_DEBUG 00293 std::cout << "Superlu:: Before numeric factorization" << std::endl; 00294 std::cout << "nzvals_ : " << nzvals_.toString() << std::endl; 00295 std::cout << "rowind_ : " << rowind_.toString() << std::endl; 00296 std::cout << "colptr_ : " << colptr_.toString() << std::endl; 00297 #endif 00298 00299 if(ILU_Flag_==false) { 00300 function_map::gstrf(&(data_.options), &(data_.AC), 00301 data_.relax, data_.panel_size, data_.etree.getRawPtr(), 00302 NULL, 0, data_.perm_c.getRawPtr(), data_.perm_r.getRawPtr(), 00303 &(data_.L), &(data_.U), &(data_.stat), &info); 00304 } 00305 else { 00306 function_map::gsitrf(&(data_.options), &(data_.AC), 00307 data_.relax, data_.panel_size, data_.etree.getRawPtr(), 00308 NULL, 0, data_.perm_c.getRawPtr(), data_.perm_r.getRawPtr(), 00309 &(data_.L), &(data_.U), &(data_.stat), &info); 00310 } 00311 00312 } 00313 // Cleanup. AC data will be alloc'd again for next factorization (if at all) 00314 SLU::Destroy_CompCol_Permuted( &(data_.AC) ); 00315 00316 // Set the number of non-zero values in the L and U factors 00317 this->setNnzLU( as<size_t>(((SLU::SCformat*)data_.L.Store)->nnz + 00318 ((SLU::NCformat*)data_.U.Store)->nnz) ); 00319 } 00320 00321 /* All processes should have the same error code */ 00322 Teuchos::broadcast(*(this->matrixA_->getComm()), 0, &info); 00323 00324 global_size_type info_st = as<global_size_type>(info); 00325 TEUCHOS_TEST_FOR_EXCEPTION( (info_st > 0) && (info_st <= this->globalNumCols_), 00326 std::runtime_error, 00327 "Factorization complete, but matrix is singular. Division by zero eminent"); 00328 TEUCHOS_TEST_FOR_EXCEPTION( (info_st > 0) && (info_st > this->globalNumCols_), 00329 std::runtime_error, 00330 "Memory allocation failure in Superlu factorization"); 00331 00332 data_.options.Fact = SLU::FACTORED; 00333 same_symbolic_ = true; 00334 00335 return(info); 00336 } 00337 00338 00339 template <class Matrix, class Vector> 00340 int 00341 Superlu<Matrix,Vector>::solve_impl(const Teuchos::Ptr<MultiVecAdapter<Vector> > X, 00342 const Teuchos::Ptr<const MultiVecAdapter<Vector> > B) const 00343 { 00344 using Teuchos::as; 00345 00346 const global_size_type ld_rhs = this->root_ ? X->getGlobalLength() : 0; 00347 const size_t nrhs = X->getGlobalNumVectors(); 00348 00349 const size_t val_store_size = as<size_t>(ld_rhs * nrhs); 00350 Teuchos::Array<slu_type> xValues(val_store_size); 00351 Teuchos::Array<slu_type> bValues(val_store_size); 00352 00353 { // Get values from RHS B 00354 #ifdef HAVE_AMESOS2_TIMERS 00355 Teuchos::TimeMonitor mvConvTimer(this->timers_.vecConvTime_); 00356 Teuchos::TimeMonitor redistTimer( this->timers_.vecRedistTime_ ); 00357 #endif 00358 Util::get_1d_copy_helper<MultiVecAdapter<Vector>, 00359 slu_type>::do_get(B, bValues(), 00360 as<size_t>(ld_rhs), 00361 ROOTED, this->rowIndexBase_); 00362 } 00363 00364 int ierr = 0; // returned error code 00365 00366 magnitude_type rpg, rcond; 00367 if ( this->root_ ) { 00368 data_.ferr.resize(nrhs); 00369 data_.berr.resize(nrhs); 00370 00371 { 00372 #ifdef HAVE_AMESOS2_TIMERS 00373 Teuchos::TimeMonitor mvConvTimer(this->timers_.vecConvTime_); 00374 #endif 00375 SLU::Dtype_t dtype = type_map::dtype; 00376 int i_ld_rhs = as<int>(ld_rhs); 00377 function_map::create_Dense_Matrix(&(data_.B), i_ld_rhs, as<int>(nrhs), 00378 bValues.getRawPtr(), i_ld_rhs, 00379 SLU::SLU_DN, dtype, SLU::SLU_GE); 00380 function_map::create_Dense_Matrix(&(data_.X), i_ld_rhs, as<int>(nrhs), 00381 xValues.getRawPtr(), i_ld_rhs, 00382 SLU::SLU_DN, dtype, SLU::SLU_GE); 00383 } 00384 00385 // Note: the values of B and X (after solution) are adjusted 00386 // appropriately within gssvx for row and column scalings. 00387 00388 { // Do solve! 00389 #ifdef HAVE_AMESOS2_TIMERS 00390 Teuchos::TimeMonitor solveTimer(this->timers_.solveTime_); 00391 #endif 00392 00393 if(ILU_Flag_==false) { 00394 function_map::gssvx(&(data_.options), &(data_.A), 00395 data_.perm_c.getRawPtr(), data_.perm_r.getRawPtr(), 00396 data_.etree.getRawPtr(), &(data_.equed), data_.R.getRawPtr(), 00397 data_.C.getRawPtr(), &(data_.L), &(data_.U), NULL, 0, &(data_.B), 00398 &(data_.X), &rpg, &rcond, data_.ferr.getRawPtr(), 00399 data_.berr.getRawPtr(), &(data_.mem_usage), &(data_.stat), &ierr); 00400 } 00401 else { 00402 function_map::gsisx(&(data_.options), &(data_.A), 00403 data_.perm_c.getRawPtr(), data_.perm_r.getRawPtr(), 00404 data_.etree.getRawPtr(), &(data_.equed), data_.R.getRawPtr(), 00405 data_.C.getRawPtr(), &(data_.L), &(data_.U), NULL, 0, &(data_.B), 00406 &(data_.X), &rpg, &rcond, &(data_.mem_usage), &(data_.stat), &ierr); 00407 } 00408 00409 } 00410 00411 // Cleanup X and B stores 00412 SLU::Destroy_SuperMatrix_Store( &(data_.X) ); 00413 SLU::Destroy_SuperMatrix_Store( &(data_.B) ); 00414 data_.X.Store = NULL; 00415 data_.B.Store = NULL; 00416 } 00417 00418 /* All processes should have the same error code */ 00419 Teuchos::broadcast(*(this->getComm()), 0, &ierr); 00420 00421 global_size_type ierr_st = as<global_size_type>(ierr); 00422 TEUCHOS_TEST_FOR_EXCEPTION( ierr < 0, 00423 std::invalid_argument, 00424 "Argument " << -ierr << " to SuperLU xgssvx had illegal value" ); 00425 TEUCHOS_TEST_FOR_EXCEPTION( ierr > 0 && ierr_st <= this->globalNumCols_, 00426 std::runtime_error, 00427 "Factorization complete, but U is exactly singular" ); 00428 TEUCHOS_TEST_FOR_EXCEPTION( ierr > 0 && ierr_st > this->globalNumCols_ + 1, 00429 std::runtime_error, 00430 "SuperLU allocated " << ierr - this->globalNumCols_ << " bytes of " 00431 "memory before allocation failure occured." ); 00432 00433 /* Update X's global values */ 00434 { 00435 #ifdef HAVE_AMESOS2_TIMERS 00436 Teuchos::TimeMonitor redistTimer(this->timers_.vecRedistTime_); 00437 #endif 00438 00439 Util::put_1d_data_helper< 00440 MultiVecAdapter<Vector>,slu_type>::do_put(X, xValues(), 00441 as<size_t>(ld_rhs), 00442 ROOTED, this->rowIndexBase_); 00443 } 00444 00445 00446 return(ierr); 00447 } 00448 00449 00450 template <class Matrix, class Vector> 00451 bool 00452 Superlu<Matrix,Vector>::matrixShapeOK_impl() const 00453 { 00454 // The Superlu factorization routines can handle square as well as 00455 // rectangular matrices, but Superlu can only apply the solve routines to 00456 // square matrices, so we check the matrix for squareness. 00457 return( this->matrixA_->getGlobalNumRows() == this->matrixA_->getGlobalNumCols() ); 00458 } 00459 00460 00461 template <class Matrix, class Vector> 00462 void 00463 Superlu<Matrix,Vector>::setParameters_impl(const Teuchos::RCP<Teuchos::ParameterList> & parameterList ) 00464 { 00465 using Teuchos::RCP; 00466 using Teuchos::getIntegralValue; 00467 using Teuchos::ParameterEntryValidator; 00468 00469 RCP<const Teuchos::ParameterList> valid_params = getValidParameters_impl(); 00470 00471 ILU_Flag_ = parameterList->get<bool>("ILU_Flag",false); 00472 if (ILU_Flag_) { 00473 SLU::ilu_set_default_options(&(data_.options)); 00474 // Override some default options 00475 data_.options.PrintStat = SLU::NO; 00476 } 00477 00478 data_.options.Trans = this->control_.useTranspose_ ? SLU::TRANS : SLU::NOTRANS; 00479 // The SuperLU transpose option can override the Amesos2 option 00480 if( parameterList->isParameter("Trans") ){ 00481 RCP<const ParameterEntryValidator> trans_validator = valid_params->getEntry("Trans").validator(); 00482 parameterList->getEntry("Trans").setValidator(trans_validator); 00483 00484 data_.options.Trans = getIntegralValue<SLU::trans_t>(*parameterList, "Trans"); 00485 } 00486 00487 if( parameterList->isParameter("IterRefine") ){ 00488 RCP<const ParameterEntryValidator> refine_validator = valid_params->getEntry("IterRefine").validator(); 00489 parameterList->getEntry("IterRefine").setValidator(refine_validator); 00490 00491 data_.options.IterRefine = getIntegralValue<SLU::IterRefine_t>(*parameterList, "IterRefine"); 00492 } 00493 00494 if( parameterList->isParameter("ColPerm") ){ 00495 RCP<const ParameterEntryValidator> colperm_validator = valid_params->getEntry("ColPerm").validator(); 00496 parameterList->getEntry("ColPerm").setValidator(colperm_validator); 00497 00498 data_.options.ColPerm = getIntegralValue<SLU::colperm_t>(*parameterList, "ColPerm"); 00499 } 00500 00501 data_.options.DiagPivotThresh = parameterList->get<double>("DiagPivotThresh", 1.0); 00502 00503 bool equil = parameterList->get<bool>("Equil", true); 00504 data_.options.Equil = equil ? SLU::YES : SLU::NO; 00505 00506 bool symmetric_mode = parameterList->get<bool>("SymmetricMode", false); 00507 data_.options.SymmetricMode = symmetric_mode ? SLU::YES : SLU::NO; 00508 00509 // ILU parameters 00510 if( parameterList->isParameter("RowPerm") ){ 00511 RCP<const ParameterEntryValidator> rowperm_validator = valid_params->getEntry("RowPerm").validator(); 00512 parameterList->getEntry("RowPerm").setValidator(rowperm_validator); 00513 data_.options.RowPerm = getIntegralValue<SLU::rowperm_t>(*parameterList, "RowPerm"); 00514 } 00515 00516 /*if( parameterList->isParameter("ILU_DropRule") ) { 00517 RCP<const ParameterEntryValidator> droprule_validator = valid_params->getEntry("ILU_DropRule").validator(); 00518 parameterList->getEntry("ILU_DropRule").setValidator(droprule_validator); 00519 data_.options.ILU_DropRule = getIntegralValue<SLU::rule_t>(*parameterList, "ILU_DropRule"); 00520 }*/ 00521 00522 data_.options.ILU_DropTol = parameterList->get<double>("ILU_DropTol", 0.0001); 00523 00524 data_.options.ILU_FillFactor = parameterList->get<double>("ILU_FillFactor", 10.0); 00525 00526 if( parameterList->isParameter("ILU_Norm") ) { 00527 RCP<const ParameterEntryValidator> norm_validator = valid_params->getEntry("ILU_Norm").validator(); 00528 parameterList->getEntry("ILU_Norm").setValidator(norm_validator); 00529 data_.options.ILU_Norm = getIntegralValue<SLU::norm_t>(*parameterList, "ILU_Norm"); 00530 } 00531 00532 if( parameterList->isParameter("ILU_MILU") ) { 00533 RCP<const ParameterEntryValidator> milu_validator = valid_params->getEntry("ILU_MILU").validator(); 00534 parameterList->getEntry("ILU_MILU").setValidator(milu_validator); 00535 data_.options.ILU_MILU = getIntegralValue<SLU::milu_t>(*parameterList, "ILU_MILU"); 00536 } 00537 00538 data_.options.ILU_FillTol = parameterList->get<double>("ILU_FillTol", 0.01); 00539 00540 } 00541 00542 00543 template <class Matrix, class Vector> 00544 Teuchos::RCP<const Teuchos::ParameterList> 00545 Superlu<Matrix,Vector>::getValidParameters_impl() const 00546 { 00547 using std::string; 00548 using Teuchos::tuple; 00549 using Teuchos::ParameterList; 00550 using Teuchos::EnhancedNumberValidator; 00551 using Teuchos::setStringToIntegralParameter; 00552 using Teuchos::stringToIntegralParameterEntryValidator; 00553 00554 static Teuchos::RCP<const Teuchos::ParameterList> valid_params; 00555 00556 if( is_null(valid_params) ){ 00557 Teuchos::RCP<Teuchos::ParameterList> pl = Teuchos::parameterList(); 00558 00559 setStringToIntegralParameter<SLU::trans_t>("Trans", "NOTRANS", 00560 "Solve for the transpose system or not", 00561 tuple<string>("TRANS","NOTRANS","CONJ"), 00562 tuple<string>("Solve with transpose", 00563 "Do not solve with transpose", 00564 "Solve with the conjugate transpose"), 00565 tuple<SLU::trans_t>(SLU::TRANS, 00566 SLU::NOTRANS, 00567 SLU::CONJ), 00568 pl.getRawPtr()); 00569 00570 setStringToIntegralParameter<SLU::IterRefine_t>("IterRefine", "NOREFINE", 00571 "Type of iterative refinement to use", 00572 tuple<string>("NOREFINE", "SLU_SINGLE", "SLU_DOUBLE"), 00573 tuple<string>("Do not use iterative refinement", 00574 "Do single iterative refinement", 00575 "Do double iterative refinement"), 00576 tuple<SLU::IterRefine_t>(SLU::NOREFINE, 00577 SLU::SLU_SINGLE, 00578 SLU::SLU_DOUBLE), 00579 pl.getRawPtr()); 00580 00581 // Note: MY_PERMC not yet supported 00582 setStringToIntegralParameter<SLU::colperm_t>("ColPerm", "COLAMD", 00583 "Specifies how to permute the columns of the " 00584 "matrix for sparsity preservation", 00585 tuple<string>("NATURAL", "MMD_AT_PLUS_A", 00586 "MMD_ATA", "COLAMD"), 00587 tuple<string>("Natural ordering", 00588 "Minimum degree ordering on A^T + A", 00589 "Minimum degree ordering on A^T A", 00590 "Approximate minimum degree column ordering"), 00591 tuple<SLU::colperm_t>(SLU::NATURAL, 00592 SLU::MMD_AT_PLUS_A, 00593 SLU::MMD_ATA, 00594 SLU::COLAMD), 00595 pl.getRawPtr()); 00596 00597 Teuchos::RCP<EnhancedNumberValidator<double> > diag_pivot_thresh_validator 00598 = Teuchos::rcp( new EnhancedNumberValidator<double>(0.0, 1.0) ); 00599 pl->set("DiagPivotThresh", 1.0, 00600 "Specifies the threshold used for a diagonal entry to be an acceptable pivot", 00601 diag_pivot_thresh_validator); // partial pivoting 00602 00603 pl->set("Equil", true, "Whether to equilibrate the system before solve"); 00604 00605 pl->set("SymmetricMode", false, 00606 "Specifies whether to use the symmetric mode. " 00607 "Gives preference to diagonal pivots and uses " 00608 "an (A^T + A)-based column permutation."); 00609 00610 // ILU parameters 00611 00612 setStringToIntegralParameter<SLU::rowperm_t>("RowPerm", "LargeDiag", 00613 "Type of row permutation strategy to use", 00614 tuple<string>("NOROWPERM","LargeDiag","MY_PERMR"), 00615 tuple<string>("Use natural ordering", 00616 "Use weighted bipartite matching algorithm", 00617 "Use the ordering given in perm_r input"), 00618 tuple<SLU::rowperm_t>(SLU::NOROWPERM, 00619 SLU::LargeDiag, 00620 SLU::MY_PERMR), 00621 pl.getRawPtr()); 00622 00623 /*setStringToIntegralParameter<SLU::rule_t>("ILU_DropRule", "DROP_BASIC", 00624 "Type of dropping strategy to use", 00625 tuple<string>("DROP_BASIC","DROP_PROWS", 00626 "DROP_COLUMN","DROP_AREA", 00627 "DROP_DYNAMIC","DROP_INTERP"), 00628 tuple<string>("ILUTP(t)","ILUTP(p,t)", 00629 "Variant of ILUTP(p,t) for j-th column", 00630 "Variant of ILUTP to control memory", 00631 "Dynamically adjust threshold", 00632 "Compute second dropping threshold by interpolation"), 00633 tuple<SLU::rule_t>(SLU::DROP_BASIC,SLU::DROP_PROWS,SLU::DROP_COLUMN, 00634 SLU::DROP_AREA,SLU::DROP_DYNAMIC,SLU::DROP_INTERP), 00635 pl.getRawPtr());*/ 00636 00637 pl->set("ILU_DropTol", 0.0001, "ILUT drop tolerance"); 00638 00639 pl->set("ILU_FillFactor", 10.0, "ILUT fill factor"); 00640 00641 setStringToIntegralParameter<SLU::norm_t>("ILU_Norm", "INF_NORM", 00642 "Type of norm to use", 00643 tuple<string>("ONE_NORM","TWO_NORM","INF_NORM"), 00644 tuple<string>("1-norm","2-norm","inf-norm"), 00645 tuple<SLU::norm_t>(SLU::ONE_NORM,SLU::TWO_NORM,SLU::INF_NORM), 00646 pl.getRawPtr()); 00647 00648 setStringToIntegralParameter<SLU::milu_t>("ILU_MILU", "SILU", 00649 "Type of modified ILU to use", 00650 tuple<string>("SILU","SMILU_1","SMILU_2","SMILU_3"), 00651 tuple<string>("Regular ILU","MILU 1","MILU 2","MILU 3"), 00652 tuple<SLU::milu_t>(SLU::SILU,SLU::SMILU_1,SLU::SMILU_2, 00653 SLU::SMILU_3), 00654 pl.getRawPtr()); 00655 00656 pl->set("ILU_FillTol", 0.01, "ILUT fill tolerance"); 00657 00658 pl->set("ILU_Flag", false, "ILU flag: if true, run ILU routines"); 00659 00660 valid_params = pl; 00661 } 00662 00663 return valid_params; 00664 } 00665 00666 00667 template <class Matrix, class Vector> 00668 bool 00669 Superlu<Matrix,Vector>::loadA_impl(EPhase current_phase) 00670 { 00671 using Teuchos::as; 00672 00673 #ifdef HAVE_AMESOS2_TIMERS 00674 Teuchos::TimeMonitor convTimer(this->timers_.mtxConvTime_); 00675 #endif 00676 00677 // SuperLU does not need the matrix at symbolicFactorization() 00678 if( current_phase == SYMBFACT ) return false; 00679 00680 // Cleanup old store memory if it's non-NULL (should only ever be non-NULL at root_) 00681 if( data_.A.Store != NULL ){ 00682 SLU::Destroy_SuperMatrix_Store( &(data_.A) ); 00683 data_.A.Store = NULL; 00684 } 00685 00686 // Only the root image needs storage allocated 00687 if( this->root_ ){ 00688 nzvals_.resize(this->globalNumNonZeros_); 00689 rowind_.resize(this->globalNumNonZeros_); 00690 colptr_.resize(this->globalNumCols_ + 1); 00691 } 00692 00693 int nnz_ret = 0; 00694 { 00695 #ifdef HAVE_AMESOS2_TIMERS 00696 Teuchos::TimeMonitor mtxRedistTimer( this->timers_.mtxRedistTime_ ); 00697 #endif 00698 00699 TEUCHOS_TEST_FOR_EXCEPTION( this->rowIndexBase_ != this->columnIndexBase_, 00700 std::runtime_error, 00701 "Row and column maps have different indexbase "); 00702 Util::get_ccs_helper< 00703 MatrixAdapter<Matrix>,slu_type,int,int>::do_get(this->matrixA_.ptr(), 00704 nzvals_(), rowind_(), 00705 colptr_(), nnz_ret, ROOTED, 00706 ARBITRARY, 00707 this->rowIndexBase_); 00708 } 00709 00710 // Get the SLU data type for this type of matrix 00711 SLU::Dtype_t dtype = type_map::dtype; 00712 00713 if( this->root_ ){ 00714 TEUCHOS_TEST_FOR_EXCEPTION( nnz_ret != as<int>(this->globalNumNonZeros_), 00715 std::runtime_error, 00716 "Did not get the expected number of non-zero vals"); 00717 00718 function_map::create_CompCol_Matrix( &(data_.A), 00719 this->globalNumRows_, this->globalNumCols_, 00720 nnz_ret, 00721 nzvals_.getRawPtr(), 00722 rowind_.getRawPtr(), 00723 colptr_.getRawPtr(), 00724 SLU::SLU_NC, dtype, SLU::SLU_GE); 00725 } 00726 00727 return true; 00728 } 00729 00730 00731 template<class Matrix, class Vector> 00732 const char* Superlu<Matrix,Vector>::name = "SuperLU"; 00733 00734 00735 } // end namespace Amesos2 00736 00737 #endif // AMESOS2_SUPERLU_DEF_HPP
1.7.6.1