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 #if defined(HAVE_AMESOS2_KLU2)
99 #include "Amesos2_KLU2.hpp"
100 #endif
101 #ifdef HAVE_AMESOS2_SUPERLUDIST // Distributed-memory SuperLU
102 #include "Amesos2_Superludist.hpp"
103 #endif
104 #ifdef HAVE_AMESOS2_SUPERLUMT // Multi-threaded SuperLU
105 #include "Amesos2_Superlumt.hpp"
106 #endif
107 #ifdef HAVE_AMESOS2_SUPERLU // Sequential SuperLU
108 #include "Amesos2_Superlu.hpp"
109 #endif
110 #ifdef HAVE_AMESOS2_PARDISO_MKL // MKL version of Pardiso
111 #include "Amesos2_PardisoMKL.hpp"
112 #endif
113 #ifdef HAVE_AMESOS2_LAPACK
114 #include "Amesos2_Lapack.hpp"
115 #endif
116 #if defined (HAVE_AMESOS2_CHOLMOD) && defined (HAVE_AMESOS2_EXPERIMENTAL)
117 #include "Amesos2_Cholmod.hpp"
118 #endif
119 #ifdef HAVE_AMESOS2_MUMPS
120 #include "Amesos2_MUMPS.hpp"
121 #endif
122 
123 
124 namespace 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  Meta::is_same<
334  typename MatrixTraits<Matrix>::scalar_t,
335  typename MultiVecAdapter<Vector>::scalar_t
336  >::value
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 
353 template < template <class,class> class ConcreteSolver,
354  class Matrix,
355  class Vector >
356 struct 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 
382  template < template <class,class> class ConcreteSolver,
383  class Matrix,
384  class Vector >
385  struct handle_solver_type_support {
386  static Teuchos::RCP<Solver<Matrix,Vector> > apply(Teuchos::RCP<const Matrix> A,
387  Teuchos::RCP<Vector> X,
388  Teuchos::RCP<const Vector> B )
389  {
390  return Meta::if_then_else<
391  solver_supports_scalar<ConcreteSolver, typename MatrixTraits<Matrix>::scalar_t>::value,
392  create_solver_with_supported_type<ConcreteSolver,Matrix,Vector>,
393  throw_no_scalar_support_exception<ConcreteSolver,Matrix,Vector> >::type::apply(A, X, B);
394  }
395  };
396 
397 
399  // Query Functions //
401 
409  bool query(const char* solverName);
410 
411 
419  bool query(const std::string solverName);
420 
421 
423  // Definitions //
425 
426  template <class Matrix,
427  class Vector >
428  Solver<Matrix,Vector>*
429  create(Matrix* A, Vector* X, Vector* B)
430  {
431  std::string solver = "Klu2";
432  // Pass non-owning RCP objects to other factory method
433  return( create(solver, rcp(A,false), rcp(X,false), rcp(B,false)).getRawPtr() );
434  }
435 
436 
437  template <class Matrix,
438  class Vector >
439  Teuchos::RCP<Solver<Matrix,Vector> >
440  create(Teuchos::RCP<const Matrix> A,
441  Teuchos::RCP<Vector> X,
442  Teuchos::RCP<const Vector> B)
443  {
444  std::string solver = "Klu2";
445  return( create(solver, A, X, B) );
446  }
447 
448 
449  template <class Matrix,
450  class Vector >
451  Solver<Matrix,Vector>*
452  create(const char* solverName, const Matrix* A, Vector* X, const Vector* B)
453  {
454  std::string solver = solverName;
455  // Pass non-owning Teuchos::RCP objects to other factory method
456  return( create(solver, rcp(A,false), rcp(X,false), rcp(B,false)).getRawPtr() );
457  }
458 
459 
460  template <class Matrix,
461  class Vector >
462  Teuchos::RCP<Solver<Matrix,Vector> >
463  create(const char* solverName,
464  const Teuchos::RCP<const Matrix> A,
465  const Teuchos::RCP<Vector> X,
466  const Teuchos::RCP<const Vector> B)
467  {
468  std::string solver = solverName;
469  return( create(solver, A, X, B) );
470  }
471 
472 
473  template <class Matrix,
474  class Vector >
475  Solver<Matrix,Vector>*
476  create(const std::string solverName, const Matrix* A){
477  return( create(solverName, rcp(A,false),
478  Teuchos::RCP<Vector>(),
479  Teuchos::RCP<const Vector>()).getRawPtr() );
480  }
481 
482 
483  template <class Matrix,
484  class Vector >
485  Teuchos::RCP<Solver<Matrix,Vector> >
486  create(const std::string solverName, const Teuchos::RCP<const Matrix> A){
487  return( create(solverName, A, Teuchos::RCP<Vector>(), Teuchos::RCP<const Vector>()) );
488  }
489 
490 
491  template <class Matrix,
492  class Vector >
493  Teuchos::RCP<Solver<Matrix,Vector> >
494  create(const std::string solverName, const Matrix* A, Vector* X, const Vector* B)
495  {
496  // Pass non-owning Teuchos::RCP objects to other factory method
497  return( create(solverName, rcp(A,false), rcp(X,false), rcp(B,false)) );
498  }
499 
500 
501  template <class Matrix,
502  class Vector >
503  Teuchos::RCP<Solver<Matrix,Vector> >
504  create(const std::string solver_name,
505  const Teuchos::RCP<const Matrix> A,
506  const Teuchos::RCP<Vector> X,
507  const Teuchos::RCP<const Vector> B)
508  {
509  std::string solverName = tolower(solver_name); // for easy string checking
510 
511  // Check for our native solver first. Treat KLU and KLU2 as equals.
512  //
513  // We use compiler guards in case a user does want to disable KLU2
514 #ifdef HAVE_AMESOS2_BASKER
515  if((solverName == "Basker") || (solverName == "basker"))
516  {
517 
518  return handle_solver_type_support<Basker, Matrix,Vector>::apply(A,X,B);
519  }
520 #endif
521 
522 
523 
524 #ifdef HAVE_AMESOS2_KLU2
525 
526 if((solverName == "amesos2_klu2") || (solverName == "klu2") ||
527  (solverName == "amesos2_klu") || (solverName == "klu")){
528  return handle_solver_type_support<KLU2,Matrix,Vector>::apply(A, X, B);
529  }
530 #endif
531 
532 #ifdef HAVE_AMESOS2_SUPERLUDIST
533  if((solverName == "amesos2_superludist") ||
534  (solverName == "superludist") ||
535  (solverName == "amesos2_superlu_dist") ||
536  (solverName == "superlu_dist")){
537  return handle_solver_type_support<Superludist,Matrix,Vector>::apply(A, X, B);
538  }
539 #endif
540 
541 #ifdef HAVE_AMESOS2_SUPERLUMT
542  if((solverName == "amesos2_superlumt") ||
543  (solverName == "superlumt") ||
544  (solverName == "amesos2_superlu_mt") ||
545  (solverName == "superlu_mt")){
546  return handle_solver_type_support<Superlumt,Matrix,Vector>::apply(A, X, B);
547  }
548 #endif
549 
550 #ifdef HAVE_AMESOS2_SUPERLU
551  if((solverName == "amesos2_superlu") ||
552  (solverName == "superlu")){
553  return handle_solver_type_support<Superlu,Matrix,Vector>::apply(A, X, B);
554  }
555 #endif
556 
557 #ifdef HAVE_AMESOS2_PARDISO_MKL
558  if((solverName == "amesos2_pardiso_mkl") ||
559  (solverName == "pardiso_mkl") ||
560  (solverName == "amesos2_pardisomkl") ||
561  (solverName == "pardisomkl")){
562  return handle_solver_type_support<PardisoMKL,Matrix,Vector>::apply(A, X, B);
563  }
564 #endif
565 
566 #ifdef HAVE_AMESOS2_LAPACK
567  if((solverName == "amesos2_lapack") ||
568  (solverName == "lapack")){
569  return handle_solver_type_support<Lapack,Matrix,Vector>::apply(A, X, B);
570  }
571 #endif
572 
573 
574 #ifdef HAVE_AMESOS2_MUMPS
575  if((solverName == "MUMPS") || (solverName == "mumps") ||
576  (solverName == "amesos2_MUMPS") || (solverName == "amesos2_mumps"))
577  {
578  return handle_solver_type_support<MUMPS,Matrix,Vector>::apply(A,X,B);
579  }
580 #endif
581 
582 #if defined (HAVE_AMESOS2_CHOLMOD) && defined (HAVE_AMESOS2_EXPERIMENTAL)
583  if(solverName == "amesos2_cholmod")
584  return handle_solver_type_support<Cholmod,Matrix,Vector>::apply(A, X, B);
585 #endif
586 
587  /* If none of the above conditionals are satisfied, then the solver
588  * requested is not yet supported. We throw a runtime exception stating
589  * this, and return null.
590  */
591  std::string err_msg = solver_name + " is not enabled or is not supported";
592  TEUCHOS_TEST_FOR_EXCEPTION(true, std::invalid_argument, err_msg);
593  return( Teuchos::null );
594  }
595 
596 } // end namespace Amesos2
597 
598 #endif // AMESOS2_FACTORY_HPP
A templated adapter/wrapper class for Trilinos Multivector type classes. Provides the functions neces...
Definition: Amesos2_AbstractConcreteMatrixAdapter.hpp:48
Simple compile-time assertion class.
Provides access to interesting solver traits.