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_UMFPACK // Umfpack
108 #include "Amesos2_Umfpack.hpp"
109 #endif
110 #ifdef HAVE_AMESOS2_SUPERLU // Sequential SuperLU
111 #include "Amesos2_Superlu.hpp"
112 #endif
113 #ifdef HAVE_AMESOS2_PARDISO_MKL // MKL version of Pardiso
114 #include "Amesos2_PardisoMKL.hpp"
115 #endif
116 #ifdef HAVE_AMESOS2_LAPACK
117 #include "Amesos2_Lapack.hpp"
118 #endif
119 #if defined (HAVE_AMESOS2_CHOLMOD) && defined (HAVE_AMESOS2_EXPERIMENTAL)
120 #include "Amesos2_Cholmod.hpp"
121 #endif
122 #ifdef HAVE_AMESOS2_MUMPS
123 #include "Amesos2_MUMPS.hpp"
124 #endif
125 
126 
127 namespace Amesos2 {
128 
129  template <class,class> class Solver;
130 
131  /*
132  * Utility function to transform a string into all lowercase
133  */
134  std::string tolower(const std::string& s);
135 
136 
151  template < class Matrix,
152  class Vector >
153  Solver<Matrix,Vector>*
154  create(const Matrix* A, Vector* X, const Vector* B);
155 
156 
171  template < class Matrix,
172  class Vector >
173  Teuchos::RCP<Solver<Matrix,Vector> >
174  create(Teuchos::RCP<const Matrix> A,
175  Teuchos::RCP<Vector> X,
176  Teuchos::RCP<const Vector> B);
177 
178 
196  template < class Matrix,
197  class Vector >
198  Solver<Matrix,Vector>*
199  create(const char* solverName, const Matrix* A, Vector* X, const Vector* B);
200 
201 
218  template < class Matrix,
219  class Vector >
220  Teuchos::RCP<Solver<Matrix,Vector> >
221  create(const char* solverName,
222  const Teuchos::RCP<const Matrix> A,
223  const Teuchos::RCP<Vector> X,
224  const Teuchos::RCP<const Vector> B);
225 
226 
243  template < class Matrix,
244  class Vector >
245  Solver<Matrix,Vector>*
246  create(const std::string solverName, const Matrix* A, Vector* X, const Vector* B);
247 
248 
265  template < class Matrix,
266  class Vector >
267  Teuchos::RCP<Solver<Matrix,Vector> >
268  create(const std::string solverName,
269  const Teuchos::RCP<const Matrix> A,
270  const Teuchos::RCP<Vector> X,
271  const Teuchos::RCP<const Vector> B);
272 
273 
292  template < class Matrix,
293  class Vector >
294  Solver<Matrix,Vector>*
295  create(const std::string solverName, const Matrix* A);
296 
297 
316  template < class Matrix,
317  class Vector >
318  Teuchos::RCP<Solver<Matrix,Vector> >
319  create(const std::string solverName,
320  const Teuchos::RCP<const Matrix> A);
321 
322 
324  // Meta-functions to help with creation of solvers //
326 
327  template < template <class,class> class ConcreteSolver,
328  class Matrix,
329  class Vector >
330  struct create_solver_with_supported_type {
331  static Teuchos::RCP<Solver<Matrix,Vector> > apply(Teuchos::RCP<const Matrix> A,
332  Teuchos::RCP<Vector> X,
333  Teuchos::RCP<const Vector> B )
334  {
335  ctassert<
336  Meta::is_same<
337  typename MatrixTraits<Matrix>::scalar_t,
338  typename MultiVecAdapter<Vector>::scalar_t
339  >::value
340  > same_scalar_assertion;
341  (void)same_scalar_assertion; // This stops the compiler from warning about unused declared variables
342 
343  // If our assertion did not fail, then create and return a new solver
344  return rcp( new ConcreteSolver<Matrix,Vector>(A, X, B) );
345  }
346  };
347 
356 template < template <class,class> class ConcreteSolver,
357  class Matrix,
358  class Vector >
359 struct throw_no_scalar_support_exception {
360  static Teuchos::RCP<Solver<Matrix,Vector> > apply(Teuchos::RCP<const Matrix> A,
361  Teuchos::RCP<Vector> X,
362  Teuchos::RCP<const Vector> B )
363  {
364  // typedef ConcreteSolver<Matrix,Vector> concretesolver_matrix_vector;
365  typedef typename MatrixTraits<Matrix>::scalar_t scalar_t;
366  TEUCHOS_TEST_FOR_EXCEPTION( true,
367  std::invalid_argument,
368  "The requested Amesos2 "
369  // << concretesolver_matrix_vector::name <<
370  " solver interface does not support the " <<
371  Teuchos::ScalarTraits<scalar_t>::name() <<
372  " scalar type." );
373  }
374 };
375 
385  template < template <class,class> class ConcreteSolver,
386  class Matrix,
387  class Vector >
388  struct handle_solver_type_support {
389  static Teuchos::RCP<Solver<Matrix,Vector> > apply(Teuchos::RCP<const Matrix> A,
390  Teuchos::RCP<Vector> X,
391  Teuchos::RCP<const Vector> B )
392  {
393  return Meta::if_then_else<
394  solver_supports_scalar<ConcreteSolver, typename MatrixTraits<Matrix>::scalar_t>::value,
395  create_solver_with_supported_type<ConcreteSolver,Matrix,Vector>,
396  throw_no_scalar_support_exception<ConcreteSolver,Matrix,Vector> >::type::apply(A, X, B);
397  }
398  };
399 
400 
402  // Query Functions //
404 
412  bool query(const char* solverName);
413 
414 
422  bool query(const std::string solverName);
423 
424 
426  // Definitions //
428 
429  template <class Matrix,
430  class Vector >
431  Solver<Matrix,Vector>*
432  create(Matrix* A, Vector* X, Vector* B)
433  {
434  std::string solver = "Klu2";
435  // Pass non-owning RCP objects to other factory method
436  return( create(solver, rcp(A,false), rcp(X,false), rcp(B,false)).getRawPtr() );
437  }
438 
439 
440  template <class Matrix,
441  class Vector >
442  Teuchos::RCP<Solver<Matrix,Vector> >
443  create(Teuchos::RCP<const Matrix> A,
444  Teuchos::RCP<Vector> X,
445  Teuchos::RCP<const Vector> B)
446  {
447  std::string solver = "Klu2";
448  return( create(solver, A, X, B) );
449  }
450 
451 
452  template <class Matrix,
453  class Vector >
454  Solver<Matrix,Vector>*
455  create(const char* solverName, const Matrix* A, Vector* X, const Vector* B)
456  {
457  std::string solver = solverName;
458  // Pass non-owning Teuchos::RCP objects to other factory method
459  return( create(solver, rcp(A,false), rcp(X,false), rcp(B,false)).getRawPtr() );
460  }
461 
462 
463  template <class Matrix,
464  class Vector >
465  Teuchos::RCP<Solver<Matrix,Vector> >
466  create(const char* solverName,
467  const Teuchos::RCP<const Matrix> A,
468  const Teuchos::RCP<Vector> X,
469  const Teuchos::RCP<const Vector> B)
470  {
471  std::string solver = solverName;
472  return( create(solver, A, X, B) );
473  }
474 
475 
476  template <class Matrix,
477  class Vector >
478  Solver<Matrix,Vector>*
479  create(const std::string solverName, const Matrix* A){
480  return( create(solverName, rcp(A,false),
481  Teuchos::RCP<Vector>(),
482  Teuchos::RCP<const Vector>()).getRawPtr() );
483  }
484 
485 
486  template <class Matrix,
487  class Vector >
488  Teuchos::RCP<Solver<Matrix,Vector> >
489  create(const std::string solverName, const Teuchos::RCP<const Matrix> A){
490  return( create(solverName, A, Teuchos::RCP<Vector>(), Teuchos::RCP<const Vector>()) );
491  }
492 
493 
494  template <class Matrix,
495  class Vector >
496  Teuchos::RCP<Solver<Matrix,Vector> >
497  create(const std::string solverName, const Matrix* A, Vector* X, const Vector* B)
498  {
499  // Pass non-owning Teuchos::RCP objects to other factory method
500  return( create(solverName, rcp(A,false), rcp(X,false), rcp(B,false)) );
501  }
502 
503 
504  template <class Matrix,
505  class Vector >
506  Teuchos::RCP<Solver<Matrix,Vector> >
507  create(const std::string solver_name,
508  const Teuchos::RCP<const Matrix> A,
509  const Teuchos::RCP<Vector> X,
510  const Teuchos::RCP<const Vector> B)
511  {
512  std::string solverName = tolower(solver_name); // for easy string checking
513 
514  // Check for our native solver first. Treat KLU and KLU2 as equals.
515  //
516  // We use compiler guards in case a user does want to disable KLU2
517 #ifdef HAVE_AMESOS2_BASKER
518  if((solverName == "Basker") || (solverName == "basker"))
519  {
520  return handle_solver_type_support<Basker, Matrix,Vector>::apply(A,X,B);
521  }
522 #endif
523 
524 
525 
526 #ifdef HAVE_AMESOS2_KLU2
527  if((solverName == "amesos2_klu2") || (solverName == "klu2") ||
528  (solverName == "amesos2_klu") || (solverName == "klu")){
529  return handle_solver_type_support<KLU2,Matrix,Vector>::apply(A, X, B);
530  }
531 #endif
532 
533 #ifdef HAVE_AMESOS2_SUPERLUDIST
534  if((solverName == "amesos2_superludist") ||
535  (solverName == "superludist") ||
536  (solverName == "amesos2_superlu_dist") ||
537  (solverName == "superlu_dist")){
538  return handle_solver_type_support<Superludist,Matrix,Vector>::apply(A, X, B);
539  }
540 #endif
541 
542 #ifdef HAVE_AMESOS2_SUPERLUMT
543  if((solverName == "amesos2_superlumt") ||
544  (solverName == "superlumt") ||
545  (solverName == "amesos2_superlu_mt") ||
546  (solverName == "superlu_mt")){
547  return handle_solver_type_support<Superlumt,Matrix,Vector>::apply(A, X, B);
548  }
549 #endif
550 
551 #ifdef HAVE_AMESOS2_UMFPACK
552  if((solverName == "amesos2_umfpack") ||
553  (solverName == "umfpack")){
554  return handle_solver_type_support<Umfpack,Matrix,Vector>::apply(A, X, B);
555  }
556 #endif
557 
558 #ifdef HAVE_AMESOS2_SUPERLU
559  if((solverName == "amesos2_superlu") ||
560  (solverName == "superlu")){
561  return handle_solver_type_support<Superlu,Matrix,Vector>::apply(A, X, B);
562  }
563 #endif
564 
565 #ifdef HAVE_AMESOS2_PARDISO_MKL
566  if((solverName == "amesos2_pardiso_mkl") ||
567  (solverName == "pardiso_mkl") ||
568  (solverName == "amesos2_pardisomkl") ||
569  (solverName == "pardisomkl")){
570  return handle_solver_type_support<PardisoMKL,Matrix,Vector>::apply(A, X, B);
571  }
572 #endif
573 
574 #ifdef HAVE_AMESOS2_LAPACK
575  if((solverName == "amesos2_lapack") ||
576  (solverName == "lapack")){
577  return handle_solver_type_support<Lapack,Matrix,Vector>::apply(A, X, B);
578  }
579 #endif
580 
581 
582 #ifdef HAVE_AMESOS2_MUMPS
583  if((solverName == "MUMPS") || (solverName == "mumps") ||
584  (solverName == "amesos2_MUMPS") || (solverName == "amesos2_mumps"))
585  {
586  return handle_solver_type_support<MUMPS,Matrix,Vector>::apply(A,X,B);
587  }
588 #endif
589 
590 #if defined (HAVE_AMESOS2_CHOLMOD) && defined (HAVE_AMESOS2_EXPERIMENTAL)
591  if(solverName == "amesos2_cholmod")
592  return handle_solver_type_support<Cholmod,Matrix,Vector>::apply(A, X, B);
593 #endif
594 
595  /* If none of the above conditionals are satisfied, then the solver
596  * requested is not yet supported. We throw a runtime exception stating
597  * this, and return null.
598  */
599  std::string err_msg = solver_name + " is not enabled or is not supported";
600  TEUCHOS_TEST_FOR_EXCEPTION(true, std::invalid_argument, err_msg);
601  return( Teuchos::null );
602  }
603 
604 } // end namespace Amesos2
605 
606 #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.