|
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 00082 #ifndef AMESOS2_FACTORY_HPP 00083 #define AMESOS2_FACTORY_HPP 00084 00085 #include "Amesos2_config.h" 00086 00087 #include "Amesos2_Solver.hpp" 00088 #include "Amesos2_SolverTraits.hpp" 00089 00090 #include "Teuchos_ScalarTraits.hpp" 00091 #include "Amesos2_MultiVecAdapter.hpp" 00092 #include "Amesos2_MatrixTraits.hpp" 00093 #include "Amesos2_ctassert.hpp" 00094 00095 #ifdef HAVE_AMESOS2_KLU2 00096 #include "Amesos2_Klu2.hpp" 00097 #endif 00098 #ifdef HAVE_AMESOS2_SUPERLUDIST // Distributed-memory SuperLU 00099 #include "Amesos2_Superludist.hpp" 00100 #endif 00101 #ifdef HAVE_AMESOS2_SUPERLUMT // Multi-threaded SuperLU 00102 #include "Amesos2_Superlumt.hpp" 00103 #endif 00104 #ifdef HAVE_AMESOS2_SUPERLU // Sequential SuperLU 00105 #include "Amesos2_Superlu.hpp" 00106 #endif 00107 #ifdef HAVE_AMESOS2_PARDISO_MKL // MKL version of Pardiso 00108 #include "Amesos2_PardisoMKL.hpp" 00109 #endif 00110 #ifdef HAVE_AMESOS2_LAPACK 00111 #include "Amesos2_Lapack.hpp" 00112 #endif 00113 00114 namespace Amesos2 { 00115 00116 template <class,class> class Solver; 00117 00118 /* 00119 * Utility function to transform a string into all lowercase 00120 */ 00121 std::string tolower(const std::string& s); 00122 00123 00138 template < class Matrix, 00139 class Vector > 00140 Solver<Matrix,Vector>* 00141 create(const Matrix* A, Vector* X, const Vector* B); 00142 00143 00158 template < class Matrix, 00159 class Vector > 00160 Teuchos::RCP<Solver<Matrix,Vector> > 00161 create(Teuchos::RCP<const Matrix> A, 00162 Teuchos::RCP<Vector> X, 00163 Teuchos::RCP<const Vector> B); 00164 00165 00183 template < class Matrix, 00184 class Vector > 00185 Solver<Matrix,Vector>* 00186 create(const char* solverName, const Matrix* A, Vector* X, const Vector* B); 00187 00188 00205 template < class Matrix, 00206 class Vector > 00207 Teuchos::RCP<Solver<Matrix,Vector> > 00208 create(const char* solverName, 00209 const Teuchos::RCP<const Matrix> A, 00210 const Teuchos::RCP<Vector> X, 00211 const Teuchos::RCP<const Vector> B); 00212 00213 00230 template < class Matrix, 00231 class Vector > 00232 Solver<Matrix,Vector>* 00233 create(const std::string solverName, const Matrix* A, Vector* X, const Vector* B); 00234 00235 00252 template < class Matrix, 00253 class Vector > 00254 Teuchos::RCP<Solver<Matrix,Vector> > 00255 create(const std::string solverName, 00256 const Teuchos::RCP<const Matrix> A, 00257 const Teuchos::RCP<Vector> X, 00258 const Teuchos::RCP<const Vector> B); 00259 00260 00279 template < class Matrix, 00280 class Vector > 00281 Solver<Matrix,Vector>* 00282 create(const std::string solverName, const Matrix* A); 00283 00284 00303 template < class Matrix, 00304 class Vector > 00305 Teuchos::RCP<Solver<Matrix,Vector> > 00306 create(const std::string solverName, 00307 const Teuchos::RCP<const Matrix> A); 00308 00309 00311 // Meta-functions to help with creation of solvers // 00313 00314 template < template <class,class> class ConcreteSolver, 00315 class Matrix, 00316 class Vector > 00317 struct create_solver_with_supported_type { 00318 static Teuchos::RCP<Solver<Matrix,Vector> > apply(Teuchos::RCP<const Matrix> A, 00319 Teuchos::RCP<Vector> X, 00320 Teuchos::RCP<const Vector> B ) 00321 { 00322 ctassert< 00323 Meta::is_same< 00324 typename MatrixTraits<Matrix>::scalar_t, 00325 typename MultiVecAdapter<Vector>::scalar_t 00326 >::value 00327 > same_scalar_assertion; 00328 (void)same_scalar_assertion; // This stops the compiler from warning about unused declared variables 00329 00330 // If our assertion did not fail, then create and return a new solver 00331 return rcp( new ConcreteSolver<Matrix,Vector>(A, X, B) ); 00332 } 00333 }; 00334 00343 template < template <class,class> class ConcreteSolver, 00344 class Matrix, 00345 class Vector > 00346 struct throw_no_scalar_support_exception { 00347 static Teuchos::RCP<Solver<Matrix,Vector> > apply(Teuchos::RCP<const Matrix> A, 00348 Teuchos::RCP<Vector> X, 00349 Teuchos::RCP<const Vector> B ) 00350 { 00351 // typedef ConcreteSolver<Matrix,Vector> concretesolver_matrix_vector; 00352 typedef typename MatrixTraits<Matrix>::scalar_t scalar_t; 00353 TEUCHOS_TEST_FOR_EXCEPTION( true, 00354 std::invalid_argument, 00355 "The requested Amesos2 " 00356 // << concretesolver_matrix_vector::name << 00357 " solver interface does not support the " << 00358 Teuchos::ScalarTraits<scalar_t>::name() << 00359 " scalar type." ); 00360 } 00361 }; 00362 00372 template < template <class,class> class ConcreteSolver, 00373 class Matrix, 00374 class Vector > 00375 struct handle_solver_type_support { 00376 static Teuchos::RCP<Solver<Matrix,Vector> > apply(Teuchos::RCP<const Matrix> A, 00377 Teuchos::RCP<Vector> X, 00378 Teuchos::RCP<const Vector> B ) 00379 { 00380 return Meta::if_then_else< 00381 solver_supports_scalar<ConcreteSolver, typename MatrixTraits<Matrix>::scalar_t>::value, 00382 create_solver_with_supported_type<ConcreteSolver,Matrix,Vector>, 00383 throw_no_scalar_support_exception<ConcreteSolver,Matrix,Vector> >::type::apply(A, X, B); 00384 } 00385 }; 00386 00387 00389 // Query Functions // 00391 00399 bool query(const char* solverName); 00400 00401 00409 bool query(const std::string solverName); 00410 00411 00413 // Definitions // 00415 00416 template <class Matrix, 00417 class Vector > 00418 Solver<Matrix,Vector>* 00419 create(Matrix* A, Vector* X, Vector* B) 00420 { 00421 std::string solver = "Klu2"; 00422 // Pass non-owning RCP objects to other factory method 00423 return( create(solver, rcp(A,false), rcp(X,false), rcp(B,false)).getRawPtr() ); 00424 } 00425 00426 00427 template <class Matrix, 00428 class Vector > 00429 Teuchos::RCP<Solver<Matrix,Vector> > 00430 create(Teuchos::RCP<const Matrix> A, 00431 Teuchos::RCP<Vector> X, 00432 Teuchos::RCP<const Vector> B) 00433 { 00434 std::string solver = "Klu2"; 00435 return( create(solver, A, X, B) ); 00436 } 00437 00438 00439 template <class Matrix, 00440 class Vector > 00441 Solver<Matrix,Vector>* 00442 create(const char* solverName, const Matrix* A, Vector* X, const Vector* B) 00443 { 00444 std::string solver = solverName; 00445 // Pass non-owning Teuchos::RCP objects to other factory method 00446 return( create(solver, rcp(A,false), rcp(X,false), rcp(B,false)).getRawPtr() ); 00447 } 00448 00449 00450 template <class Matrix, 00451 class Vector > 00452 Teuchos::RCP<Solver<Matrix,Vector> > 00453 create(const char* solverName, 00454 const Teuchos::RCP<const Matrix> A, 00455 const Teuchos::RCP<Vector> X, 00456 const Teuchos::RCP<const Vector> B) 00457 { 00458 std::string solver = solverName; 00459 return( create(solver, A, X, B) ); 00460 } 00461 00462 00463 template <class Matrix, 00464 class Vector > 00465 Solver<Matrix,Vector>* 00466 create(const std::string solverName, const Matrix* A){ 00467 return( create(solverName, rcp(A,false), 00468 Teuchos::RCP<Vector>(), 00469 Teuchos::RCP<const Vector>()).getRawPtr() ); 00470 } 00471 00472 00473 template <class Matrix, 00474 class Vector > 00475 Teuchos::RCP<Solver<Matrix,Vector> > 00476 create(const std::string solverName, const Teuchos::RCP<const Matrix> A){ 00477 return( create(solverName, A, Teuchos::RCP<Vector>(), Teuchos::RCP<const Vector>()) ); 00478 } 00479 00480 00481 template <class Matrix, 00482 class Vector > 00483 Teuchos::RCP<Solver<Matrix,Vector> > 00484 create(const std::string solverName, const Matrix* A, Vector* X, const Vector* B) 00485 { 00486 // Pass non-owning Teuchos::RCP objects to other factory method 00487 return( create(solverName, rcp(A,false), rcp(X,false), rcp(B,false)) ); 00488 } 00489 00490 00491 template <class Matrix, 00492 class Vector > 00493 Teuchos::RCP<Solver<Matrix,Vector> > 00494 create(const std::string solver_name, 00495 const Teuchos::RCP<const Matrix> A, 00496 const Teuchos::RCP<Vector> X, 00497 const Teuchos::RCP<const Vector> B) 00498 { 00499 std::string solverName = tolower(solver_name); // for easy string checking 00500 00501 // Check for our native solver first. Treat KLU and KLU2 as equals. 00502 // 00503 // We use compiler guards in case a user does want to disable KLU2 00504 #ifdef HAVE_AMESOS2_KLU2 00505 if((solverName == "amesos2_klu2") || (solverName == "klu2") || 00506 (solverName == "amesos2_klu") || (solverName == "klu")){ 00507 return handle_solver_type_support<Klu2,Matrix,Vector>::apply(A, X, B); 00508 } 00509 #endif 00510 00511 #ifdef HAVE_AMESOS2_SUPERLUDIST 00512 if((solverName == "amesos2_superludist") || 00513 (solverName == "superludist") || 00514 (solverName == "amesos2_superlu_dist") || 00515 (solverName == "superlu_dist")){ 00516 return handle_solver_type_support<Superludist,Matrix,Vector>::apply(A, X, B); 00517 } 00518 #endif 00519 00520 #ifdef HAVE_AMESOS2_SUPERLUMT 00521 if((solverName == "amesos2_superlumt") || 00522 (solverName == "superlumt") || 00523 (solverName == "amesos2_superlu_mt") || 00524 (solverName == "superlu_mt")){ 00525 return handle_solver_type_support<Superlumt,Matrix,Vector>::apply(A, X, B); 00526 } 00527 #endif 00528 00529 #ifdef HAVE_AMESOS2_SUPERLU 00530 if((solverName == "amesos2_superlu") || 00531 (solverName == "superlu")){ 00532 return handle_solver_type_support<Superlu,Matrix,Vector>::apply(A, X, B); 00533 } 00534 #endif 00535 00536 #ifdef HAVE_AMESOS2_PARDISO_MKL 00537 if((solverName == "amesos2_pardiso_mkl") || 00538 (solverName == "pardiso_mkl") || 00539 (solverName == "amesos2_pardisomkl") || 00540 (solverName == "pardisomkl")){ 00541 return handle_solver_type_support<PardisoMKL,Matrix,Vector>::apply(A, X, B); 00542 } 00543 #endif 00544 00545 #ifdef HAVE_AMESOS2_LAPACK 00546 if((solverName == "amesos2_lapack") || 00547 (solverName == "lapack")){ 00548 return handle_solver_type_support<Lapack,Matrix,Vector>::apply(A, X, B); 00549 } 00550 #endif 00551 00552 /* If none of the above conditionals are satisfied, then the solver 00553 * requested is not yet supported. We throw a runtime exception stating 00554 * this, and return null. 00555 */ 00556 std::string err_msg = solver_name + " is not enabled or is not supported"; 00557 TEUCHOS_TEST_FOR_EXCEPTION(true, std::invalid_argument, err_msg); 00558 return( Teuchos::null ); 00559 } 00560 00561 } // end namespace Amesos2 00562 00563 #endif // AMESOS2_FACTORY_HPP
1.7.6.1