Amesos2 - Direct Sparse Solver Interfaces Version of the Day
Amesos2_Factory.hpp
Go to the documentation of this file.
1// @HEADER
2// *****************************************************************************
3// Amesos2: Templated Direct Sparse Solver Package
4//
5// Copyright 2011 NTESS and the Amesos2 contributors.
6// SPDX-License-Identifier: BSD-3-Clause
7// *****************************************************************************
8// @HEADER
9
48#ifndef AMESOS2_FACTORY_HPP
49#define AMESOS2_FACTORY_HPP
50
51#include "Amesos2_config.h"
52
53#include "Teuchos_CompilerCodeTweakMacros.hpp"
54
55#include "Amesos2_Solver.hpp"
57
58#include "Teuchos_ScalarTraits.hpp"
60#include "Amesos2_MatrixTraits.hpp"
61#include "Amesos2_ctassert.hpp"
62
63#ifdef HAVE_AMESOS2_BASKER
64#include "Amesos2_Basker.hpp"
65#endif
66
67#ifdef HAVE_AMESOS2_SHYLU_NODEBASKER
68#include "Amesos2_ShyLUBasker.hpp"
69#endif
70
71#if defined(HAVE_AMESOS2_KLU2)
72#include "Amesos2_KLU2.hpp"
73#endif
74
75#ifdef HAVE_AMESOS2_SUPERLUDIST // Distributed-memory SuperLU
76#include "Amesos2_Superludist.hpp"
77#endif
78
79#ifdef HAVE_AMESOS2_SUPERLUMT // Multi-threaded SuperLU
80#include "Amesos2_Superlumt.hpp"
81#endif
82
83#ifdef HAVE_AMESOS2_UMFPACK // Umfpack
84#include "Amesos2_Umfpack.hpp"
85#endif
86
87#ifdef HAVE_AMESOS2_SHYLU_NODETACHO // Tacho
88#include "Amesos2_Tacho.hpp"
89#endif
90
91#ifdef HAVE_AMESOS2_SUPERLU // Sequential SuperLU
92#include "Amesos2_Superlu.hpp"
93#endif
94
95#ifdef HAVE_AMESOS2_PARDISO_MKL // MKL version of Pardiso
96#include "Amesos2_PardisoMKL.hpp"
97#endif
98
99#ifdef HAVE_AMESOS2_CSS_MKL // Cluster-Sparse solver from MKL
100#include "Amesos2_CssMKL.hpp"
101#endif
102
103#ifdef HAVE_AMESOS2_LAPACK
104#include "Amesos2_Lapack.hpp"
105#endif
106
107#if defined (HAVE_AMESOS2_CHOLMOD) && defined (HAVE_AMESOS2_EXPERIMENTAL)
108#include "Amesos2_Cholmod.hpp"
109#endif
110
111#if defined (HAVE_AMESOS2_CUSOLVER) && defined (HAVE_AMESOS2_CUSPARSE)
112#include "Amesos2_cuSOLVER.hpp"
113#endif
114
115#ifdef HAVE_AMESOS2_MUMPS
116#include "Amesos2_MUMPS.hpp"
117#endif
118
119#ifdef HAVE_AMESOS2_STRUMPACK
120#include "Amesos2_STRUMPACK.hpp"
121#endif
122
123
124namespace Amesos2 {
125
126 template <class,class> class Solver;
127
128 /*
129 * Utility function to transform a string into all lowercase
130 */
131 std::string tolower(const std::string& s);
132
133
148 template < class Matrix,
149 class Vector >
150 Solver<Matrix,Vector>*
151 create(const Matrix* A, Vector* X, const Vector* B);
152
153
168 template < class Matrix,
169 class Vector >
170 Teuchos::RCP<Solver<Matrix,Vector> >
171 create(Teuchos::RCP<const Matrix> A,
172 Teuchos::RCP<Vector> X,
173 Teuchos::RCP<const Vector> B);
174
175
193 template < class Matrix,
194 class Vector >
195 Solver<Matrix,Vector>*
196 create(const char* solverName, const Matrix* A, Vector* X, const Vector* B);
197
198
215 template < class Matrix,
216 class Vector >
217 Teuchos::RCP<Solver<Matrix,Vector> >
218 create(const char* solverName,
219 const Teuchos::RCP<const Matrix> A,
220 const Teuchos::RCP<Vector> X,
221 const Teuchos::RCP<const Vector> B);
222
223
240 template < class Matrix,
241 class Vector >
242 Solver<Matrix,Vector>*
243 create(const std::string& solverName, const Matrix* A, Vector* X, const Vector* B);
244
245
262 template < class Matrix,
263 class Vector >
264 Teuchos::RCP<Solver<Matrix,Vector> >
265 create(const std::string& solverName,
266 const Teuchos::RCP<const Matrix> A,
267 const Teuchos::RCP<Vector> X,
268 const Teuchos::RCP<const Vector> B);
269
270
289 template < class Matrix,
290 class Vector >
291 Solver<Matrix,Vector>*
292 create(const std::string& solverName, const Matrix* A);
293
294
313 template < class Matrix,
314 class Vector >
315 Teuchos::RCP<Solver<Matrix,Vector> >
316 create(const std::string& solverName,
317 const Teuchos::RCP<const Matrix> A);
318
319
321 // Meta-functions to help with creation of solvers //
323
324 template < template <class,class> class ConcreteSolver,
325 class Matrix,
326 class Vector >
327 struct create_solver_with_supported_type {
328 static Teuchos::RCP<Solver<Matrix,Vector> > apply(Teuchos::RCP<const Matrix> A,
329 Teuchos::RCP<Vector> X,
330 Teuchos::RCP<const Vector> B )
331 {
332 ctassert<
333 std::is_same_v<
334 typename MatrixTraits<Matrix>::scalar_t,
335 typename MultiVecAdapter<Vector>::scalar_t
336 >
337 > same_scalar_assertion;
338 (void)same_scalar_assertion; // This stops the compiler from warning about unused declared variables
339
340 // If our assertion did not fail, then create and return a new solver
341 return rcp( new ConcreteSolver<Matrix,Vector>(A, X, B) );
342 }
343 };
344
353template < template <class,class> class ConcreteSolver,
354 class Matrix,
355 class Vector >
356struct throw_no_scalar_support_exception {
357 static Teuchos::RCP<Solver<Matrix,Vector> > apply(Teuchos::RCP<const Matrix> A,
358 Teuchos::RCP<Vector> X,
359 Teuchos::RCP<const Vector> B )
360 {
361 // typedef ConcreteSolver<Matrix,Vector> concretesolver_matrix_vector;
362 typedef typename MatrixTraits<Matrix>::scalar_t scalar_t;
363 TEUCHOS_TEST_FOR_EXCEPTION( true,
364 std::invalid_argument,
365 "The requested Amesos2 "
366 // << concretesolver_matrix_vector::name <<
367 " solver interface does not support the " <<
368 Teuchos::ScalarTraits<scalar_t>::name() <<
369 " scalar type." );
370 }
371};
372
373template < template <class,class> class ConcreteSolver,
374 class Matrix,
375 class Vector >
376struct throw_no_matrix_support_exception {
377 static Teuchos::RCP<Solver<Matrix,Vector> > apply(Teuchos::RCP<const Matrix> A,
378 Teuchos::RCP<Vector> X,
379 Teuchos::RCP<const Vector> B )
380 {
381 TEUCHOS_TEST_FOR_EXCEPTION( true,
382 std::invalid_argument,
383 "This solver does not support the kokkos adapter." );
384 }
385};
386
396 template < template <class,class> class ConcreteSolver,
397 class Matrix,
398 class Vector >
399 struct handle_solver_scalar_type_support {
400 static Teuchos::RCP<Solver<Matrix,Vector> > apply(Teuchos::RCP<const Matrix> A,
401 Teuchos::RCP<Vector> X,
402 Teuchos::RCP<const Vector> B )
403 {
404 return std::conditional_t<
405 solver_supports_scalar<ConcreteSolver, typename MatrixTraits<Matrix>::scalar_t>::value,
406 create_solver_with_supported_type<ConcreteSolver,Matrix,Vector>,
407 throw_no_scalar_support_exception<ConcreteSolver,Matrix,Vector> >::apply(A, X, B);
408 }
409 };
410
420 template < template <class,class> class ConcreteSolver,
421 class Matrix,
422 class Vector >
423 struct handle_solver_matrix_and_type_support {
424 static Teuchos::RCP<Solver<Matrix,Vector> > apply(Teuchos::RCP<const Matrix> A,
425 Teuchos::RCP<Vector> X,
426 Teuchos::RCP<const Vector> B )
427 {
428 return std::conditional_t<
429 solver_supports_matrix<ConcreteSolver, Matrix>::value,
430 handle_solver_scalar_type_support<ConcreteSolver,Matrix,Vector>,
431 throw_no_matrix_support_exception<ConcreteSolver,Matrix,Vector> >::apply(A, X, B);
432 }
433 };
434
436 // Query Functions //
438
446 bool query(const char* solverName);
447
448
456 bool query(const std::string& solverName);
457
458
460 // Definitions //
462
463 template <class Matrix,
464 class Vector >
465 Solver<Matrix,Vector>*
466 create(Matrix* A, Vector* X, Vector* B)
467 {
468 std::string solver = "Klu2";
469 // Pass non-owning RCP objects to other factory method
470 return( create(solver, rcp(A,false), rcp(X,false), rcp(B,false)).getRawPtr() );
471 }
472
473
474 template <class Matrix,
475 class Vector >
476 Teuchos::RCP<Solver<Matrix,Vector> >
477 create(Teuchos::RCP<const Matrix> A,
478 Teuchos::RCP<Vector> X,
479 Teuchos::RCP<const Vector> B)
480 {
481 std::string solver = "Klu2";
482 return( create(solver, A, X, B) );
483 }
484
485
486 template <class Matrix,
487 class Vector >
488 Solver<Matrix,Vector>*
489 create(const char* solverName, const Matrix* A, Vector* X, const Vector* B)
490 {
491 std::string solver = solverName;
492 // Pass non-owning Teuchos::RCP objects to other factory method
493 return( create(solver, rcp(A,false), rcp(X,false), rcp(B,false)).getRawPtr() );
494 }
495
496
497 template <class Matrix,
498 class Vector >
499 Teuchos::RCP<Solver<Matrix,Vector> >
500 create(const char* solverName,
501 const Teuchos::RCP<const Matrix> A,
502 const Teuchos::RCP<Vector> X,
503 const Teuchos::RCP<const Vector> B)
504 {
505 std::string solver = solverName;
506 return( create(solver, A, X, B) );
507 }
508
509
510 template <class Matrix,
511 class Vector >
512 Solver<Matrix,Vector>*
513 create(const std::string& solverName, const Matrix* A){
514 return( create(solverName, rcp(A,false),
515 Teuchos::RCP<Vector>(),
516 Teuchos::RCP<const Vector>()).getRawPtr() );
517 }
518
519
520 template <class Matrix,
521 class Vector >
522 Teuchos::RCP<Solver<Matrix,Vector> >
523 create(const std::string& solverName, const Teuchos::RCP<const Matrix> A){
524 return( create(solverName, A, Teuchos::RCP<Vector>(), Teuchos::RCP<const Vector>()) );
525 }
526
527
528 template <class Matrix,
529 class Vector >
530 Teuchos::RCP<Solver<Matrix,Vector> >
531 create(const std::string& solverName, const Matrix* A, Vector* X, const Vector* B)
532 {
533 // Pass non-owning Teuchos::RCP objects to other factory method
534 return( create(solverName, rcp(A,false), rcp(X,false), rcp(B,false)) );
535 }
536
537
538 template <class Matrix,
539 class Vector >
540 Teuchos::RCP<Solver<Matrix,Vector> >
541 create(const std::string& solver_name,
542 const Teuchos::RCP<const Matrix> A,
543 const Teuchos::RCP<Vector> X,
544 const Teuchos::RCP<const Vector> B)
545 {
546 std::string solverName = tolower(solver_name); // for easy string checking
547
548 // Check for our native solver first. Treat KLU and KLU2 as equals.
549 //
550 // We use compiler guards in case a user does want to disable KLU2
551#ifdef HAVE_AMESOS2_SHYLU_NODEBASKER
552 if((solverName == "ShyLUBasker") || (solverName == "shylubasker") || (solverName == "amesos2_shylubasker"))
553 {
554 return handle_solver_matrix_and_type_support<ShyLUBasker, Matrix,Vector>::apply(A,X,B);
555 }
556#endif
557
558#ifdef HAVE_AMESOS2_BASKER
559 if((solverName == "Basker") || (solverName == "basker") || (solverName == "amesos2_basker"))
560 {
561 return handle_solver_matrix_and_type_support<Basker, Matrix,Vector>::apply(A,X,B);
562 }
563#endif
564
565
566#ifdef HAVE_AMESOS2_KLU2
567 if((solverName == "amesos2_klu2") || (solverName == "klu2") ||
568 (solverName == "amesos2_klu") || (solverName == "klu")){
569 return handle_solver_matrix_and_type_support<KLU2,Matrix,Vector>::apply(A, X, B);
570 }
571#endif
572
573#ifdef HAVE_AMESOS2_SUPERLUDIST
574 if((solverName == "amesos2_superludist") ||
575 (solverName == "superludist") ||
576 (solverName == "amesos2_superlu_dist") ||
577 (solverName == "superlu_dist")){
578 return handle_solver_matrix_and_type_support<Superludist,Matrix,Vector>::apply(A, X, B);
579 }
580#endif
581
582#ifdef HAVE_AMESOS2_SUPERLUMT
583 if((solverName == "amesos2_superlumt") ||
584 (solverName == "superlumt") ||
585 (solverName == "amesos2_superlu_mt") ||
586 (solverName == "superlu_mt")){
587 return handle_solver_matrix_and_type_support<Superlumt,Matrix,Vector>::apply(A, X, B);
588 }
589#endif
590
591#ifdef HAVE_AMESOS2_UMFPACK
592 if((solverName == "amesos2_umfpack") ||
593 (solverName == "umfpack")){
594 return handle_solver_matrix_and_type_support<Umfpack,Matrix,Vector>::apply(A, X, B);
595 }
596#endif
597
598#ifdef HAVE_AMESOS2_SHYLU_NODETACHO
599 if((solverName == "amesos2_tacho") ||
600 (solverName == "tacho")){
601 return handle_solver_matrix_and_type_support<TachoSolver,Matrix,Vector>::apply(A, X, B);
602 }
603
604#endif
605
606#ifdef HAVE_AMESOS2_SUPERLU
607 if((solverName == "amesos2_superlu") ||
608 (solverName == "superlu")){
609 return handle_solver_matrix_and_type_support<Superlu,Matrix,Vector>::apply(A, X, B);
610 }
611#endif
612
613#ifdef HAVE_AMESOS2_PARDISO_MKL
614 if((solverName == "amesos2_pardiso_mkl") ||
615 (solverName == "pardiso_mkl") ||
616 (solverName == "amesos2_pardisomkl") ||
617 (solverName == "pardisomkl")){
618 return handle_solver_matrix_and_type_support<PardisoMKL,Matrix,Vector>::apply(A, X, B);
619 }
620#endif
621#ifdef HAVE_AMESOS2_CSS_MKL
622 if((solverName == "amesos2_css_mkl") ||
623 (solverName == "css_mkl") ||
624 (solverName == "amesos2_cssmkl") ||
625 (solverName == "cssmkl")){
626 return handle_solver_matrix_and_type_support<CssMKL,Matrix,Vector>::apply(A, X, B);
627 }
628#endif
629
630#ifdef HAVE_AMESOS2_LAPACK
631 if((solverName == "amesos2_lapack") ||
632 (solverName == "lapack")){
633 return handle_solver_matrix_and_type_support<Lapack,Matrix,Vector>::apply(A, X, B);
634 }
635#endif
636
637
638#ifdef HAVE_AMESOS2_MUMPS
639 if((solverName == "MUMPS") || (solverName == "mumps") ||
640 (solverName == "amesos2_MUMPS") || (solverName == "amesos2_mumps"))
641 {
642 return handle_solver_matrix_and_type_support<MUMPS,Matrix,Vector>::apply(A,X,B);
643 }
644#endif
645
646#ifdef HAVE_AMESOS2_STRUMPACK
647 if((solverName == "STRUMPACK") || (solverName == "strumpack") ||
648 (solverName == "amesos2_STRUMPACK") || (solverName == "amesos2_strumpack"))
649 {
650 return handle_solver_matrix_and_type_support<STRUMPACK,Matrix,Vector>::apply(A,X,B);
651 }
652#endif
653
654#if defined (HAVE_AMESOS2_CHOLMOD) && defined (HAVE_AMESOS2_EXPERIMENTAL)
655 if(solverName == "amesos2_cholmod" || solverName == "cholmod")
656 return handle_solver_matrix_and_type_support<Cholmod,Matrix,Vector>::apply(A, X, B);
657#endif
658
659#if defined (HAVE_AMESOS2_CUSOLVER) && defined (HAVE_AMESOS2_CUSPARSE)
660 if(solverName == "amesos2_cusolver" || solverName == "cusolver")
661 return handle_solver_matrix_and_type_support<cuSOLVER,Matrix,Vector>::apply(A, X, B);
662#endif
663
664 /* If none of the above conditionals are satisfied, then the solver
665 * requested is not yet supported. We throw a runtime exception stating
666 * this, and return null.
667 */
668 std::string err_msg = solver_name + " is not enabled or is not supported";
669 TEUCHOS_TEST_FOR_EXCEPTION(true, std::invalid_argument, err_msg);
670 //return( Teuchos::null ); // unreachable
671 TEUCHOS_UNREACHABLE_RETURN(Teuchos::null);
672 }
673
674} // end namespace Amesos2
675
676#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.