|
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 #if defined(HAVE_AMESOS2_KLU2) & !(defined HAVE_TPETRA_INST_COMPLEX_FLOAT) 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 #if defined (HAVE_AMESOS2_CHOLMOD) && defined (HAVE_AMESOS2_EXPERIMENTAL) 00114 #include "Amesos2_Cholmod.hpp" 00115 #endif 00116 00117 namespace Amesos2 { 00118 00119 template <class,class> class Solver; 00120 00121 /* 00122 * Utility function to transform a string into all lowercase 00123 */ 00124 std::string tolower(const std::string& s); 00125 00126 00141 template < class Matrix, 00142 class Vector > 00143 Solver<Matrix,Vector>* 00144 create(const Matrix* A, Vector* X, const Vector* B); 00145 00146 00161 template < class Matrix, 00162 class Vector > 00163 Teuchos::RCP<Solver<Matrix,Vector> > 00164 create(Teuchos::RCP<const Matrix> A, 00165 Teuchos::RCP<Vector> X, 00166 Teuchos::RCP<const Vector> B); 00167 00168 00186 template < class Matrix, 00187 class Vector > 00188 Solver<Matrix,Vector>* 00189 create(const char* solverName, const Matrix* A, Vector* X, const Vector* B); 00190 00191 00208 template < class Matrix, 00209 class Vector > 00210 Teuchos::RCP<Solver<Matrix,Vector> > 00211 create(const char* solverName, 00212 const Teuchos::RCP<const Matrix> A, 00213 const Teuchos::RCP<Vector> X, 00214 const Teuchos::RCP<const Vector> B); 00215 00216 00233 template < class Matrix, 00234 class Vector > 00235 Solver<Matrix,Vector>* 00236 create(const std::string solverName, const Matrix* A, Vector* X, const Vector* B); 00237 00238 00255 template < class Matrix, 00256 class Vector > 00257 Teuchos::RCP<Solver<Matrix,Vector> > 00258 create(const std::string solverName, 00259 const Teuchos::RCP<const Matrix> A, 00260 const Teuchos::RCP<Vector> X, 00261 const Teuchos::RCP<const Vector> B); 00262 00263 00282 template < class Matrix, 00283 class Vector > 00284 Solver<Matrix,Vector>* 00285 create(const std::string solverName, const Matrix* A); 00286 00287 00306 template < class Matrix, 00307 class Vector > 00308 Teuchos::RCP<Solver<Matrix,Vector> > 00309 create(const std::string solverName, 00310 const Teuchos::RCP<const Matrix> A); 00311 00312 00314 // Meta-functions to help with creation of solvers // 00316 00317 template < template <class,class> class ConcreteSolver, 00318 class Matrix, 00319 class Vector > 00320 struct create_solver_with_supported_type { 00321 static Teuchos::RCP<Solver<Matrix,Vector> > apply(Teuchos::RCP<const Matrix> A, 00322 Teuchos::RCP<Vector> X, 00323 Teuchos::RCP<const Vector> B ) 00324 { 00325 ctassert< 00326 Meta::is_same< 00327 typename MatrixTraits<Matrix>::scalar_t, 00328 typename MultiVecAdapter<Vector>::scalar_t 00329 >::value 00330 > same_scalar_assertion; 00331 (void)same_scalar_assertion; // This stops the compiler from warning about unused declared variables 00332 00333 // If our assertion did not fail, then create and return a new solver 00334 return rcp( new ConcreteSolver<Matrix,Vector>(A, X, B) ); 00335 } 00336 }; 00337 00346 template < template <class,class> class ConcreteSolver, 00347 class Matrix, 00348 class Vector > 00349 struct throw_no_scalar_support_exception { 00350 static Teuchos::RCP<Solver<Matrix,Vector> > apply(Teuchos::RCP<const Matrix> A, 00351 Teuchos::RCP<Vector> X, 00352 Teuchos::RCP<const Vector> B ) 00353 { 00354 // typedef ConcreteSolver<Matrix,Vector> concretesolver_matrix_vector; 00355 typedef typename MatrixTraits<Matrix>::scalar_t scalar_t; 00356 TEUCHOS_TEST_FOR_EXCEPTION( true, 00357 std::invalid_argument, 00358 "The requested Amesos2 " 00359 // << concretesolver_matrix_vector::name << 00360 " solver interface does not support the " << 00361 Teuchos::ScalarTraits<scalar_t>::name() << 00362 " scalar type." ); 00363 } 00364 }; 00365 00375 template < template <class,class> class ConcreteSolver, 00376 class Matrix, 00377 class Vector > 00378 struct handle_solver_type_support { 00379 static Teuchos::RCP<Solver<Matrix,Vector> > apply(Teuchos::RCP<const Matrix> A, 00380 Teuchos::RCP<Vector> X, 00381 Teuchos::RCP<const Vector> B ) 00382 { 00383 return Meta::if_then_else< 00384 solver_supports_scalar<ConcreteSolver, typename MatrixTraits<Matrix>::scalar_t>::value, 00385 create_solver_with_supported_type<ConcreteSolver,Matrix,Vector>, 00386 throw_no_scalar_support_exception<ConcreteSolver,Matrix,Vector> >::type::apply(A, X, B); 00387 } 00388 }; 00389 00390 00392 // Query Functions // 00394 00402 bool query(const char* solverName); 00403 00404 00412 bool query(const std::string solverName); 00413 00414 00416 // Definitions // 00418 00419 template <class Matrix, 00420 class Vector > 00421 Solver<Matrix,Vector>* 00422 create(Matrix* A, Vector* X, Vector* B) 00423 { 00424 std::string solver = "Klu2"; 00425 // Pass non-owning RCP objects to other factory method 00426 return( create(solver, rcp(A,false), rcp(X,false), rcp(B,false)).getRawPtr() ); 00427 } 00428 00429 00430 template <class Matrix, 00431 class Vector > 00432 Teuchos::RCP<Solver<Matrix,Vector> > 00433 create(Teuchos::RCP<const Matrix> A, 00434 Teuchos::RCP<Vector> X, 00435 Teuchos::RCP<const Vector> B) 00436 { 00437 std::string solver = "Klu2"; 00438 return( create(solver, A, X, B) ); 00439 } 00440 00441 00442 template <class Matrix, 00443 class Vector > 00444 Solver<Matrix,Vector>* 00445 create(const char* solverName, const Matrix* A, Vector* X, const Vector* B) 00446 { 00447 std::string solver = solverName; 00448 // Pass non-owning Teuchos::RCP objects to other factory method 00449 return( create(solver, rcp(A,false), rcp(X,false), rcp(B,false)).getRawPtr() ); 00450 } 00451 00452 00453 template <class Matrix, 00454 class Vector > 00455 Teuchos::RCP<Solver<Matrix,Vector> > 00456 create(const char* solverName, 00457 const Teuchos::RCP<const Matrix> A, 00458 const Teuchos::RCP<Vector> X, 00459 const Teuchos::RCP<const Vector> B) 00460 { 00461 std::string solver = solverName; 00462 return( create(solver, A, X, B) ); 00463 } 00464 00465 00466 template <class Matrix, 00467 class Vector > 00468 Solver<Matrix,Vector>* 00469 create(const std::string solverName, const Matrix* A){ 00470 return( create(solverName, rcp(A,false), 00471 Teuchos::RCP<Vector>(), 00472 Teuchos::RCP<const Vector>()).getRawPtr() ); 00473 } 00474 00475 00476 template <class Matrix, 00477 class Vector > 00478 Teuchos::RCP<Solver<Matrix,Vector> > 00479 create(const std::string solverName, const Teuchos::RCP<const Matrix> A){ 00480 return( create(solverName, A, Teuchos::RCP<Vector>(), Teuchos::RCP<const Vector>()) ); 00481 } 00482 00483 00484 template <class Matrix, 00485 class Vector > 00486 Teuchos::RCP<Solver<Matrix,Vector> > 00487 create(const std::string solverName, const Matrix* A, Vector* X, const Vector* B) 00488 { 00489 // Pass non-owning Teuchos::RCP objects to other factory method 00490 return( create(solverName, rcp(A,false), rcp(X,false), rcp(B,false)) ); 00491 } 00492 00493 00494 template <class Matrix, 00495 class Vector > 00496 Teuchos::RCP<Solver<Matrix,Vector> > 00497 create(const std::string solver_name, 00498 const Teuchos::RCP<const Matrix> A, 00499 const Teuchos::RCP<Vector> X, 00500 const Teuchos::RCP<const Vector> B) 00501 { 00502 std::string solverName = tolower(solver_name); // for easy string checking 00503 00504 // Check for our native solver first. Treat KLU and KLU2 as equals. 00505 // 00506 // We use compiler guards in case a user does want to disable KLU2 00507 #ifdef HAVE_AMESOS2_KLU2 00508 00509 if((solverName == "amesos2_klu2") || (solverName == "klu2") || 00510 (solverName == "amesos2_klu") || (solverName == "klu")){ 00511 #ifdef HAVE_TPETRA_INST_COMPLEX_FLOAT 00512 std::string err_msg = solver_name + " is not is not supported with complex<float>"; 00513 TEUCHOS_TEST_FOR_EXCEPTION(true, std::invalid_argument, err_msg); 00514 return( Teuchos::null ); 00515 #else 00516 return handle_solver_type_support<KLU2,Matrix,Vector>::apply(A, X, B); 00517 } 00518 #endif 00519 #endif 00520 00521 #ifdef HAVE_AMESOS2_SUPERLUDIST 00522 if((solverName == "amesos2_superludist") || 00523 (solverName == "superludist") || 00524 (solverName == "amesos2_superlu_dist") || 00525 (solverName == "superlu_dist")){ 00526 return handle_solver_type_support<Superludist,Matrix,Vector>::apply(A, X, B); 00527 } 00528 #endif 00529 00530 #ifdef HAVE_AMESOS2_SUPERLUMT 00531 if((solverName == "amesos2_superlumt") || 00532 (solverName == "superlumt") || 00533 (solverName == "amesos2_superlu_mt") || 00534 (solverName == "superlu_mt")){ 00535 return handle_solver_type_support<Superlumt,Matrix,Vector>::apply(A, X, B); 00536 } 00537 #endif 00538 00539 #ifdef HAVE_AMESOS2_SUPERLU 00540 if((solverName == "amesos2_superlu") || 00541 (solverName == "superlu")){ 00542 return handle_solver_type_support<Superlu,Matrix,Vector>::apply(A, X, B); 00543 } 00544 #endif 00545 00546 #ifdef HAVE_AMESOS2_PARDISO_MKL 00547 if((solverName == "amesos2_pardiso_mkl") || 00548 (solverName == "pardiso_mkl") || 00549 (solverName == "amesos2_pardisomkl") || 00550 (solverName == "pardisomkl")){ 00551 return handle_solver_type_support<PardisoMKL,Matrix,Vector>::apply(A, X, B); 00552 } 00553 #endif 00554 00555 #ifdef HAVE_AMESOS2_LAPACK 00556 if((solverName == "amesos2_lapack") || 00557 (solverName == "lapack")){ 00558 return handle_solver_type_support<Lapack,Matrix,Vector>::apply(A, X, B); 00559 } 00560 #endif 00561 00562 #if defined (HAVE_AMESOS2_CHOLMOD) && defined (HAVE_AMESOS2_EXPERIMENTAL) 00563 if(solverName == "amesos2_cholmod") 00564 return handle_solver_type_support<Cholmod,Matrix,Vector>::apply(A, X, B); 00565 #endif 00566 00567 /* If none of the above conditionals are satisfied, then the solver 00568 * requested is not yet supported. We throw a runtime exception stating 00569 * this, and return null. 00570 */ 00571 err_msg = solver_name + " is not enabled or is not supported"; 00572 TEUCHOS_TEST_FOR_EXCEPTION(true, std::invalid_argument, err_msg); 00573 return( Teuchos::null ); 00574 } 00575 00576 } // end namespace Amesos2 00577 00578 #endif // AMESOS2_FACTORY_HPP
1.7.6.1