|
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 00052 #ifndef AMESOS2_KLU2_DEF_HPP 00053 #define AMESOS2_KLU2_DEF_HPP 00054 00055 #include <Teuchos_Tuple.hpp> 00056 #include <Teuchos_ParameterList.hpp> 00057 #include <Teuchos_StandardParameterEntryValidators.hpp> 00058 00059 #include "Amesos2_SolverCore_def.hpp" 00060 #include "Amesos2_KLU2_decl.hpp" 00061 00062 namespace Amesos2 { 00063 00064 00065 template <class Matrix, class Vector> 00066 KLU2<Matrix,Vector>::KLU2( 00067 Teuchos::RCP<const Matrix> A, 00068 Teuchos::RCP<Vector> X, 00069 Teuchos::RCP<const Vector> B ) 00070 : SolverCore<Amesos2::KLU2,Matrix,Vector>(A, X, B) 00071 , nzvals_() // initialize to empty arrays 00072 , rowind_() 00073 , colptr_() 00074 { 00075 ::KLU2::klu_defaults<scalar_type, local_ordinal_type> (&(data_.common_)) ; 00076 data_.symbolic_ = NULL; 00077 data_.numeric_ = NULL; 00078 00079 // Override some default options 00080 // TODO: use data_ here to init 00081 } 00082 00083 00084 template <class Matrix, class Vector> 00085 KLU2<Matrix,Vector>::~KLU2( ) 00086 { 00087 /* Free KLU2 data_types 00088 * - Matrices 00089 * - Vectors 00090 * - Other data 00091 */ 00092 if (data_.symbolic_ != NULL) 00093 ::KLU2::klu_free_symbolic<scalar_type, local_ordinal_type> 00094 (&(data_.symbolic_), &(data_.common_)) ; 00095 if (data_.numeric_ != NULL) 00096 ::KLU2::klu_free_numeric<scalar_type, local_ordinal_type> 00097 (&(data_.numeric_), &(data_.common_)) ; 00098 00099 // Storage is initialized in numericFactorization_impl() 00100 //if ( data_.A.Store != NULL ){ 00101 // destoy 00102 //} 00103 00104 // only root allocated these SuperMatrices. 00105 //if ( data_.L.Store != NULL ){ // will only be true for this->root_ 00106 // destroy .. 00107 //} 00108 } 00109 00110 template<class Matrix, class Vector> 00111 int 00112 KLU2<Matrix,Vector>::preOrdering_impl() 00113 { 00114 /* TODO: Define what it means for KLU2 00115 */ 00116 #ifdef HAVE_AMESOS2_TIMERS 00117 Teuchos::TimeMonitor preOrderTimer(this->timers_.preOrderTime_); 00118 #endif 00119 00120 return(0); 00121 } 00122 00123 00124 template <class Matrix, class Vector> 00125 int 00126 KLU2<Matrix,Vector>::symbolicFactorization_impl() 00127 { 00128 data_.symbolic_ = ::KLU2::klu_analyze<scalar_type, local_ordinal_type> 00129 ((local_ordinal_type)this->globalNumCols_, colptr_.getRawPtr(), 00130 rowind_.getRawPtr(), &(data_.common_)) ; 00131 00132 #ifdef HAVE_AMESOS2_DEBUG 00133 // TODO ": This should move to symbolic 00134 TEUCHOS_TEST_FOR_EXCEPTION( data_.A.ncol != as<int>(this->globalNumCols_), 00135 std::runtime_error, 00136 "Error in converting to KLU2 : wrong number of global columns." ); 00137 TEUCHOS_TEST_FOR_EXCEPTION( data_.A.nrow != as<int>(this->globalNumRows_), 00138 std::runtime_error, 00139 "Error in converting to KLU2 SuperMatrix: wrong number of global rows." ); 00140 #endif 00141 00142 return(0); 00143 } 00144 00145 00146 template <class Matrix, class Vector> 00147 int 00148 KLU2<Matrix,Vector>::numericFactorization_impl() 00149 { 00150 using Teuchos::as; 00151 00152 // Cleanup old L and U matrices if we are not reusing a symbolic 00153 // factorization. Stores and other data will be allocated in gstrf. 00154 // Only rank 0 has valid pointers, TODO: for KLU2 00155 00156 00157 int info = 0; 00158 if ( this->root_ ){ 00159 00160 { // Do factorization 00161 #ifdef HAVE_AMESOS2_TIMERS 00162 Teuchos::TimeMonitor numFactTimer(this->timers_.numFactTime_); 00163 #endif 00164 00165 #ifdef HAVE_AMESOS2_VERBOSE_DEBUG 00166 std::cout << "KLU2:: Before numeric factorization" << std::endl; 00167 std::cout << "nzvals_ : " << nzvals_.toString() << std::endl; 00168 std::cout << "rowind_ : " << rowind_.toString() << std::endl; 00169 std::cout << "colptr_ : " << colptr_.toString() << std::endl; 00170 #endif 00171 00172 data_.numeric_ = ::KLU2::klu_factor<scalar_type, local_ordinal_type> 00173 (colptr_.getRawPtr(), rowind_.getRawPtr(), nzvals_.getRawPtr(), 00174 data_.symbolic_, &(data_.common_)) ; 00175 00176 } 00177 00178 // Set the number of non-zero values in the L and U factors // TODO 00179 //this->setNnzLU( as<size_t>(((SLU::SCformat*)data_.L.Store)->nnz + 00180 //((SLU::NCformat*)data_.U.Store)->nnz) ); 00181 } 00182 00183 /* All processes should have the same error code */ 00184 Teuchos::broadcast(*(this->matrixA_->getComm()), 0, &info); 00185 00186 global_size_type info_st = as<global_size_type>(info); 00187 /* TODO : Proper error messages 00188 TEUCHOS_TEST_FOR_EXCEPTION( (info_st > 0) && (info_st <= this->globalNumCols_), 00189 std::runtime_error, 00190 "Factorization complete, but matrix is singular. Division by zero eminent"); 00191 TEUCHOS_TEST_FOR_EXCEPTION( (info_st > 0) && (info_st > this->globalNumCols_), 00192 std::runtime_error, 00193 "Memory allocation failure in KLU2 factorization");*/ 00194 00195 //data_.options.Fact = SLU::FACTORED; 00196 //same_symbolic_ = true; 00197 00198 return(info); 00199 } 00200 00201 00202 template <class Matrix, class Vector> 00203 int 00204 KLU2<Matrix,Vector>::solve_impl( 00205 const Teuchos::Ptr<MultiVecAdapter<Vector> > X, 00206 const Teuchos::Ptr<const MultiVecAdapter<Vector> > B) const 00207 { 00208 using Teuchos::as; 00209 00210 const global_size_type ld_rhs = this->root_ ? X->getGlobalLength() : 0; 00211 const size_t nrhs = X->getGlobalNumVectors(); 00212 00213 const size_t val_store_size = as<size_t>(ld_rhs * nrhs); 00214 Teuchos::Array<slu_type> bValues(val_store_size); 00215 00216 { // Get values from RHS B 00217 #ifdef HAVE_AMESOS2_TIMERS 00218 Teuchos::TimeMonitor mvConvTimer(this->timers_.vecConvTime_); 00219 Teuchos::TimeMonitor redistTimer( this->timers_.vecRedistTime_ ); 00220 #endif 00221 Util::get_1d_copy_helper<MultiVecAdapter<Vector>, 00222 slu_type>::do_get(B, bValues(), 00223 as<size_t>(ld_rhs), 00224 ROOTED); 00225 } 00226 00227 00228 int ierr = 0; // returned error code 00229 00230 magnitude_type rpg, rcond; 00231 if ( this->root_ ) { 00232 00233 //local_ordinal_type i_ld_rhs = as<local_ordinal_type>(ld_rhs); 00234 00235 { // Do solve! 00236 #ifdef HAVE_AMESOS2_TIMERS 00237 Teuchos::TimeMonitor solveTimer(this->timers_.solveTime_); 00238 #endif 00239 ::KLU2::klu_solve<scalar_type, local_ordinal_type> 00240 (data_.symbolic_, data_.numeric_, 00241 (local_ordinal_type)this->globalNumCols_, 00242 (local_ordinal_type)nrhs, 00243 bValues.getRawPtr(), &(data_.common_)) ; 00244 00245 } 00246 00247 } 00248 00249 /* All processes should have the same error code */ 00250 Teuchos::broadcast(*(this->getComm()), 0, &ierr); 00251 00252 global_size_type ierr_st = as<global_size_type>(ierr); 00253 // TODO 00254 //TEUCHOS_TEST_FOR_EXCEPTION( ierr < 0, 00255 //std::invalid_argument, 00256 //"Argument " << -ierr << " to KLU2 xgssvx had illegal value" ); 00257 //TEUCHOS_TEST_FOR_EXCEPTION( ierr > 0 && ierr_st <= this->globalNumCols_, 00258 //std::runtime_error, 00259 //"Factorization complete, but U is exactly singular" ); 00260 //TEUCHOS_TEST_FOR_EXCEPTION( ierr > 0 && ierr_st > this->globalNumCols_ + 1, 00261 //std::runtime_error, 00262 //"KLU2 allocated " << ierr - this->globalNumCols_ << " bytes of " 00263 //"memory before allocation failure occured." ); 00264 00265 /* Update X's global values */ 00266 { 00267 #ifdef HAVE_AMESOS2_TIMERS 00268 Teuchos::TimeMonitor redistTimer(this->timers_.vecRedistTime_); 00269 #endif 00270 00271 Util::put_1d_data_helper< 00272 MultiVecAdapter<Vector>,slu_type>::do_put(X, bValues(), 00273 as<size_t>(ld_rhs), 00274 ROOTED); 00275 } 00276 00277 00278 return(ierr); 00279 } 00280 00281 00282 template <class Matrix, class Vector> 00283 bool 00284 KLU2<Matrix,Vector>::matrixShapeOK_impl() const 00285 { 00286 // The KLU2 factorization routines can handle square as well as 00287 // rectangular matrices, but KLU2 can only apply the solve routines to 00288 // square matrices, so we check the matrix for squareness. 00289 return( this->matrixA_->getGlobalNumRows() == this->matrixA_->getGlobalNumCols() ); 00290 } 00291 00292 00293 template <class Matrix, class Vector> 00294 void 00295 KLU2<Matrix,Vector>::setParameters_impl(const Teuchos::RCP<Teuchos::ParameterList> & parameterList ) 00296 { 00297 using Teuchos::RCP; 00298 using Teuchos::getIntegralValue; 00299 using Teuchos::ParameterEntryValidator; 00300 00301 RCP<const Teuchos::ParameterList> valid_params = getValidParameters_impl(); 00302 00303 // The KLU2 transpose option can override the Amesos2 option 00304 //if( parameterList->isParameter("Trans") ){ 00305 //RCP<const ParameterEntryValidator> trans_validator = valid_params->getEntry("Trans").validator(); 00306 //parameterList->getEntry("Trans").setValidator(trans_validator); 00307 00308 //data_.options.Trans = getIntegralValue<SLU::trans_t>(*parameterList, "Trans"); 00309 //} 00310 00311 } 00312 00313 00314 template <class Matrix, class Vector> 00315 Teuchos::RCP<const Teuchos::ParameterList> 00316 KLU2<Matrix,Vector>::getValidParameters_impl() const 00317 { 00318 using Teuchos::ParameterList; 00319 00320 static Teuchos::RCP<const Teuchos::ParameterList> valid_params; 00321 00322 if( is_null(valid_params) ){ 00323 Teuchos::RCP<Teuchos::ParameterList> pl = Teuchos::parameterList(); 00324 00325 pl->set("Equil", true, "Whether to equilibrate the system before solve, does nothing now"); 00326 00327 valid_params = pl; 00328 } 00329 00330 return valid_params; 00331 } 00332 00333 00334 template <class Matrix, class Vector> 00335 bool 00336 KLU2<Matrix,Vector>::loadA_impl(EPhase current_phase) 00337 { 00338 using Teuchos::as; 00339 00340 #ifdef HAVE_AMESOS2_TIMERS 00341 Teuchos::TimeMonitor convTimer(this->timers_.mtxConvTime_); 00342 #endif 00343 00344 // Only the root image needs storage allocated 00345 if( this->root_ ){ 00346 nzvals_.resize(this->globalNumNonZeros_); 00347 rowind_.resize(this->globalNumNonZeros_); 00348 colptr_.resize(this->globalNumCols_ + 1); 00349 } 00350 00351 local_ordinal_type nnz_ret = 0; 00352 { 00353 #ifdef HAVE_AMESOS2_TIMERS 00354 Teuchos::TimeMonitor mtxRedistTimer( this->timers_.mtxRedistTime_ ); 00355 #endif 00356 00357 Util::get_ccs_helper< 00358 MatrixAdapter<Matrix>,slu_type,local_ordinal_type,local_ordinal_type> 00359 ::do_get(this->matrixA_.ptr(), nzvals_(), rowind_(), colptr_(), 00360 nnz_ret, ROOTED, ARBITRARY); 00361 } 00362 00363 00364 if( this->root_ ){ 00365 std::cout << "nnz=" << nnz_ret << "gnnz" << this->globalNumNonZeros_ << std::endl; 00366 TEUCHOS_TEST_FOR_EXCEPTION( nnz_ret != as<local_ordinal_type>(this->globalNumNonZeros_), 00367 std::runtime_error, 00368 "Did not get the expected number of non-zero vals"); 00369 } 00370 00371 return true; 00372 } 00373 00374 00375 template<class Matrix, class Vector> 00376 const char* KLU2<Matrix,Vector>::name = "KLU2"; 00377 00378 00379 } // end namespace Amesos2 00380 00381 #endif // AMESOS2_KLU2_DEF_HPP
1.7.6.1