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"
88 #include "Amesos2_SolverTraits.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 
148 namespace Amesos2 {
149 
150  template <class,class> class Solver;
151 
152  /*
153  * Utility function to transform a string into all lowercase
154  */
155  std::string tolower(const std::string& s);
156 
157 
172  template < class Matrix,
173  class Vector >
174  Solver<Matrix,Vector>*
175  create(const Matrix* A, Vector* X, const Vector* B);
176 
177 
192  template < class Matrix,
193  class Vector >
194  Teuchos::RCP<Solver<Matrix,Vector> >
195  create(Teuchos::RCP<const Matrix> A,
196  Teuchos::RCP<Vector> X,
197  Teuchos::RCP<const Vector> B);
198 
199 
217  template < class Matrix,
218  class Vector >
219  Solver<Matrix,Vector>*
220  create(const char* solverName, const Matrix* A, Vector* X, const Vector* B);
221 
222 
239  template < class Matrix,
240  class Vector >
241  Teuchos::RCP<Solver<Matrix,Vector> >
242  create(const char* solverName,
243  const Teuchos::RCP<const Matrix> A,
244  const Teuchos::RCP<Vector> X,
245  const Teuchos::RCP<const Vector> B);
246 
247 
264  template < class Matrix,
265  class Vector >
266  Solver<Matrix,Vector>*
267  create(const std::string solverName, const Matrix* A, Vector* X, const Vector* B);
268 
269 
286  template < class Matrix,
287  class Vector >
288  Teuchos::RCP<Solver<Matrix,Vector> >
289  create(const std::string solverName,
290  const Teuchos::RCP<const Matrix> A,
291  const Teuchos::RCP<Vector> X,
292  const Teuchos::RCP<const Vector> B);
293 
294 
313  template < class Matrix,
314  class Vector >
315  Solver<Matrix,Vector>*
316  create(const std::string solverName, const Matrix* A);
317 
318 
337  template < class Matrix,
338  class Vector >
339  Teuchos::RCP<Solver<Matrix,Vector> >
340  create(const std::string solverName,
341  const Teuchos::RCP<const Matrix> A);
342 
343 
345  // Meta-functions to help with creation of solvers //
347 
348  template < template <class,class> class ConcreteSolver,
349  class Matrix,
350  class Vector >
351  struct create_solver_with_supported_type {
352  static Teuchos::RCP<Solver<Matrix,Vector> > apply(Teuchos::RCP<const Matrix> A,
353  Teuchos::RCP<Vector> X,
354  Teuchos::RCP<const Vector> B )
355  {
356  ctassert<
357  Meta::is_same<
358  typename MatrixTraits<Matrix>::scalar_t,
359  typename MultiVecAdapter<Vector>::scalar_t
360  >::value
361  > same_scalar_assertion;
362  (void)same_scalar_assertion; // This stops the compiler from warning about unused declared variables
363 
364  // If our assertion did not fail, then create and return a new solver
365  return rcp( new ConcreteSolver<Matrix,Vector>(A, X, B) );
366  }
367  };
368 
377 template < template <class,class> class ConcreteSolver,
378  class Matrix,
379  class Vector >
380 struct throw_no_scalar_support_exception {
381  static Teuchos::RCP<Solver<Matrix,Vector> > apply(Teuchos::RCP<const Matrix> A,
382  Teuchos::RCP<Vector> X,
383  Teuchos::RCP<const Vector> B )
384  {
385  // typedef ConcreteSolver<Matrix,Vector> concretesolver_matrix_vector;
386  typedef typename MatrixTraits<Matrix>::scalar_t scalar_t;
387  TEUCHOS_TEST_FOR_EXCEPTION( true,
388  std::invalid_argument,
389  "The requested Amesos2 "
390  // << concretesolver_matrix_vector::name <<
391  " solver interface does not support the " <<
392  Teuchos::ScalarTraits<scalar_t>::name() <<
393  " scalar type." );
394  }
395 };
396 
397 template < template <class,class> class ConcreteSolver,
398  class Matrix,
399  class Vector >
400 struct throw_no_matrix_support_exception {
401  static Teuchos::RCP<Solver<Matrix,Vector> > apply(Teuchos::RCP<const Matrix> A,
402  Teuchos::RCP<Vector> X,
403  Teuchos::RCP<const Vector> B )
404  {
405  TEUCHOS_TEST_FOR_EXCEPTION( true,
406  std::invalid_argument,
407  "This solver does not support the kokkos adapter." );
408  }
409 };
410 
420  template < template <class,class> class ConcreteSolver,
421  class Matrix,
422  class Vector >
423  struct handle_solver_scalar_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 Meta::if_then_else<
429  solver_supports_scalar<ConcreteSolver, typename MatrixTraits<Matrix>::scalar_t>::value,
430  create_solver_with_supported_type<ConcreteSolver,Matrix,Vector>,
431  throw_no_scalar_support_exception<ConcreteSolver,Matrix,Vector> >::type::apply(A, X, B);
432  }
433  };
434 
444  template < template <class,class> class ConcreteSolver,
445  class Matrix,
446  class Vector >
447  struct handle_solver_matrix_and_type_support {
448  static Teuchos::RCP<Solver<Matrix,Vector> > apply(Teuchos::RCP<const Matrix> A,
449  Teuchos::RCP<Vector> X,
450  Teuchos::RCP<const Vector> B )
451  {
452  return Meta::if_then_else<
453  solver_supports_matrix<ConcreteSolver, Matrix>::value,
454  handle_solver_scalar_type_support<ConcreteSolver,Matrix,Vector>,
455  throw_no_matrix_support_exception<ConcreteSolver,Matrix,Vector> >::type::apply(A, X, B);
456  }
457  };
458 
460  // Query Functions //
462 
470  bool query(const char* solverName);
471 
472 
480  bool query(const std::string solverName);
481 
482 
484  // Definitions //
486 
487  template <class Matrix,
488  class Vector >
489  Solver<Matrix,Vector>*
490  create(Matrix* A, Vector* X, Vector* B)
491  {
492  std::string solver = "Klu2";
493  // Pass non-owning RCP objects to other factory method
494  return( create(solver, rcp(A,false), rcp(X,false), rcp(B,false)).getRawPtr() );
495  }
496 
497 
498  template <class Matrix,
499  class Vector >
500  Teuchos::RCP<Solver<Matrix,Vector> >
501  create(Teuchos::RCP<const Matrix> A,
502  Teuchos::RCP<Vector> X,
503  Teuchos::RCP<const Vector> B)
504  {
505  std::string solver = "Klu2";
506  return( create(solver, A, X, B) );
507  }
508 
509 
510  template <class Matrix,
511  class Vector >
512  Solver<Matrix,Vector>*
513  create(const char* solverName, const Matrix* A, Vector* X, const Vector* B)
514  {
515  std::string solver = solverName;
516  // Pass non-owning Teuchos::RCP objects to other factory method
517  return( create(solver, rcp(A,false), rcp(X,false), rcp(B,false)).getRawPtr() );
518  }
519 
520 
521  template <class Matrix,
522  class Vector >
523  Teuchos::RCP<Solver<Matrix,Vector> >
524  create(const char* solverName,
525  const Teuchos::RCP<const Matrix> A,
526  const Teuchos::RCP<Vector> X,
527  const Teuchos::RCP<const Vector> B)
528  {
529  std::string solver = solverName;
530  return( create(solver, A, X, B) );
531  }
532 
533 
534  template <class Matrix,
535  class Vector >
536  Solver<Matrix,Vector>*
537  create(const std::string solverName, const Matrix* A){
538  return( create(solverName, rcp(A,false),
539  Teuchos::RCP<Vector>(),
540  Teuchos::RCP<const Vector>()).getRawPtr() );
541  }
542 
543 
544  template <class Matrix,
545  class Vector >
546  Teuchos::RCP<Solver<Matrix,Vector> >
547  create(const std::string solverName, const Teuchos::RCP<const Matrix> A){
548  return( create(solverName, A, Teuchos::RCP<Vector>(), Teuchos::RCP<const Vector>()) );
549  }
550 
551 
552  template <class Matrix,
553  class Vector >
554  Teuchos::RCP<Solver<Matrix,Vector> >
555  create(const std::string solverName, const Matrix* A, Vector* X, const Vector* B)
556  {
557  // Pass non-owning Teuchos::RCP objects to other factory method
558  return( create(solverName, rcp(A,false), rcp(X,false), rcp(B,false)) );
559  }
560 
561 
562  template <class Matrix,
563  class Vector >
564  Teuchos::RCP<Solver<Matrix,Vector> >
565  create(const std::string solver_name,
566  const Teuchos::RCP<const Matrix> A,
567  const Teuchos::RCP<Vector> X,
568  const Teuchos::RCP<const Vector> B)
569  {
570  std::string solverName = tolower(solver_name); // for easy string checking
571 
572  // Check for our native solver first. Treat KLU and KLU2 as equals.
573  //
574  // We use compiler guards in case a user does want to disable KLU2
575 #ifdef HAVE_AMESOS2_SHYLUBASKER
576  if((solverName == "ShyLUBasker") || (solverName == "shylubasker") || (solverName == "amesos2_shylubasker"))
577  {
578  return handle_solver_matrix_and_type_support<ShyLUBasker, Matrix,Vector>::apply(A,X,B);
579  }
580 #endif
581 
582 #ifdef HAVE_AMESOS2_BASKER
583  if((solverName == "Basker") || (solverName == "basker") || (solverName == "amesos2_basker"))
584  {
585  return handle_solver_matrix_and_type_support<Basker, Matrix,Vector>::apply(A,X,B);
586  }
587 #endif
588 
589 
590 #ifdef HAVE_AMESOS2_KLU2
591  if((solverName == "amesos2_klu2") || (solverName == "klu2") ||
592  (solverName == "amesos2_klu") || (solverName == "klu")){
593  return handle_solver_matrix_and_type_support<KLU2,Matrix,Vector>::apply(A, X, B);
594  }
595 #endif
596 
597 #ifdef HAVE_AMESOS2_SUPERLUDIST
598  if((solverName == "amesos2_superludist") ||
599  (solverName == "superludist") ||
600  (solverName == "amesos2_superlu_dist") ||
601  (solverName == "superlu_dist")){
602  return handle_solver_matrix_and_type_support<Superludist,Matrix,Vector>::apply(A, X, B);
603  }
604 #endif
605 
606 #ifdef HAVE_AMESOS2_SUPERLUMT
607  if((solverName == "amesos2_superlumt") ||
608  (solverName == "superlumt") ||
609  (solverName == "amesos2_superlu_mt") ||
610  (solverName == "superlu_mt")){
611  return handle_solver_matrix_and_type_support<Superlumt,Matrix,Vector>::apply(A, X, B);
612  }
613 #endif
614 
615 #ifdef HAVE_AMESOS2_UMFPACK
616  if((solverName == "amesos2_umfpack") ||
617  (solverName == "umfpack")){
618  return handle_solver_matrix_and_type_support<Umfpack,Matrix,Vector>::apply(A, X, B);
619  }
620 #endif
621 
622 #ifdef HAVE_AMESOS2_TACHO
623  if((solverName == "amesos2_tacho") ||
624  (solverName == "tacho")){
625  return handle_solver_matrix_and_type_support<TachoSolver,Matrix,Vector>::apply(A, X, B);
626  }
627 
628 #endif
629 
630 #ifdef HAVE_AMESOS2_SUPERLU
631  if((solverName == "amesos2_superlu") ||
632  (solverName == "superlu")){
633  return handle_solver_matrix_and_type_support<Superlu,Matrix,Vector>::apply(A, X, B);
634  }
635 #endif
636 
637 #ifdef HAVE_AMESOS2_PARDISO_MKL
638  if((solverName == "amesos2_pardiso_mkl") ||
639  (solverName == "pardiso_mkl") ||
640  (solverName == "amesos2_pardisomkl") ||
641  (solverName == "pardisomkl")){
642  return handle_solver_matrix_and_type_support<PardisoMKL,Matrix,Vector>::apply(A, X, B);
643  }
644 #endif
645 
646 #ifdef HAVE_AMESOS2_LAPACK
647  if((solverName == "amesos2_lapack") ||
648  (solverName == "lapack")){
649  return handle_solver_matrix_and_type_support<Lapack,Matrix,Vector>::apply(A, X, B);
650  }
651 #endif
652 
653 
654 #ifdef HAVE_AMESOS2_MUMPS
655  if((solverName == "MUMPS") || (solverName == "mumps") ||
656  (solverName == "amesos2_MUMPS") || (solverName == "amesos2_mumps"))
657  {
658  return handle_solver_matrix_and_type_support<MUMPS,Matrix,Vector>::apply(A,X,B);
659  }
660 #endif
661 
662 #if defined (HAVE_AMESOS2_CHOLMOD) && defined (HAVE_AMESOS2_EXPERIMENTAL)
663  if(solverName == "amesos2_cholmod" || solverName == "cholmod")
664  return handle_solver_matrix_and_type_support<Cholmod,Matrix,Vector>::apply(A, X, B);
665 #endif
666 
667 #if defined (HAVE_AMESOS2_CUSOLVER) && defined (HAVE_AMESOS2_CUSPARSE)
668  if(solverName == "amesos2_cusolver" || solverName == "cusolver")
669  return handle_solver_matrix_and_type_support<cuSOLVER,Matrix,Vector>::apply(A, X, B);
670 #endif
671 
672  /* If none of the above conditionals are satisfied, then the solver
673  * requested is not yet supported. We throw a runtime exception stating
674  * this, and return null.
675  */
676  std::string err_msg = solver_name + " is not enabled or is not supported";
677  TEUCHOS_TEST_FOR_EXCEPTION(true, std::invalid_argument, err_msg);
678  //return( Teuchos::null ); // unreachable
679  }
680 
681 } // end namespace Amesos2
682 
683 #endif // AMESOS2_FACTORY_HPP
A templated adapter/wrapper class for Trilinos Multivector type classes. Provides the functions neces...
Simple compile-time assertion class.
Provides access to interesting solver traits.