|
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_CHOLMOD_DEF_HPP 00054 #define AMESOS2_CHOLMOD_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_Cholmod_decl.hpp" 00062 00063 00064 namespace Amesos2 { 00065 00066 00067 template <class Matrix, class Vector> 00068 Cholmod<Matrix,Vector>::Cholmod( 00069 Teuchos::RCP<const Matrix> A, 00070 Teuchos::RCP<Vector> X, 00071 Teuchos::RCP<const Vector> B ) 00072 : SolverCore<Amesos2::Cholmod,Matrix,Vector>(A, X, B) 00073 , nzvals_() // initialize to empty arrays 00074 , rowind_() 00075 , colptr_() 00076 , firstsolve(true) 00077 , map() 00078 { 00079 CHOL::cholmod_start(&data_.c); 00080 (&data_.c)->nmethods=9; 00081 (&data_.c)->quick_return_if_not_posdef=1; 00082 00083 //(&data_.c)->method[0].ordering=CHOLMOD_NATURAL; 00084 //(&data_.c)->print=5; 00085 data_.Y = NULL; 00086 data_.E = NULL; 00087 } 00088 00089 00090 template <class Matrix, class Vector> 00091 Cholmod<Matrix,Vector>::~Cholmod( ) 00092 { 00093 CHOL::cholmod_free_factor (&(data_.L), &(data_.c)); 00094 00095 CHOL::cholmod_free_dense(&(data_.Y), &data_.c); 00096 CHOL::cholmod_free_dense(&(data_.E), &data_.c); 00097 00098 CHOL::cholmod_finish(&(data_.c)); 00099 } 00100 00101 template<class Matrix, class Vector> 00102 int 00103 Cholmod<Matrix,Vector>::preOrdering_impl() 00104 { 00105 #ifdef HAVE_AMESOS2_TIMERS 00106 Teuchos::TimeMonitor preOrderTimer(this->timers_.preOrderTime_); 00107 #endif 00108 data_.L = CHOL::cholmod_analyze (&data_.A, &(data_.c)); 00109 //data_.L->is_super=1; 00110 data_.L->is_ll=1; 00111 00112 skip_symfact = true; 00113 00114 return(0); 00115 } 00116 00117 00118 template <class Matrix, class Vector> 00119 int 00120 Cholmod<Matrix,Vector>::symbolicFactorization_impl() 00121 { 00122 if ( !skip_symfact ){ 00123 #ifdef HAVE_AMESOS2_TIMERS 00124 Teuchos::TimeMonitor symFactTimer(this->timers_.symFactTime_); 00125 #endif 00126 CHOL::cholmod_resymbol (&data_.A, NULL, 0, true, data_.L, &(data_.c)); 00127 } else { 00128 /* 00129 * Symbolic factorization has already occured in preOrdering_impl, 00130 * but if the user calls this routine directly later, we need to 00131 * redo the symbolic factorization. 00132 */ 00133 skip_symfact = false; 00134 } 00135 00136 return(0); 00137 } 00138 00139 00140 template <class Matrix, class Vector> 00141 int 00142 Cholmod<Matrix,Vector>::numericFactorization_impl() 00143 { 00144 using Teuchos::as; 00145 00146 int info = 0; 00147 00148 #ifdef HAVE_AMESOS2_DEBUG 00149 TEUCHOS_TEST_FOR_EXCEPTION(data_.A.ncol != as<size_t>(this->globalNumCols_), 00150 std::runtime_error, 00151 "Error in converting to cholmod_sparse: wrong number of global columns." ); 00152 TEUCHOS_TEST_FOR_EXCEPTION(data_.A.nrow != as<size_t>(this->globalNumRows_), 00153 std::runtime_error, 00154 "Error in converting to cholmod_sparse: wrong number of global rows." ); 00155 #endif 00156 00157 { // Do factorization 00158 #ifdef HAVE_AMESOS2_TIMERS 00159 Teuchos::TimeMonitor numFactTimer(this->timers_.numFactTime_); 00160 #endif 00161 00162 #ifdef HAVE_AMESOS2_VERBOSE_DEBUG 00163 std::cout << "Cholmod:: Before numeric factorization" << std::endl; 00164 std::cout << "nzvals_ : " << nzvals_.toString() << std::endl; 00165 std::cout << "rowind_ : " << rowind_.toString() << std::endl; 00166 std::cout << "colptr_ : " << colptr_.toString() << std::endl; 00167 #endif 00168 //cholmod_print_sparse(data_.A,"A",&(data_.c)); 00169 CHOL::cholmod_factorize(&data_.A, data_.L, &(data_.c)); 00170 //cholmod_print_factor(data_.L,"L",&(data_.c)); 00171 info = (&data_.c)->status; 00172 00173 } 00174 00175 00176 00177 /* All processes should have the same error code */ 00178 Teuchos::broadcast(*(this->matrixA_->getComm()), 0, &info); 00179 00180 TEUCHOS_TEST_FOR_EXCEPTION(info == 2, 00181 std::runtime_error, 00182 "Memory allocation failure in Cholmod factorization"); 00183 00184 return(info); 00185 } 00186 00187 00188 template <class Matrix, class Vector> 00189 int 00190 Cholmod<Matrix,Vector>::solve_impl(const Teuchos::Ptr<MultiVecAdapter<Vector> > X, 00191 const Teuchos::Ptr<const MultiVecAdapter<Vector> > B) const 00192 { 00193 using Teuchos::as; 00194 00195 const global_size_type ld_rhs = X->getGlobalLength(); 00196 const size_t nrhs = X->getGlobalNumVectors(); 00197 00198 Teuchos::RCP<const Tpetra::Map<local_ordinal_type, 00199 global_ordinal_type, node_type> > map2; 00200 00201 const size_t val_store_size = as<size_t>(ld_rhs * nrhs); 00202 Teuchos::Array<chol_type> xValues(val_store_size); 00203 Teuchos::Array<chol_type> bValues(val_store_size); 00204 00205 { // Get values from RHS B 00206 #ifdef HAVE_AMESOS2_TIMERS 00207 Teuchos::TimeMonitor mvConvTimer(this->timers_.vecConvTime_); 00208 Teuchos::TimeMonitor redistTimer( this->timers_.vecRedistTime_ ); 00209 #endif 00210 Util::get_1d_copy_helper<MultiVecAdapter<Vector>, 00211 chol_type>::do_get(B, bValues(), 00212 as<size_t>(ld_rhs), 00213 ROOTED, this->rowIndexBase_); 00214 00215 } 00216 00217 00218 int ierr = 0; // returned error code 00219 00220 { 00221 #ifdef HAVE_AMESOS2_TIMERS 00222 Teuchos::TimeMonitor mvConvTimer(this->timers_.vecConvTime_); 00223 #endif 00224 00225 function_map::cholmod_init_dense(as<int>(this->globalNumRows_), 00226 as<int>(nrhs), as<int>(ld_rhs), 00227 bValues.getRawPtr(), &data_.b); 00228 function_map::cholmod_init_dense(as<int>(this->globalNumRows_), 00229 as<int>(nrhs), as<int>(ld_rhs), 00230 xValues.getRawPtr(), &data_.x); 00231 } 00232 00233 00234 { // Do solve! 00235 #ifdef HAVE_AMESOS2_TIMERS 00236 Teuchos::TimeMonitor solveTimer(this->timers_.solveTime_); 00237 #endif 00238 00239 CHOL::cholmod_dense *xtemp = &(data_.x); 00240 00241 CHOL::cholmod_solve2(CHOLMOD_A, data_.L, &data_.b, NULL, 00242 &xtemp, NULL, &data_.Y, &data_.E, &data_.c); 00243 00244 ierr = (&data_.c)->status; 00245 } 00246 00247 00248 00249 /* All processes should have the same error code */ 00250 Teuchos::broadcast(*(this->getComm()), 0, &ierr); 00251 00252 TEUCHOS_TEST_FOR_EXCEPTION(ierr == -2, std::runtime_error, "Ran out of memory" ); 00253 00254 /* Update X's global values */ 00255 { 00256 #ifdef HAVE_AMESOS2_TIMERS 00257 Teuchos::TimeMonitor redistTimer(this->timers_.vecRedistTime_); 00258 #endif 00259 00260 Util::put_1d_data_helper< 00261 MultiVecAdapter<Vector>,chol_type>::do_put(X, xValues(), 00262 as<size_t>(ld_rhs), 00263 ROOTED, this->rowIndexBase_); 00264 00265 } 00266 00267 00268 return(ierr); 00269 } 00270 00271 00272 template <class Matrix, class Vector> 00273 bool 00274 Cholmod<Matrix,Vector>::matrixShapeOK_impl() const 00275 { 00276 return( this->matrixA_->getGlobalNumRows() == this->matrixA_->getGlobalNumCols() ); 00277 } 00278 00279 00280 template <class Matrix, class Vector> 00281 void 00282 Cholmod<Matrix,Vector>::setParameters_impl(const Teuchos::RCP<Teuchos::ParameterList> & parameterList ) 00283 { 00284 using Teuchos::RCP; 00285 using Teuchos::getIntegralValue; 00286 using Teuchos::ParameterEntryValidator; 00287 00288 RCP<const Teuchos::ParameterList> valid_params = getValidParameters_impl(); 00289 00290 00291 if( parameterList->isParameter("Trans") ){ 00292 RCP<const ParameterEntryValidator> trans_validator = valid_params->getEntry("Trans").validator(); 00293 parameterList->getEntry("Trans").setValidator(trans_validator); 00294 00295 } 00296 00297 if( parameterList->isParameter("IterRefine") ){ 00298 RCP<const ParameterEntryValidator> refine_validator = valid_params->getEntry("IterRefine").validator(); 00299 parameterList->getEntry("IterRefine").setValidator(refine_validator); 00300 00301 00302 } 00303 00304 if( parameterList->isParameter("ColPerm") ){ 00305 RCP<const ParameterEntryValidator> colperm_validator = valid_params->getEntry("ColPerm").validator(); 00306 parameterList->getEntry("ColPerm").setValidator(colperm_validator); 00307 00308 00309 } 00310 00311 (&data_.c)->dbound = parameterList->get<double>("dbound", 0.0); 00312 00313 bool prefer_upper = parameterList->get<bool>("PreferUpper", true); 00314 00315 (&data_.c)->prefer_upper = prefer_upper ? 1 : 0; 00316 00317 (&data_.c)->print = parameterList->get<int>("print",3); 00318 00319 (&data_.c)->nmethods = parameterList->get<int>("nmethods",0); 00320 00321 } 00322 00323 00324 template <class Matrix, class Vector> 00325 Teuchos::RCP<const Teuchos::ParameterList> 00326 Cholmod<Matrix,Vector>::getValidParameters_impl() const 00327 { 00328 using std::string; 00329 using Teuchos::tuple; 00330 using Teuchos::ParameterList; 00331 using Teuchos::EnhancedNumberValidator; 00332 using Teuchos::setStringToIntegralParameter; 00333 using Teuchos::stringToIntegralParameterEntryValidator; 00334 00335 static Teuchos::RCP<const Teuchos::ParameterList> valid_params; 00336 00337 if( is_null(valid_params) ){ 00338 Teuchos::RCP<Teuchos::ParameterList> pl = Teuchos::parameterList(); 00339 00340 00341 Teuchos::RCP<EnhancedNumberValidator<int> > print_validator 00342 = Teuchos::rcp( new EnhancedNumberValidator<int>(0,5)); 00343 00344 Teuchos::RCP<EnhancedNumberValidator<int> > nmethods_validator 00345 = Teuchos::rcp( new EnhancedNumberValidator<int>(0,9)); 00346 00347 pl->set("nmethods", 0, "Specifies the number of different ordering methods to try", nmethods_validator); 00348 00349 pl->set("print", 3, "Specifies the verbosity of the print statements", print_validator); 00350 00351 pl->set("dbound", 0.0, 00352 "Specifies the smallest absolute value on the diagonal D for the LDL' factorization"); 00353 00354 00355 pl->set("Equil", true, "Whether to equilibrate the system before solve"); 00356 00357 pl->set("PreferUpper", true, 00358 "Specifies whether the matrix will be " 00359 "stored in upper triangular form."); 00360 00361 valid_params = pl; 00362 } 00363 00364 return valid_params; 00365 } 00366 00367 00368 template <class Matrix, class Vector> 00369 bool 00370 Cholmod<Matrix,Vector>::loadA_impl(EPhase current_phase) 00371 { 00372 using Teuchos::as; 00373 00374 #ifdef HAVE_AMESOS2_TIMERS 00375 Teuchos::TimeMonitor convTimer(this->timers_.mtxConvTime_); 00376 #endif 00377 00378 // Only the root image needs storage allocated 00379 00380 nzvals_.resize(this->globalNumNonZeros_); 00381 rowind_.resize(this->globalNumNonZeros_); 00382 colptr_.resize(this->globalNumCols_ + 1); 00383 00384 00385 int nnz_ret = 0; 00386 { 00387 #ifdef HAVE_AMESOS2_TIMERS 00388 Teuchos::TimeMonitor mtxRedistTimer( this->timers_.mtxRedistTime_ ); 00389 #endif 00390 00391 TEUCHOS_TEST_FOR_EXCEPTION(this->rowIndexBase_ != this->columnIndexBase_, 00392 std::runtime_error, 00393 "Row and column maps have different indexbase "); 00394 Util::get_ccs_helper< 00395 MatrixAdapter<Matrix>,chol_type,int,int>::do_get(this->matrixA_.ptr(), 00396 nzvals_(), rowind_(), 00397 colptr_(), nnz_ret, ROOTED, 00398 ARBITRARY, 00399 this->rowIndexBase_); 00400 } 00401 00402 00403 TEUCHOS_TEST_FOR_EXCEPTION(nnz_ret != as<int>(this->globalNumNonZeros_), 00404 std::runtime_error, 00405 "Did not get the expected number of non-zero vals"); 00406 00407 function_map::cholmod_init_sparse(as<size_t>(this->globalNumRows_), 00408 as<size_t>(this->globalNumCols_), 00409 as<size_t>(this->globalNumNonZeros_), 00410 0, 00411 colptr_.getRawPtr(), 00412 nzvals_.getRawPtr(), 00413 rowind_.getRawPtr(), 00414 &(data_.A)); 00415 00416 00417 return true; 00418 } 00419 00420 00421 template<class Matrix, class Vector> 00422 const char* Cholmod<Matrix,Vector>::name = "Cholmod"; 00423 00424 00425 } // end namespace Amesos2 00426 00427 #endif // AMESOS2_CHOLMOD_DEF_HPP
1.7.6.1