This file is indexed.

/usr/include/trilinos/Amesos2_Factory.hpp is in libtrilinos-amesos2-dev 12.12.1-5.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
// @HEADER
//
// ***********************************************************************
//
//           Amesos2: Templated Direct Sparse Solver Package
//                  Copyright 2011 Sandia Corporation
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the Corporation nor the names of the
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Questions? Contact Michael A. Heroux (maherou@sandia.gov)
//
// ***********************************************************************
//
// @HEADER

/**
 * \file   Amesos2_Factory.hpp
 * \author Eric Bavier <etbavie@sandia.gov>
 * \date   Tue Jun  7 16:25:16 2011
 *
 * \brief  Contains declarations for Amesos2::create and Amesos2::query.
 *
 * Amesos2 defines the nonmember factory method \c Amesos2::create for
 * creating instances of Amesos2 solvers.  If a users asks
 * Amesos2::create to create a solver with a matrix whose scalar type
 * is not supported by that solver, then a runtime
 * std::invalid_argument exception will be thrown.
 *
 * The \c Amesos2::query function can be used to ask Amesos2 at
 * runtime whether a particular solver is supported.
 *
 * \attention
 * Users should favor these factory methods for creating Amesos2 solver
 * instances over explicitly instantiating their own.
 *
 * \note A solver's third-party library must be enabled in the
 * Trilinos build, and Amesos2 must be also told to enable it.  Put
 * <tt>Amesos2_ENABLE_<i>SOLVERNAME</i>:BOOL=ON</tt> in your Trilinos
 * configuration script to do this, where <i>SOLVERNAME</i> is the
 * name of the solver you would like to enable.
 *
 * \section usage Example Usage
 *
 * \code
 * typedef Tpetra::CrsMatrix<double,int> MAT;
 * typedef Tpetra::MultiVector<double,int> VEC;
 * // ... Create A of type RCP<MAT>, and X and B of type RCP<VEC> ...
 * RCP<Amesos2::Solver<MAT,VEC> > solver = Amesos2::create<MAT,VEC>("SuperLU", A, X, B);
 * \endcode
 *
 * \ingroup amesos2_solver_framework
 */

#ifndef AMESOS2_FACTORY_HPP
#define AMESOS2_FACTORY_HPP

#include "Amesos2_config.h"

#include "Amesos2_Solver.hpp"
#include "Amesos2_SolverTraits.hpp"

#include "Teuchos_ScalarTraits.hpp"
#include "Amesos2_MultiVecAdapter.hpp"
#include "Amesos2_MatrixTraits.hpp"
#include "Amesos2_ctassert.hpp"

#ifdef HAVE_AMESOS2_BASKER
#include "Amesos2_Basker.hpp"
#endif
#if defined(HAVE_AMESOS2_KLU2)
#include "Amesos2_KLU2.hpp"
#endif
#ifdef HAVE_AMESOS2_SUPERLUDIST // Distributed-memory SuperLU
#include "Amesos2_Superludist.hpp"
#endif
#ifdef HAVE_AMESOS2_SUPERLUMT   // Multi-threaded SuperLU
#include "Amesos2_Superlumt.hpp"
#endif
#ifdef HAVE_AMESOS2_UMFPACK     // Umfpack
#include "Amesos2_Umfpack.hpp"
#endif
#ifdef HAVE_AMESOS2_SUPERLU     // Sequential SuperLU
#include "Amesos2_Superlu.hpp"
#endif
#ifdef HAVE_AMESOS2_PARDISO_MKL // MKL version of Pardiso
#include "Amesos2_PardisoMKL.hpp"
#endif
#ifdef HAVE_AMESOS2_LAPACK
#include "Amesos2_Lapack.hpp"
#endif
#if defined (HAVE_AMESOS2_CHOLMOD) && defined (HAVE_AMESOS2_EXPERIMENTAL)
#include "Amesos2_Cholmod.hpp"
#endif
#ifdef HAVE_AMESOS2_MUMPS
#include "Amesos2_MUMPS.hpp"
#endif


namespace Amesos2 {

  template <class,class> class Solver;

  /*
   * Utility function to transform a string into all lowercase
   */
  std::string tolower(const std::string& s);


  /**
   * \brief Creates an Amesos2 Solver interface with Matrix A, LHS vector X,
   * and RHS vector B.
   *
   * This is the default option which interfaces with the native KLU2 solver.
   *
   * \param [in] A pointer to a matrix of coefficients
   * \param [in] X pointer to LHS solution vector
   * \param [in] B pointer to RHS vector
   *
   * \return A \c C pointer to a KLU2 solver interface.
   *
   * \relatesalso Amesos2::Solver
   */
  template < class Matrix,
             class Vector >
  Solver<Matrix,Vector>*
  create(const Matrix* A, Vector* X, const Vector* B);


  /**
   * \brief Creates an Amesos2 Solver interface with Matrix A, LHS vector X,
   * and RHS vector B.
   *
   * This is the default option which interfaces with the native KLU2 solver.
   *
   * \param [in] A <tt>Teuchos::RCP</tt> to the coefficient matrix
   * \param [in] X <tt>Teuchos::RCP</tt> to LHS solution vector
   * \param [in] B <tt>Teuchos::RCP</tt> to RHS vector
   *
   * \return A <tt>Teuchos::RCP</tt> to a KLU2 solver interface.
   *
   * \relatesalso Amesos2::Solver
   */
  template < class Matrix,
             class Vector >
  Teuchos::RCP<Solver<Matrix,Vector> >
  create(Teuchos::RCP<const Matrix> A,
         Teuchos::RCP<Vector>       X,
         Teuchos::RCP<const Vector> B);


  /**
   * \brief Creates an Amesos2 Solver interface with Matrix A, LHS vector X,
   * and RHS vector B.
   *
   * \param [in] solverName A \c C character string with the name of the
   *                        underlying third-party solver desired.
   * \param [in] A pointer to a matrix of coefficients
   * \param [in] X pointer to LHS solution vector
   * \param [in] B pointer to RHS vector
   *
   * \return A \c C pointer to an Amesos2 solver interface.
   *
   * \throw std::invalid_argument The third-party solver named by \c
   * solverName is not supported.
   *
   * \relatesalso Amesos2::Solver
   */
  template < class Matrix,
             class Vector >
  Solver<Matrix,Vector>*
  create(const char* solverName, const Matrix* A, Vector* X, const Vector* B);


  /**
   * \brief Creates an Amesos2 Solver interface with Matrix A, LHS vector X,
   * and RHS vector B.
   *
   * \param [in] solverName The name of the desired third-party solver
   * \param [in] A <tt>Teuchos::RCP</tt> to the coefficient matrix
   * \param [in] X <tt>Teuchos::RCP</tt> to LHS solution vector
   * \param [in] B <tt>Teuchos::RCP</tt> to RHS vector
   *
   * \return A <tt>Teuchos::RCP</tt> to an Amesos2 solver interface.
   *
   * \throw std::invalid_argument The third-party solver named by \c
   * solverName is not supported.
   *
   * \relatesalso Amesos2::Solver
   */
  template < class Matrix,
             class Vector >
  Teuchos::RCP<Solver<Matrix,Vector> >
  create(const char* solverName,
         const Teuchos::RCP<const Matrix> A,
         const Teuchos::RCP<Vector>       X,
         const Teuchos::RCP<const Vector> B);


  /**
   * \brief Creates an Amesos2 Solver interface with Matrix A, LHS vector X,
   * and RHS vector B.
   *
   * \param [in] solverName The name of the desired third-party solver
   * \param [in] A \c C pointer to the coefficient matrix
   * \param [in] X \c C pointer to LHS solution vector
   * \param [in] B \c C pointer to RHS vector
   *
   * \return A \c C pointer to an Amesos2 solver interface.
   *
   * \throw std::invalid_argument The third-party solver named by \c
   * solverName is not supported.
   *
   * \relatesalso Amesos2::Solver
   */
  template < class Matrix,
             class Vector >
  Solver<Matrix,Vector>*
  create(const std::string solverName, const Matrix* A, Vector* X, const Vector* B);


  /**
   * \brief Creates an Amesos2 Solver interface with Matrix A, LHS vector X,
   * and RHS vector B.
   *
   * \param [in] solverName The name of the desired third-party solver
   * \param [in] A <tt>Teuchos::RCP</tt> to the coefficient matrix
   * \param [in] X <tt>Teuchos::RCP</tt> to LHS solution vector
   * \param [in] B <tt>Teuchos::RCP</tt> to RHS vector
   *
   * \return A <tt>Teuchos::RCP</tt> to an Amesos2 solver interface.
   *
   * \throw std::invalid_argument The third-party solver named by \c
   * solverName is not supported.
   *
   * \relatesalso Amesos2::Solver
   */
  template < class Matrix,
             class Vector >
  Teuchos::RCP<Solver<Matrix,Vector> >
  create(const std::string solverName,
         const Teuchos::RCP<const Matrix> A,
         const Teuchos::RCP<Vector>       X,
         const Teuchos::RCP<const Vector> B);


  /**
   * \brief Creates an Amesos2 Solver interface with Matrix A.
   *
   * Suitable for cases where numeric factorization must be performed
   * before the X and B vectors are known.  Before a solve, the \c
   * setX() and \c setB() functions should be used to set X and B, or
   * the overloaded solve(X,B) method should be used.
   *
   * \param [in] solverName The name of the desired third-party solver
   * \param [in] A \c C pointer to the coefficient matrix
   *
   * \return A \c C pointer to an Amesos2 solver interface.
   *
   * \throw std::invalid_argument The third-party solver named by \c
   * solverName is not supported.
   *
   * \relatesalso Amesos2::Solver
   */
  template < class Matrix,
             class Vector >
  Solver<Matrix,Vector>*
  create(const std::string solverName, const Matrix* A);


  /**
   * \brief Creates an Amesos2 Solver interface with Matrix A.
   *
   * Suitable for cases where numeric factorization must be performed
   * before the X and B vectors are known.  Before a solve, the \c
   * setX() and \c setB() functions should be used to set X and B, or
   * the overloaded solve(X,B) method should be used.
   *
   * \param [in] solverName The name of the desired third-party solver
   * \param [in] A <tt>Teuchos::RCP</tt> to the coefficient matrix
   *
   * \return A <tt>Teuchos::RCP</tt> to an Amesos2 solver interface.
   *
   * \throw std::invalid_argument The third-party solver named by \c
   * solverName is not supported.
   *
   * \relatesalso Amesos2::Solver
   */
  template < class Matrix,
             class Vector >
  Teuchos::RCP<Solver<Matrix,Vector> >
  create(const std::string solverName,
         const Teuchos::RCP<const Matrix> A);


  /////////////////////////////////////////////////////
  // Meta-functions to help with creation of solvers //
  /////////////////////////////////////////////////////

  template < template <class,class> class ConcreteSolver,
             class Matrix,
             class Vector >
  struct create_solver_with_supported_type {
    static Teuchos::RCP<Solver<Matrix,Vector> > apply(Teuchos::RCP<const Matrix> A,
                                                      Teuchos::RCP<Vector>       X,
                                                      Teuchos::RCP<const Vector> B )
    {
      ctassert<
        Meta::is_same<
          typename MatrixTraits<Matrix>::scalar_t,
          typename MultiVecAdapter<Vector>::scalar_t
        >::value
      > same_scalar_assertion;
      (void)same_scalar_assertion; // This stops the compiler from warning about unused declared variables

      // If our assertion did not fail, then create and return a new solver
      return rcp( new ConcreteSolver<Matrix,Vector>(A, X, B) );
    }
  };

/**
 * \internal
 *
 * If the apply method of this struct is ever called, then it means
 * that the user requested to create a concrete solver interface for
 * a matrix whose scalar type is not supported by the solver.  In
 * such a case we throw a runtime exception.
 */
template < template <class,class> class ConcreteSolver,
           class Matrix,
           class Vector >
struct throw_no_scalar_support_exception {
  static Teuchos::RCP<Solver<Matrix,Vector> > apply(Teuchos::RCP<const Matrix> A,
                                                    Teuchos::RCP<Vector>       X,
                                                    Teuchos::RCP<const Vector> B )
  {
    // typedef ConcreteSolver<Matrix,Vector> concretesolver_matrix_vector;
    typedef typename MatrixTraits<Matrix>::scalar_t scalar_t;
    TEUCHOS_TEST_FOR_EXCEPTION( true,
                        std::invalid_argument,
                        "The requested Amesos2 "
                        // << concretesolver_matrix_vector::name <<
                        " solver interface does not support the " <<
                        Teuchos::ScalarTraits<scalar_t>::name() <<
                        " scalar type." );
  }
};

  /**
   * \internal
   *
   * Utility meta-function which binds to an exception-throwing
   * runtime function if the solver does not support the scalar type
   * of the matrix.  Otherwise, if the scalar type is supported, then
   * this returns an RCP to a new concrete Amesos2 solver of the given
   * type.
   */
  template < template <class,class> class ConcreteSolver,
             class Matrix,
             class Vector >
  struct handle_solver_type_support {
    static Teuchos::RCP<Solver<Matrix,Vector> > apply(Teuchos::RCP<const Matrix> A,
                                                      Teuchos::RCP<Vector>       X,
                                                      Teuchos::RCP<const Vector> B )
    {
      return Meta::if_then_else<
      solver_supports_scalar<ConcreteSolver, typename MatrixTraits<Matrix>::scalar_t>::value,
        create_solver_with_supported_type<ConcreteSolver,Matrix,Vector>,
        throw_no_scalar_support_exception<ConcreteSolver,Matrix,Vector> >::type::apply(A, X, B);
    }
  };


  /////////////////////
  // Query Functions //
  /////////////////////

  /**
   * \brief Queries the Factory for support of the named third-party library.
   *
   * \return \c true if the solver is supported.
   *
   * \relatesalso Amesos2::Solver
   */
  bool query(const char* solverName);


  /**
   * \brief Queries the Factory for support of the named third-party library.
   *
   * \return \c true if the solver is supported.
   *
   * \relatesalso Amesos2::Solver
   */
  bool query(const std::string solverName);


  /////////////////
  // Definitions //
  /////////////////

  template <class Matrix,
            class Vector >
  Solver<Matrix,Vector>*
  create(Matrix* A, Vector* X, Vector* B)
  {
    std::string solver = "Klu2";
    // Pass non-owning RCP objects to other factory method
    return( create(solver, rcp(A,false), rcp(X,false), rcp(B,false)).getRawPtr() );
  }


  template <class Matrix,
            class Vector >
  Teuchos::RCP<Solver<Matrix,Vector> >
  create(Teuchos::RCP<const Matrix> A,
         Teuchos::RCP<Vector>       X,
         Teuchos::RCP<const Vector> B)
  {
    std::string solver = "Klu2";
    return( create(solver, A, X, B) );
  }


  template <class Matrix,
            class Vector >
  Solver<Matrix,Vector>*
  create(const char* solverName, const Matrix* A, Vector* X, const Vector* B)
  {
    std::string solver = solverName;
    // Pass non-owning Teuchos::RCP objects to other factory method
    return( create(solver, rcp(A,false), rcp(X,false), rcp(B,false)).getRawPtr() );
  }


  template <class Matrix,
            class Vector >
  Teuchos::RCP<Solver<Matrix,Vector> >
  create(const char* solverName,
         const Teuchos::RCP<const Matrix> A,
         const Teuchos::RCP<Vector>       X,
         const Teuchos::RCP<const Vector> B)
  {
    std::string solver = solverName;
    return( create(solver, A, X, B) );
  }


  template <class Matrix,
            class Vector >
  Solver<Matrix,Vector>*
  create(const std::string solverName, const Matrix* A){
    return( create(solverName, rcp(A,false),
                   Teuchos::RCP<Vector>(),
                   Teuchos::RCP<const Vector>()).getRawPtr() );
  }


  template <class Matrix,
            class Vector >
  Teuchos::RCP<Solver<Matrix,Vector> >
  create(const std::string solverName, const Teuchos::RCP<const Matrix> A){
    return( create(solverName, A, Teuchos::RCP<Vector>(), Teuchos::RCP<const Vector>()) );
  }


  template <class Matrix,
            class Vector >
  Teuchos::RCP<Solver<Matrix,Vector> >
  create(const std::string solverName, const Matrix* A, Vector* X, const Vector* B)
  {
    // Pass non-owning Teuchos::RCP objects to other factory method
    return( create(solverName, rcp(A,false), rcp(X,false), rcp(B,false)) );
  }


  template <class Matrix,
            class Vector >
  Teuchos::RCP<Solver<Matrix,Vector> >
  create(const std::string solver_name,
         const Teuchos::RCP<const Matrix> A,
         const Teuchos::RCP<Vector>       X,
         const Teuchos::RCP<const Vector> B)
  {
    std::string solverName = tolower(solver_name); // for easy string checking

    // Check for our native solver first.  Treat KLU and KLU2 as equals.
    //
    // We use compiler guards in case a user does want to disable KLU2
#ifdef HAVE_AMESOS2_BASKER
    if((solverName == "Basker") || (solverName == "basker"))
    {
      return handle_solver_type_support<Basker, Matrix,Vector>::apply(A,X,B);
    }
#endif



#ifdef HAVE_AMESOS2_KLU2 
    if((solverName == "amesos2_klu2") || (solverName == "klu2") ||
        (solverName == "amesos2_klu")  || (solverName == "klu")){
      return handle_solver_type_support<KLU2,Matrix,Vector>::apply(A, X, B);
    }
#endif

#ifdef HAVE_AMESOS2_SUPERLUDIST
    if((solverName == "amesos2_superludist") ||
       (solverName == "superludist") ||
       (solverName == "amesos2_superlu_dist") ||
       (solverName == "superlu_dist")){
      return handle_solver_type_support<Superludist,Matrix,Vector>::apply(A, X, B);
    }
#endif

#ifdef HAVE_AMESOS2_SUPERLUMT
    if((solverName == "amesos2_superlumt") ||
       (solverName == "superlumt") ||
       (solverName == "amesos2_superlu_mt") ||
       (solverName == "superlu_mt")){
      return handle_solver_type_support<Superlumt,Matrix,Vector>::apply(A, X, B);
    }
#endif

#ifdef HAVE_AMESOS2_UMFPACK
    if((solverName == "amesos2_umfpack") ||
       (solverName == "umfpack")){
      return handle_solver_type_support<Umfpack,Matrix,Vector>::apply(A, X, B);
    }
#endif

#ifdef HAVE_AMESOS2_SUPERLU
    if((solverName == "amesos2_superlu") ||
       (solverName == "superlu")){
      return handle_solver_type_support<Superlu,Matrix,Vector>::apply(A, X, B);
    }
#endif

#ifdef HAVE_AMESOS2_PARDISO_MKL
    if((solverName == "amesos2_pardiso_mkl") ||
       (solverName == "pardiso_mkl") ||
       (solverName == "amesos2_pardisomkl")  ||
       (solverName == "pardisomkl")){
      return handle_solver_type_support<PardisoMKL,Matrix,Vector>::apply(A, X, B);
    }
#endif

#ifdef HAVE_AMESOS2_LAPACK
    if((solverName == "amesos2_lapack") ||
       (solverName == "lapack")){
      return handle_solver_type_support<Lapack,Matrix,Vector>::apply(A, X, B);
    }
#endif


#ifdef HAVE_AMESOS2_MUMPS
    if((solverName == "MUMPS") || (solverName == "mumps") ||
       (solverName == "amesos2_MUMPS") || (solverName == "amesos2_mumps"))
      {
        return handle_solver_type_support<MUMPS,Matrix,Vector>::apply(A,X,B);
      }
#endif

#if defined (HAVE_AMESOS2_CHOLMOD) && defined (HAVE_AMESOS2_EXPERIMENTAL)
    if(solverName == "amesos2_cholmod")
      return handle_solver_type_support<Cholmod,Matrix,Vector>::apply(A, X, B);
#endif

    /* If none of the above conditionals are satisfied, then the solver
     * requested is not yet supported.  We throw a runtime exception stating
     * this, and return null.
     */
    std::string err_msg = solver_name + " is not enabled or is not supported";
    TEUCHOS_TEST_FOR_EXCEPTION(true, std::invalid_argument, err_msg);
    return( Teuchos::null );
  }

} // end namespace Amesos2

#endif  // AMESOS2_FACTORY_HPP