Amesos2 - Direct Sparse Solver Interfaces Version of the Day
Amesos2_Factory.hpp
Go to the documentation of this file.
1// @HEADER
2//
3// ***********************************************************************
4//
5// Amesos2: Templated Direct Sparse Solver Package
6// Copyright 2011 Sandia Corporation
7//
8// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
9// the U.S. Government retains certain rights in this software.
10//
11// Redistribution and use in source and binary forms, with or without
12// modification, are permitted provided that the following conditions are
13// met:
14//
15// 1. Redistributions of source code must retain the above copyright
16// notice, this list of conditions and the following disclaimer.
17//
18// 2. Redistributions in binary form must reproduce the above copyright
19// notice, this list of conditions and the following disclaimer in the
20// documentation and/or other materials provided with the distribution.
21//
22// 3. Neither the name of the Corporation nor the names of the
23// contributors may be used to endorse or promote products derived from
24// this software without specific prior written permission.
25//
26// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
27// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
30// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37//
38// Questions? Contact Michael A. Heroux (maherou@sandia.gov)
39//
40// ***********************************************************************
41//
42// @HEADER
43
82#ifndef AMESOS2_FACTORY_HPP
83#define AMESOS2_FACTORY_HPP
84
85#include "Amesos2_config.h"
86
87#include "Amesos2_Solver.hpp"
89
90#include "Teuchos_ScalarTraits.hpp"
92#include "Amesos2_MatrixTraits.hpp"
93#include "Amesos2_ctassert.hpp"
94
95#ifdef HAVE_AMESOS2_BASKER
96#include "Amesos2_Basker.hpp"
97#endif
98
99#ifdef HAVE_AMESOS2_SHYLUBASKER
100#include "Amesos2_ShyLUBasker.hpp"
101#endif
102
103#if defined(HAVE_AMESOS2_KLU2)
104#include "Amesos2_KLU2.hpp"
105#endif
106
107#ifdef HAVE_AMESOS2_SUPERLUDIST // Distributed-memory SuperLU
108#include "Amesos2_Superludist.hpp"
109#endif
110
111#ifdef HAVE_AMESOS2_SUPERLUMT // Multi-threaded SuperLU
112#include "Amesos2_Superlumt.hpp"
113#endif
114
115#ifdef HAVE_AMESOS2_UMFPACK // Umfpack
116#include "Amesos2_Umfpack.hpp"
117#endif
118
119#ifdef HAVE_AMESOS2_TACHO // Tacho
120#include "Amesos2_Tacho.hpp"
121#endif
122
123#ifdef HAVE_AMESOS2_SUPERLU // Sequential SuperLU
124#include "Amesos2_Superlu.hpp"
125#endif
126
127#ifdef HAVE_AMESOS2_PARDISO_MKL // MKL version of Pardiso
128#include "Amesos2_PardisoMKL.hpp"
129#endif
130
131#ifdef HAVE_AMESOS2_LAPACK
132#include "Amesos2_Lapack.hpp"
133#endif
134
135#if defined (HAVE_AMESOS2_CHOLMOD) && defined (HAVE_AMESOS2_EXPERIMENTAL)
136#include "Amesos2_Cholmod.hpp"
137#endif
138
139#if defined (HAVE_AMESOS2_CUSOLVER) && defined (HAVE_AMESOS2_CUSPARSE)
140#include "Amesos2_cuSOLVER.hpp"
141#endif
142
143#ifdef HAVE_AMESOS2_MUMPS
144#include "Amesos2_MUMPS.hpp"
145#endif
146
147#ifdef HAVE_AMESOS2_STRUMPACK
148#include "Amesos2_STRUMPACK.hpp"
149#endif
150
151
152namespace Amesos2 {
153
154 template <class,class> class Solver;
155
156 /*
157 * Utility function to transform a string into all lowercase
158 */
159 std::string tolower(const std::string& s);
160
161
176 template < class Matrix,
177 class Vector >
178 Solver<Matrix,Vector>*
179 create(const Matrix* A, Vector* X, const Vector* B);
180
181
196 template < class Matrix,
197 class Vector >
198 Teuchos::RCP<Solver<Matrix,Vector> >
199 create(Teuchos::RCP<const Matrix> A,
200 Teuchos::RCP<Vector> X,
201 Teuchos::RCP<const Vector> B);
202
203
221 template < class Matrix,
222 class Vector >
223 Solver<Matrix,Vector>*
224 create(const char* solverName, const Matrix* A, Vector* X, const Vector* B);
225
226
243 template < class Matrix,
244 class Vector >
245 Teuchos::RCP<Solver<Matrix,Vector> >
246 create(const char* solverName,
247 const Teuchos::RCP<const Matrix> A,
248 const Teuchos::RCP<Vector> X,
249 const Teuchos::RCP<const Vector> B);
250
251
268 template < class Matrix,
269 class Vector >
270 Solver<Matrix,Vector>*
271 create(const std::string solverName, const Matrix* A, Vector* X, const Vector* B);
272
273
290 template < class Matrix,
291 class Vector >
292 Teuchos::RCP<Solver<Matrix,Vector> >
293 create(const std::string solverName,
294 const Teuchos::RCP<const Matrix> A,
295 const Teuchos::RCP<Vector> X,
296 const Teuchos::RCP<const Vector> B);
297
298
317 template < class Matrix,
318 class Vector >
319 Solver<Matrix,Vector>*
320 create(const std::string solverName, const Matrix* A);
321
322
341 template < class Matrix,
342 class Vector >
343 Teuchos::RCP<Solver<Matrix,Vector> >
344 create(const std::string solverName,
345 const Teuchos::RCP<const Matrix> A);
346
347
349 // Meta-functions to help with creation of solvers //
351
352 template < template <class,class> class ConcreteSolver,
353 class Matrix,
354 class Vector >
355 struct create_solver_with_supported_type {
356 static Teuchos::RCP<Solver<Matrix,Vector> > apply(Teuchos::RCP<const Matrix> A,
357 Teuchos::RCP<Vector> X,
358 Teuchos::RCP<const Vector> B )
359 {
360 ctassert<
361 Meta::is_same<
362 typename MatrixTraits<Matrix>::scalar_t,
363 typename MultiVecAdapter<Vector>::scalar_t
364 >::value
365 > same_scalar_assertion;
366 (void)same_scalar_assertion; // This stops the compiler from warning about unused declared variables
367
368 // If our assertion did not fail, then create and return a new solver
369 return rcp( new ConcreteSolver<Matrix,Vector>(A, X, B) );
370 }
371 };
372
381template < template <class,class> class ConcreteSolver,
382 class Matrix,
383 class Vector >
384struct throw_no_scalar_support_exception {
385 static Teuchos::RCP<Solver<Matrix,Vector> > apply(Teuchos::RCP<const Matrix> A,
386 Teuchos::RCP<Vector> X,
387 Teuchos::RCP<const Vector> B )
388 {
389 // typedef ConcreteSolver<Matrix,Vector> concretesolver_matrix_vector;
390 typedef typename MatrixTraits<Matrix>::scalar_t scalar_t;
391 TEUCHOS_TEST_FOR_EXCEPTION( true,
392 std::invalid_argument,
393 "The requested Amesos2 "
394 // << concretesolver_matrix_vector::name <<
395 " solver interface does not support the " <<
396 Teuchos::ScalarTraits<scalar_t>::name() <<
397 " scalar type." );
398 }
399};
400
401template < template <class,class> class ConcreteSolver,
402 class Matrix,
403 class Vector >
404struct throw_no_matrix_support_exception {
405 static Teuchos::RCP<Solver<Matrix,Vector> > apply(Teuchos::RCP<const Matrix> A,
406 Teuchos::RCP<Vector> X,
407 Teuchos::RCP<const Vector> B )
408 {
409 TEUCHOS_TEST_FOR_EXCEPTION( true,
410 std::invalid_argument,
411 "This solver does not support the kokkos adapter." );
412 }
413};
414
424 template < template <class,class> class ConcreteSolver,
425 class Matrix,
426 class Vector >
427 struct handle_solver_scalar_type_support {
428 static Teuchos::RCP<Solver<Matrix,Vector> > apply(Teuchos::RCP<const Matrix> A,
429 Teuchos::RCP<Vector> X,
430 Teuchos::RCP<const Vector> B )
431 {
432 return Meta::if_then_else<
433 solver_supports_scalar<ConcreteSolver, typename MatrixTraits<Matrix>::scalar_t>::value,
434 create_solver_with_supported_type<ConcreteSolver,Matrix,Vector>,
435 throw_no_scalar_support_exception<ConcreteSolver,Matrix,Vector> >::type::apply(A, X, B);
436 }
437 };
438
448 template < template <class,class> class ConcreteSolver,
449 class Matrix,
450 class Vector >
451 struct handle_solver_matrix_and_type_support {
452 static Teuchos::RCP<Solver<Matrix,Vector> > apply(Teuchos::RCP<const Matrix> A,
453 Teuchos::RCP<Vector> X,
454 Teuchos::RCP<const Vector> B )
455 {
456 return Meta::if_then_else<
457 solver_supports_matrix<ConcreteSolver, Matrix>::value,
458 handle_solver_scalar_type_support<ConcreteSolver,Matrix,Vector>,
459 throw_no_matrix_support_exception<ConcreteSolver,Matrix,Vector> >::type::apply(A, X, B);
460 }
461 };
462
464 // Query Functions //
466
474 bool query(const char* solverName);
475
476
484 bool query(const std::string solverName);
485
486
488 // Definitions //
490
491 template <class Matrix,
492 class Vector >
493 Solver<Matrix,Vector>*
494 create(Matrix* A, Vector* X, Vector* B)
495 {
496 std::string solver = "Klu2";
497 // Pass non-owning RCP objects to other factory method
498 return( create(solver, rcp(A,false), rcp(X,false), rcp(B,false)).getRawPtr() );
499 }
500
501
502 template <class Matrix,
503 class Vector >
504 Teuchos::RCP<Solver<Matrix,Vector> >
505 create(Teuchos::RCP<const Matrix> A,
506 Teuchos::RCP<Vector> X,
507 Teuchos::RCP<const Vector> B)
508 {
509 std::string solver = "Klu2";
510 return( create(solver, A, X, B) );
511 }
512
513
514 template <class Matrix,
515 class Vector >
516 Solver<Matrix,Vector>*
517 create(const char* solverName, const Matrix* A, Vector* X, const Vector* B)
518 {
519 std::string solver = solverName;
520 // Pass non-owning Teuchos::RCP objects to other factory method
521 return( create(solver, rcp(A,false), rcp(X,false), rcp(B,false)).getRawPtr() );
522 }
523
524
525 template <class Matrix,
526 class Vector >
527 Teuchos::RCP<Solver<Matrix,Vector> >
528 create(const char* solverName,
529 const Teuchos::RCP<const Matrix> A,
530 const Teuchos::RCP<Vector> X,
531 const Teuchos::RCP<const Vector> B)
532 {
533 std::string solver = solverName;
534 return( create(solver, A, X, B) );
535 }
536
537
538 template <class Matrix,
539 class Vector >
540 Solver<Matrix,Vector>*
541 create(const std::string solverName, const Matrix* A){
542 return( create(solverName, rcp(A,false),
543 Teuchos::RCP<Vector>(),
544 Teuchos::RCP<const Vector>()).getRawPtr() );
545 }
546
547
548 template <class Matrix,
549 class Vector >
550 Teuchos::RCP<Solver<Matrix,Vector> >
551 create(const std::string solverName, const Teuchos::RCP<const Matrix> A){
552 return( create(solverName, A, Teuchos::RCP<Vector>(), Teuchos::RCP<const Vector>()) );
553 }
554
555
556 template <class Matrix,
557 class Vector >
558 Teuchos::RCP<Solver<Matrix,Vector> >
559 create(const std::string solverName, const Matrix* A, Vector* X, const Vector* B)
560 {
561 // Pass non-owning Teuchos::RCP objects to other factory method
562 return( create(solverName, rcp(A,false), rcp(X,false), rcp(B,false)) );
563 }
564
565
566 template <class Matrix,
567 class Vector >
568 Teuchos::RCP<Solver<Matrix,Vector> >
569 create(const std::string solver_name,
570 const Teuchos::RCP<const Matrix> A,
571 const Teuchos::RCP<Vector> X,
572 const Teuchos::RCP<const Vector> B)
573 {
574 std::string solverName = tolower(solver_name); // for easy string checking
575
576 // Check for our native solver first. Treat KLU and KLU2 as equals.
577 //
578 // We use compiler guards in case a user does want to disable KLU2
579#ifdef HAVE_AMESOS2_SHYLUBASKER
580 if((solverName == "ShyLUBasker") || (solverName == "shylubasker") || (solverName == "amesos2_shylubasker"))
581 {
582 return handle_solver_matrix_and_type_support<ShyLUBasker, Matrix,Vector>::apply(A,X,B);
583 }
584#endif
585
586#ifdef HAVE_AMESOS2_BASKER
587 if((solverName == "Basker") || (solverName == "basker") || (solverName == "amesos2_basker"))
588 {
589 return handle_solver_matrix_and_type_support<Basker, Matrix,Vector>::apply(A,X,B);
590 }
591#endif
592
593
594#ifdef HAVE_AMESOS2_KLU2
595 if((solverName == "amesos2_klu2") || (solverName == "klu2") ||
596 (solverName == "amesos2_klu") || (solverName == "klu")){
597 return handle_solver_matrix_and_type_support<KLU2,Matrix,Vector>::apply(A, X, B);
598 }
599#endif
600
601#ifdef HAVE_AMESOS2_SUPERLUDIST
602 if((solverName == "amesos2_superludist") ||
603 (solverName == "superludist") ||
604 (solverName == "amesos2_superlu_dist") ||
605 (solverName == "superlu_dist")){
606 return handle_solver_matrix_and_type_support<Superludist,Matrix,Vector>::apply(A, X, B);
607 }
608#endif
609
610#ifdef HAVE_AMESOS2_SUPERLUMT
611 if((solverName == "amesos2_superlumt") ||
612 (solverName == "superlumt") ||
613 (solverName == "amesos2_superlu_mt") ||
614 (solverName == "superlu_mt")){
615 return handle_solver_matrix_and_type_support<Superlumt,Matrix,Vector>::apply(A, X, B);
616 }
617#endif
618
619#ifdef HAVE_AMESOS2_UMFPACK
620 if((solverName == "amesos2_umfpack") ||
621 (solverName == "umfpack")){
622 return handle_solver_matrix_and_type_support<Umfpack,Matrix,Vector>::apply(A, X, B);
623 }
624#endif
625
626#ifdef HAVE_AMESOS2_TACHO
627 if((solverName == "amesos2_tacho") ||
628 (solverName == "tacho")){
629 return handle_solver_matrix_and_type_support<TachoSolver,Matrix,Vector>::apply(A, X, B);
630 }
631
632#endif
633
634#ifdef HAVE_AMESOS2_SUPERLU
635 if((solverName == "amesos2_superlu") ||
636 (solverName == "superlu")){
637 return handle_solver_matrix_and_type_support<Superlu,Matrix,Vector>::apply(A, X, B);
638 }
639#endif
640
641#ifdef HAVE_AMESOS2_PARDISO_MKL
642 if((solverName == "amesos2_pardiso_mkl") ||
643 (solverName == "pardiso_mkl") ||
644 (solverName == "amesos2_pardisomkl") ||
645 (solverName == "pardisomkl")){
646 return handle_solver_matrix_and_type_support<PardisoMKL,Matrix,Vector>::apply(A, X, B);
647 }
648#endif
649
650#ifdef HAVE_AMESOS2_LAPACK
651 if((solverName == "amesos2_lapack") ||
652 (solverName == "lapack")){
653 return handle_solver_matrix_and_type_support<Lapack,Matrix,Vector>::apply(A, X, B);
654 }
655#endif
656
657
658#ifdef HAVE_AMESOS2_MUMPS
659 if((solverName == "MUMPS") || (solverName == "mumps") ||
660 (solverName == "amesos2_MUMPS") || (solverName == "amesos2_mumps"))
661 {
662 return handle_solver_matrix_and_type_support<MUMPS,Matrix,Vector>::apply(A,X,B);
663 }
664#endif
665
666#ifdef HAVE_AMESOS2_STRUMPACK
667 if((solverName == "STRUMPACK") || (solverName == "strumpack") ||
668 (solverName == "amesos2_STRUMPACK") || (solverName == "amesos2_strumpack"))
669 {
670 return handle_solver_matrix_and_type_support<STRUMPACK,Matrix,Vector>::apply(A,X,B);
671 }
672#endif
673
674#if defined (HAVE_AMESOS2_CHOLMOD) && defined (HAVE_AMESOS2_EXPERIMENTAL)
675 if(solverName == "amesos2_cholmod" || solverName == "cholmod")
676 return handle_solver_matrix_and_type_support<Cholmod,Matrix,Vector>::apply(A, X, B);
677#endif
678
679#if defined (HAVE_AMESOS2_CUSOLVER) && defined (HAVE_AMESOS2_CUSPARSE)
680 if(solverName == "amesos2_cusolver" || solverName == "cusolver")
681 return handle_solver_matrix_and_type_support<cuSOLVER,Matrix,Vector>::apply(A, X, B);
682#endif
683
684 /* If none of the above conditionals are satisfied, then the solver
685 * requested is not yet supported. We throw a runtime exception stating
686 * this, and return null.
687 */
688 std::string err_msg = solver_name + " is not enabled or is not supported";
689 TEUCHOS_TEST_FOR_EXCEPTION(true, std::invalid_argument, err_msg);
690 //return( Teuchos::null ); // unreachable
691 }
692
693} // end namespace Amesos2
694
695#endif // AMESOS2_FACTORY_HPP
A templated adapter/wrapper class for Trilinos Multivector type classes. Provides the functions neces...
Provides access to interesting solver traits.
Simple compile-time assertion class.