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 #ifdef HAVE_AMESOS2_MUMPS
140 #include "Amesos2_MUMPS.hpp"
141 #endif
142 
143 
144 namespace Amesos2 {
145 
146  template <class,class> class Solver;
147 
148  /*
149  * Utility function to transform a string into all lowercase
150  */
151  std::string tolower(const std::string& s);
152 
153 
168  template < class Matrix,
169  class Vector >
170  Solver<Matrix,Vector>*
171  create(const Matrix* A, Vector* X, const Vector* B);
172 
173 
188  template < class Matrix,
189  class Vector >
190  Teuchos::RCP<Solver<Matrix,Vector> >
191  create(Teuchos::RCP<const Matrix> A,
192  Teuchos::RCP<Vector> X,
193  Teuchos::RCP<const Vector> B);
194 
195 
213  template < class Matrix,
214  class Vector >
215  Solver<Matrix,Vector>*
216  create(const char* solverName, const Matrix* A, Vector* X, const Vector* B);
217 
218 
235  template < class Matrix,
236  class Vector >
237  Teuchos::RCP<Solver<Matrix,Vector> >
238  create(const char* solverName,
239  const Teuchos::RCP<const Matrix> A,
240  const Teuchos::RCP<Vector> X,
241  const Teuchos::RCP<const Vector> B);
242 
243 
260  template < class Matrix,
261  class Vector >
262  Solver<Matrix,Vector>*
263  create(const std::string solverName, const Matrix* A, Vector* X, const Vector* B);
264 
265 
282  template < class Matrix,
283  class Vector >
284  Teuchos::RCP<Solver<Matrix,Vector> >
285  create(const std::string solverName,
286  const Teuchos::RCP<const Matrix> A,
287  const Teuchos::RCP<Vector> X,
288  const Teuchos::RCP<const Vector> B);
289 
290 
309  template < class Matrix,
310  class Vector >
311  Solver<Matrix,Vector>*
312  create(const std::string solverName, const Matrix* A);
313 
314 
333  template < class Matrix,
334  class Vector >
335  Teuchos::RCP<Solver<Matrix,Vector> >
336  create(const std::string solverName,
337  const Teuchos::RCP<const Matrix> A);
338 
339 
341  // Meta-functions to help with creation of solvers //
343 
344  template < template <class,class> class ConcreteSolver,
345  class Matrix,
346  class Vector >
347  struct create_solver_with_supported_type {
348  static Teuchos::RCP<Solver<Matrix,Vector> > apply(Teuchos::RCP<const Matrix> A,
349  Teuchos::RCP<Vector> X,
350  Teuchos::RCP<const Vector> B )
351  {
352  ctassert<
353  Meta::is_same<
354  typename MatrixTraits<Matrix>::scalar_t,
355  typename MultiVecAdapter<Vector>::scalar_t
356  >::value
357  > same_scalar_assertion;
358  (void)same_scalar_assertion; // This stops the compiler from warning about unused declared variables
359 
360  // If our assertion did not fail, then create and return a new solver
361  return rcp( new ConcreteSolver<Matrix,Vector>(A, X, B) );
362  }
363  };
364 
373 template < template <class,class> class ConcreteSolver,
374  class Matrix,
375  class Vector >
376 struct throw_no_scalar_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  // typedef ConcreteSolver<Matrix,Vector> concretesolver_matrix_vector;
382  typedef typename MatrixTraits<Matrix>::scalar_t scalar_t;
383  TEUCHOS_TEST_FOR_EXCEPTION( true,
384  std::invalid_argument,
385  "The requested Amesos2 "
386  // << concretesolver_matrix_vector::name <<
387  " solver interface does not support the " <<
388  Teuchos::ScalarTraits<scalar_t>::name() <<
389  " scalar type." );
390  }
391 };
392 
402  template < template <class,class> class ConcreteSolver,
403  class Matrix,
404  class Vector >
405  struct handle_solver_type_support {
406  static Teuchos::RCP<Solver<Matrix,Vector> > apply(Teuchos::RCP<const Matrix> A,
407  Teuchos::RCP<Vector> X,
408  Teuchos::RCP<const Vector> B )
409  {
410  return Meta::if_then_else<
411  solver_supports_scalar<ConcreteSolver, typename MatrixTraits<Matrix>::scalar_t>::value,
412  create_solver_with_supported_type<ConcreteSolver,Matrix,Vector>,
413  throw_no_scalar_support_exception<ConcreteSolver,Matrix,Vector> >::type::apply(A, X, B);
414  }
415  };
416 
417 
419  // Query Functions //
421 
429  bool query(const char* solverName);
430 
431 
439  bool query(const std::string solverName);
440 
441 
443  // Definitions //
445 
446  template <class Matrix,
447  class Vector >
448  Solver<Matrix,Vector>*
449  create(Matrix* A, Vector* X, Vector* B)
450  {
451  std::string solver = "Klu2";
452  // Pass non-owning RCP objects to other factory method
453  return( create(solver, rcp(A,false), rcp(X,false), rcp(B,false)).getRawPtr() );
454  }
455 
456 
457  template <class Matrix,
458  class Vector >
459  Teuchos::RCP<Solver<Matrix,Vector> >
460  create(Teuchos::RCP<const Matrix> A,
461  Teuchos::RCP<Vector> X,
462  Teuchos::RCP<const Vector> B)
463  {
464  std::string solver = "Klu2";
465  return( create(solver, A, X, B) );
466  }
467 
468 
469  template <class Matrix,
470  class Vector >
471  Solver<Matrix,Vector>*
472  create(const char* solverName, const Matrix* A, Vector* X, const Vector* B)
473  {
474  std::string solver = solverName;
475  // Pass non-owning Teuchos::RCP objects to other factory method
476  return( create(solver, rcp(A,false), rcp(X,false), rcp(B,false)).getRawPtr() );
477  }
478 
479 
480  template <class Matrix,
481  class Vector >
482  Teuchos::RCP<Solver<Matrix,Vector> >
483  create(const char* solverName,
484  const Teuchos::RCP<const Matrix> A,
485  const Teuchos::RCP<Vector> X,
486  const Teuchos::RCP<const Vector> B)
487  {
488  std::string solver = solverName;
489  return( create(solver, A, X, B) );
490  }
491 
492 
493  template <class Matrix,
494  class Vector >
495  Solver<Matrix,Vector>*
496  create(const std::string solverName, const Matrix* A){
497  return( create(solverName, rcp(A,false),
498  Teuchos::RCP<Vector>(),
499  Teuchos::RCP<const Vector>()).getRawPtr() );
500  }
501 
502 
503  template <class Matrix,
504  class Vector >
505  Teuchos::RCP<Solver<Matrix,Vector> >
506  create(const std::string solverName, const Teuchos::RCP<const Matrix> A){
507  return( create(solverName, A, Teuchos::RCP<Vector>(), Teuchos::RCP<const Vector>()) );
508  }
509 
510 
511  template <class Matrix,
512  class Vector >
513  Teuchos::RCP<Solver<Matrix,Vector> >
514  create(const std::string solverName, const Matrix* A, Vector* X, const Vector* B)
515  {
516  // Pass non-owning Teuchos::RCP objects to other factory method
517  return( create(solverName, rcp(A,false), rcp(X,false), rcp(B,false)) );
518  }
519 
520 
521  template <class Matrix,
522  class Vector >
523  Teuchos::RCP<Solver<Matrix,Vector> >
524  create(const std::string solver_name,
525  const Teuchos::RCP<const Matrix> A,
526  const Teuchos::RCP<Vector> X,
527  const Teuchos::RCP<const Vector> B)
528  {
529  std::string solverName = tolower(solver_name); // for easy string checking
530 
531  // Check for our native solver first. Treat KLU and KLU2 as equals.
532  //
533  // We use compiler guards in case a user does want to disable KLU2
534 #ifdef HAVE_AMESOS2_SHYLUBASKER
535  if((solverName == "ShyLUBasker") || (solverName == "shylubasker") || (solverName == "amesos2_shylubasker"))
536  {
537  return handle_solver_type_support<ShyLUBasker, Matrix,Vector>::apply(A,X,B);
538  }
539 #endif
540 
541 #ifdef HAVE_AMESOS2_BASKER
542  if((solverName == "Basker") || (solverName == "basker") || (solverName == "amesos2_basker"))
543  {
544  return handle_solver_type_support<Basker, Matrix,Vector>::apply(A,X,B);
545  }
546 #endif
547 
548 
549 #ifdef HAVE_AMESOS2_KLU2
550  if((solverName == "amesos2_klu2") || (solverName == "klu2") ||
551  (solverName == "amesos2_klu") || (solverName == "klu")){
552  return handle_solver_type_support<KLU2,Matrix,Vector>::apply(A, X, B);
553  }
554 #endif
555 
556 #ifdef HAVE_AMESOS2_SUPERLUDIST
557  if((solverName == "amesos2_superludist") ||
558  (solverName == "superludist") ||
559  (solverName == "amesos2_superlu_dist") ||
560  (solverName == "superlu_dist")){
561  return handle_solver_type_support<Superludist,Matrix,Vector>::apply(A, X, B);
562  }
563 #endif
564 
565 #ifdef HAVE_AMESOS2_SUPERLUMT
566  if((solverName == "amesos2_superlumt") ||
567  (solverName == "superlumt") ||
568  (solverName == "amesos2_superlu_mt") ||
569  (solverName == "superlu_mt")){
570  return handle_solver_type_support<Superlumt,Matrix,Vector>::apply(A, X, B);
571  }
572 #endif
573 
574 #ifdef HAVE_AMESOS2_UMFPACK
575  if((solverName == "amesos2_umfpack") ||
576  (solverName == "umfpack")){
577  return handle_solver_type_support<Umfpack,Matrix,Vector>::apply(A, X, B);
578  }
579 #endif
580 
581 #ifdef HAVE_AMESOS2_TACHO
582  if((solverName == "amesos2_tacho") ||
583  (solverName == "tacho")){
584  return handle_solver_type_support<TachoSolver,Matrix,Vector>::apply(A, X, B);
585  }
586 #endif
587 
588 #ifdef HAVE_AMESOS2_SUPERLU
589  if((solverName == "amesos2_superlu") ||
590  (solverName == "superlu")){
591  return handle_solver_type_support<Superlu,Matrix,Vector>::apply(A, X, B);
592  }
593 #endif
594 
595 #ifdef HAVE_AMESOS2_PARDISO_MKL
596  if((solverName == "amesos2_pardiso_mkl") ||
597  (solverName == "pardiso_mkl") ||
598  (solverName == "amesos2_pardisomkl") ||
599  (solverName == "pardisomkl")){
600  return handle_solver_type_support<PardisoMKL,Matrix,Vector>::apply(A, X, B);
601  }
602 #endif
603 
604 #ifdef HAVE_AMESOS2_LAPACK
605  if((solverName == "amesos2_lapack") ||
606  (solverName == "lapack")){
607  return handle_solver_type_support<Lapack,Matrix,Vector>::apply(A, X, B);
608  }
609 #endif
610 
611 
612 #ifdef HAVE_AMESOS2_MUMPS
613  if((solverName == "MUMPS") || (solverName == "mumps") ||
614  (solverName == "amesos2_MUMPS") || (solverName == "amesos2_mumps"))
615  {
616  return handle_solver_type_support<MUMPS,Matrix,Vector>::apply(A,X,B);
617  }
618 #endif
619 
620 #if defined (HAVE_AMESOS2_CHOLMOD) && defined (HAVE_AMESOS2_EXPERIMENTAL)
621  if(solverName == "amesos2_cholmod")
622  return handle_solver_type_support<Cholmod,Matrix,Vector>::apply(A, X, B);
623 #endif
624 
625  /* If none of the above conditionals are satisfied, then the solver
626  * requested is not yet supported. We throw a runtime exception stating
627  * this, and return null.
628  */
629  std::string err_msg = solver_name + " is not enabled or is not supported";
630  TEUCHOS_TEST_FOR_EXCEPTION(true, std::invalid_argument, err_msg);
631  //return( Teuchos::null ); // unreachable
632  }
633 
634 } // end namespace Amesos2
635 
636 #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.