Amesos2 - Direct Sparse Solver Interfaces  Version of the Day
Amesos2_Superludist_FunctionMap.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 
53 #ifndef AMESOS2_SUPERLUDIST_FUNCTIONMAP_HPP
54 #define AMESOS2_SUPERLUDIST_FUNCTIONMAP_HPP
55 
56 #ifdef HAVE_TEUCHOS_COMPLEX
57 #include <complex>
58 #endif
59 
60 #include "Amesos2_config.h"
61 #include "Amesos2_FunctionMap.hpp"
62 #include "Amesos2_MatrixAdapter.hpp"
64 
65 
66 // Declarations of SuperLU_DIST types and namespace are found in
67 // Superludist_TypeMap.hpp
68 
69 #define AMESOS2_SLUD_GET_DIAG_SCALE(eq) (((eq)=='N') ? SLUD::NOEQUIL : ((eq)=='R') ? SLUD::ROW : ((eq)=='C') ? SLUD::COL : SLUD::BOTH)
70 
71 #define AMESOS2_SLUD_GET_EQUED(ds) (((ds)==SLUD::NOEQUIL) ? 'N' : ((ds)==SLUD::ROW) ? 'R' : ((ds)==SLUD::COL) ? 'C' : 'B')
72 
73 namespace Amesos2 {
74 
75  template <class Matrix, class Vector> class Superludist;
76 
77  SLUD::DiagScale_t get_diag_scale(char eq);
78  char get_equed(SLUD::DiagScale_t ds);
79 
80 
81  /* ==================== Specializations ====================
82  *
83  * \cond SuperLU_DIST_function_specializations
84  */
85 
108  template <>
109  struct FunctionMap<Superludist,double>
110  {
111  typedef TypeMap<Superludist,double> type_map;
112 
126  static void gstrf(SLUD::amesos2_superlu_dist_options_t* options, int m, int n, double anorm,
127  type_map::LUstruct_t* LU, SLUD::gridinfo_t* grid, SLUD::SuperLUStat_t* stat,
128  int* info)
129  {
130  SLUD::D::pdgstrf(options, m, n, anorm, LU, grid, stat, info);
131  }
132 
137  static void gstrs(SLUD::int_t n, type_map::LUstruct_t* lu_struct,
138  SLUD::ScalePermstruct_t* scale_perm_struct, SLUD::gridinfo_t* grid,
139  type_map::type* B, SLUD::int_t l_numrows, SLUD::int_t fst_global_row,
140  SLUD::int_t ldb, int nrhs, type_map::SOLVEstruct_t* solve_struct,
141  SLUD::SuperLUStat_t* stat, int* info)
142  {
143  SLUD::D::pdgstrs(n, lu_struct, scale_perm_struct, grid, B, l_numrows,
144  fst_global_row, ldb, nrhs, solve_struct, stat, info);
145  }
146 
154  static void gstrs_Bglobal(SLUD::int_t n, type_map::LUstruct_t* lu_struct,
155  SLUD::gridinfo_t* grid, type_map::type* B,
156  SLUD::int_t ldb, int nrhs,
157  SLUD::SuperLUStat_t* stat, int* info)
158  {
159  SLUD::D::pdgstrs_Bglobal(n, lu_struct, grid, B, ldb, nrhs, stat, info);
160  }
161 
165  static void gsrfs(SLUD::int_t n, SLUD::SuperMatrix* A, double anorm,
166  type_map::LUstruct_t* lu_struct,
167  SLUD::ScalePermstruct_t* scale_perm,
168  SLUD::gridinfo_t* grid, type_map::type* B, SLUD::int_t ldb,
169  type_map::type* X, SLUD::int_t ldx, int nrhs,
170  type_map::SOLVEstruct_t* solve_struct, double* berr,
171  SLUD::SuperLUStat_t* stat, int* info)
172  {
173  SLUD::D::pdgsrfs(n, A, anorm, lu_struct, scale_perm, grid, B, ldb,
174  X, ldx, nrhs, solve_struct, berr, stat, info);
175  }
176 
184  static void gsrfs_ABXglobal(SLUD::int_t n, SLUD::SuperMatrix* A, double anorm,
185  type_map::LUstruct_t* lu_struct, SLUD::gridinfo_t* grid,
186  type_map::type* B, SLUD::int_t ldb, type_map::type* X,
187  SLUD::int_t ldx, int nrhs, double* berr,
188  SLUD::SuperLUStat_t* stat, int* info)
189  {
190  SLUD::D::pdgsrfs_ABXglobal(n, A, anorm, lu_struct, grid, B, ldb,
191  X, ldx, nrhs, berr, stat, info);
192  }
193 
198  static void create_CompRowLoc_Matrix(SLUD::SuperMatrix* A, SLUD::int_t g_numrows,
199  SLUD::int_t g_numcols, SLUD::int_t l_nnz,
200  SLUD::int_t l_numrows, SLUD::int_t fst_global_row,
201  type_map::type* nzval, SLUD::int_t* colind,
202  SLUD::int_t* rowptr, SLUD::Stype_t storage_t,
203  SLUD::Dtype_t data_t, SLUD::Mtype_t mat_t)
204  {
205  SLUD::D::dCreate_CompRowLoc_Matrix_dist(A, g_numrows, g_numcols, l_nnz,
206  l_numrows, fst_global_row,
207  nzval, colind, rowptr,
208  storage_t, data_t, mat_t);
209  }
210 
218  static void create_CompCol_Matrix(SLUD::SuperMatrix* A, SLUD::int_t numrows,
219  SLUD::int_t numcols, SLUD::int_t nnz,
220  type_map::type* nzval, SLUD::int_t* rowind,
221  SLUD::int_t* colptr, SLUD::Stype_t storage_t,
222  SLUD::Dtype_t data_t, SLUD::Mtype_t mat_t)
223  {
224  SLUD::D::dCreate_CompCol_Matrix_dist(A, numrows, numcols, nnz,
225  nzval, rowind, colptr,
226  storage_t, data_t, mat_t);
227  }
228 
237  static void create_Dense_Matrix(SLUD::SuperMatrix* X, int m, int n,
238  type_map::type* x, int ldx, SLUD::Stype_t stype,
239  SLUD::Dtype_t dtype, SLUD::Mtype_t mtype)
240  {
241  SLUD::D::dCreate_Dense_Matrix_dist(X, m, n, x, ldx, stype, dtype, mtype);
242  }
243 
244  static void permute_Dense_Matrix(SLUD::int_t fst_row, SLUD::int_t m_loc,
245  SLUD::int_t* row_to_proc, SLUD::int_t* perm,
246  type_map::type* X, int ldx, type_map::type* B,
247  int ldb, int nrhs, SLUD::gridinfo_t* grid)
248  {
249  SLUD::D::pdPermute_Dense_Matrix(fst_row, m_loc, row_to_proc, perm,
250  X, ldx, B, ldb, nrhs, grid);
251  }
252 
261  static void gsequ_loc(SLUD::SuperMatrix* A, double* r, double* c,
262  double* rowcnd, double* colcnd, double* amax, int* info,
263  SLUD::gridinfo_t* grid)
264  {
265  SLUD::D::pdgsequ(A, r, c, rowcnd, colcnd, amax, info, grid);
266  }
267 
272  static void gsequ(SLUD::SuperMatrix* A, double* r, double* c,
273  double* rowcnd, double* colcnd, double* amax, int* info)
274  {
275  SLUD::D::dgsequ_dist(A, r, c, rowcnd, colcnd, amax, info);
276  }
277 
281  static void laqgs_loc(SLUD::SuperMatrix* A, double* r, double* c,
282  double rowcnd, double colcnd, double amax,
283  SLUD::DiagScale_t* equed)
284  {
285  char eq = AMESOS2_SLUD_GET_EQUED(*equed);
286  SLUD::D::pdlaqgs(A, r, c, rowcnd, colcnd, amax, &eq);
287  *equed = AMESOS2_SLUD_GET_DIAG_SCALE(eq);
288  }
289 
303  static void laqgs(SLUD::SuperMatrix* A, double* r, double* c,
304  double rowcnd, double colcnd, double amax, SLUD::DiagScale_t* equed)
305  {
306  char eq = AMESOS2_SLUD_GET_EQUED(*equed);
307  SLUD::D::dlaqgs_dist(A, r, c, rowcnd, colcnd, amax, &eq);
308  *equed = AMESOS2_SLUD_GET_DIAG_SCALE(eq);
309  }
310 
311  /*
312  * This version suitable for A in NCPformat
313  */
314  static void distribute(SLUD::fact_t fact, SLUD::int_t n,
315  SLUD::SuperMatrix* A, SLUD::Glu_freeable_t* glu_freeable,
316  type_map::LUstruct_t* lu, SLUD::gridinfo_t* grid)
317  {
318  SLUD::D::ddistribute(fact, n, A, glu_freeable, lu, grid);
319  }
320 
321  /*
322  * This version suitable for A in NR_loc format.
323  *
324  * This routine should be used in the case where fact ==
325  * SamePattern_SameRowPerm, otherwise dist_psymbtonum should be
326  * called.o
327  */
328  static void pdistribute(SLUD::fact_t fact, SLUD::int_t n,
329  SLUD::SuperMatrix* A, SLUD::ScalePermstruct_t* scale_perm,
330  SLUD::Glu_freeable_t* glu_freeable, type_map::LUstruct_t* lu,
331  SLUD::gridinfo_t* grid)
332  {
333  SLUD::D::pddistribute(fact, n, A, scale_perm, glu_freeable, lu, grid);
334  }
335 
336  /*
337  * Distributes the input matrix A onto the 2D process grid based on
338  * the L/U graph data in pslu_freeable. On exit the struct lu
339  * contains the information necessary to perform a numeric
340  * factorization using gstrf.
341  *
342  * This routine should always be called with fact == DOFACT
343  */
344  static void dist_psymbtonum(SLUD::fact_t fact, SLUD::int_t n, SLUD::SuperMatrix* A,
345  SLUD::ScalePermstruct_t* scale_perm,
346  SLUD::Pslu_freeable_t* pslu_freeable,
347  type_map::LUstruct_t* lu, SLUD::gridinfo_t* grid)
348  {
349  SLUD::D::ddist_psymbtonum(fact, n, A, scale_perm, pslu_freeable, lu, grid);
350  }
351 
352  /*
353  * The parameter norm may be one of:
354  * - 'M' for the max absolute matrix entry value
355  * - '1' for the norm1(A)
356  * - 'I' for the normI(A)
357  * - 'F' for the Frobenius norm of A
358  */
359  static double plangs(char* norm, SLUD::SuperMatrix* A, SLUD::gridinfo_t* grid)
360  {
361  return SLUD::D::pdlangs(norm, A, grid);
362  }
363 
364  static void SolveInit(SLUD::amesos2_superlu_dist_options_t* options, SLUD::SuperMatrix* A,
365  SLUD::int_t* perm_r, SLUD::int_t* perm_c, SLUD::int_t nrhs,
366  type_map::LUstruct_t* lu, SLUD::gridinfo_t* grid,
367  type_map::SOLVEstruct_t* solve_struct)
368  {
369  SLUD::D::dSolveInit(options, A, perm_r, perm_c, nrhs, lu, grid, solve_struct);
370  }
371 
372  static void LUstructInit(SLUD::int_t m, SLUD::int_t n,
373  type_map::LUstruct_t* lu)
374  {
375 #ifdef HAVE_SUPERLUDIST_LUSTRUCTINIT_2ARG
376  SLUD::D::LUstructInit(n, lu);
377 #else
378  SLUD::D::LUstructInit(m, n, lu);
379 #endif
380  }
381 
382  static void Destroy_LU(SLUD::int_t m, SLUD::gridinfo_t* grid,
383  type_map::LUstruct_t* lu)
384  {
385  SLUD::D::Destroy_LU(m, grid, lu);
386  }
387 
388  static void LUstructFree(type_map::LUstruct_t* lu)
389  {
390  SLUD::D::LUstructFree(lu);
391  }
392 
393  static void SolveFinalize(SLUD::amesos2_superlu_dist_options_t* options,
394  type_map::SOLVEstruct_t* solve_struct)
395  {
396  SLUD::D::dSolveFinalize(options, solve_struct);
397  }
398  };
399 
400 
401 #if defined(HAVE_TEUCHOS_COMPLEX) && !defined(__clang__)
402  /* The specializations for Teuchos::as<> for SLUD::complex and
403  * SLUD::doublecomplex are provided in Amesos2_Superlu_Type.hpp
404  */
405  template <>
406  struct FunctionMap<Superludist,SLUD::Z::doublecomplex>
407  {
408  typedef TypeMap<Superludist,std::complex<double> > type_map;
409 
410  static void gstrf(SLUD::amesos2_superlu_dist_options_t* options, int m, int n, double anorm,
411  type_map::LUstruct_t* LU, SLUD::gridinfo_t* grid,
412  SLUD::SuperLUStat_t* stat, int* info)
413  {
414  SLUD::Z::pzgstrf(options, m, n, anorm, LU, grid, stat, info);
415  }
416 
417  static void gstrs(SLUD::int_t n, type_map::LUstruct_t* lu_struct,
418  SLUD::ScalePermstruct_t* scale_perm_struct,
419  SLUD::gridinfo_t* grid, type_map::type* B,
420  SLUD::int_t l_numrows, SLUD::int_t fst_global_row,
421  SLUD::int_t ldb, int nrhs,
422  type_map::SOLVEstruct_t* solve_struct,
423  SLUD::SuperLUStat_t* stat, int* info)
424  {
425  SLUD::Z::pzgstrs(n, lu_struct, scale_perm_struct, grid, B, l_numrows,
426  fst_global_row, ldb, nrhs, solve_struct, stat, info);
427  }
428 
429  static void gstrs_Bglobal(SLUD::int_t n, type_map::LUstruct_t* lu_struct,
430  SLUD::gridinfo_t* grid, type_map::type* B,
431  SLUD::int_t ldb, int nrhs, SLUD::SuperLUStat_t* stat, int* info)
432  {
433  SLUD::Z::pzgstrs_Bglobal(n, lu_struct, grid, B, ldb, nrhs, stat, info);
434  }
435 
436  static void create_CompRowLoc_Matrix(SLUD::SuperMatrix* A, SLUD::int_t g_numrows,
437  SLUD::int_t g_numcols, SLUD::int_t l_nnz,
438  SLUD::int_t l_numrows, SLUD::int_t fst_global_row,
439  type_map::type* nzval, SLUD::int_t* colind,
440  SLUD::int_t* rowptr, SLUD::Stype_t storage_t,
441  SLUD::Dtype_t data_t, SLUD::Mtype_t mat_t)
442  {
443  SLUD::Z::zCreate_CompRowLoc_Matrix_dist(A, g_numrows, g_numcols, l_nnz,
444  l_numrows, fst_global_row,
445  nzval, colind, rowptr,
446  storage_t, data_t, mat_t);
447  }
448 
449  static void create_CompCol_Matrix(SLUD::SuperMatrix* A, SLUD::int_t numrows,
450  SLUD::int_t numcols, SLUD::int_t nnz,
451  type_map::type* nzval, SLUD::int_t* rowind,
452  SLUD::int_t* colptr, SLUD::Stype_t storage_t,
453  SLUD::Dtype_t data_t, SLUD::Mtype_t mat_t)
454  {
455  SLUD::Z::zCreate_CompCol_Matrix_dist(A, numrows, numcols, nnz,
456  nzval, rowind, colptr,
457  storage_t, data_t, mat_t);
458  }
459 
460  static void create_Dense_Matrix(SLUD::SuperMatrix* X, int m, int n,
461  TypeMap<Superludist,std::complex<double> >::type* x, int ldx,
462  SLUD::Stype_t stype, SLUD::Dtype_t dtype, SLUD::Mtype_t mtype)
463  {
464  SLUD::Z::zCreate_Dense_Matrix_dist(X, m, n, x, ldx, stype, dtype, mtype);
465  }
466 
467  static void permute_Dense_Matrix(SLUD::int_t fst_row, SLUD::int_t m_loc,
468  SLUD::int_t* row_to_proc, SLUD::int_t* perm,
469  type_map::type* X, int ldx,
470  type_map::type* B, int ldb,
471  int nrhs, SLUD::gridinfo_t* grid)
472  {
473  SLUD::Z::pzPermute_Dense_Matrix(fst_row, m_loc, row_to_proc, perm,
474  X, ldx, B, ldb, nrhs, grid);
475  }
476 
477  static void gsequ_loc(SLUD::SuperMatrix* A, double* r, double* c,
478  double* rowcnd, double* colcnd, double* amax, int* info,
479  SLUD::gridinfo_t* grid)
480  {
481  SLUD::Z::pzgsequ(A, r, c, rowcnd, colcnd, amax, info, grid);
482  }
483 
484  static void gsequ(SLUD::SuperMatrix* A, double* r, double* c,
485  double* rowcnd, double* colcnd, double* amax, int* info)
486  {
487  SLUD::Z::zgsequ_dist(A, r, c, rowcnd, colcnd, amax, info);
488  }
489 
490  static void laqgs_loc(SLUD::SuperMatrix* A, double* r, double* c,
491  double rowcnd, double colcnd, double amax, SLUD::DiagScale_t* equed)
492  {
493  char eq = AMESOS2_SLUD_GET_EQUED(*equed);
494  SLUD::Z::pzlaqgs(A, r, c, rowcnd, colcnd, amax, &eq);
495  *equed = AMESOS2_SLUD_GET_DIAG_SCALE(eq);
496  }
497 
498  static void laqgs(SLUD::SuperMatrix* A, double* r, double* c,
499  double rowcnd, double colcnd, double amax, SLUD::DiagScale_t* equed)
500  {
501  char eq = AMESOS2_SLUD_GET_EQUED(*equed);
502  SLUD::Z::zlaqgs_dist(A, r, c, rowcnd, colcnd, amax, &eq);
503  *equed = AMESOS2_SLUD_GET_DIAG_SCALE(eq);
504  }
505 
506  static void distribute(SLUD::fact_t fact, SLUD::int_t n,
507  SLUD::SuperMatrix* A, SLUD::Glu_freeable_t* glu_freeable,
508  type_map::LUstruct_t* lu, SLUD::gridinfo_t* grid)
509  {
510  SLUD::Z::zdistribute(fact, n, A, glu_freeable, lu, grid);
511  }
512 
513  static void pdistribute(SLUD::fact_t fact, SLUD::int_t n,
514  SLUD::SuperMatrix* A, SLUD::ScalePermstruct_t* scale_perm,
515  SLUD::Glu_freeable_t* glu_freeable, type_map::LUstruct_t* lu,
516  SLUD::gridinfo_t* grid)
517  {
518  SLUD::Z::pzdistribute(fact, n, A, scale_perm, glu_freeable, lu, grid);
519  }
520 
521  static void dist_psymbtonum(SLUD::fact_t fact, SLUD::int_t n,
522  SLUD::SuperMatrix* A, SLUD::ScalePermstruct_t* scale_perm,
523  SLUD::Pslu_freeable_t* pslu_freeable, type_map::LUstruct_t* lu,
524  SLUD::gridinfo_t* grid)
525  {
526  SLUD::Z::zdist_psymbtonum(fact, n, A, scale_perm, pslu_freeable, lu, grid);
527  }
528 
529  static double plangs(char* norm, SLUD::SuperMatrix* A, SLUD::gridinfo_t* grid)
530  {
531  return SLUD::Z::pzlangs(norm, A, grid);
532  }
533 
534  static void SolveInit(SLUD::amesos2_superlu_dist_options_t* options, SLUD::SuperMatrix* A,
535  SLUD::int_t* perm_r, SLUD::int_t* perm_c, SLUD::int_t nrhs,
536  type_map::LUstruct_t* lu, SLUD::gridinfo_t* grid,
537  type_map::SOLVEstruct_t* solve_struct)
538  {
539  SLUD::Z::zSolveInit(options, A, perm_r, perm_c, nrhs, lu, grid, solve_struct);
540  }
541 
542  static void LUstructInit(SLUD::int_t m, SLUD::int_t n, type_map::LUstruct_t* lu)
543  {
544 #ifdef HAVE_SUPERLUDIST_LUSTRUCTINIT_2ARG
545  SLUD::Z::LUstructInit(n, lu);
546 #else
547  SLUD::Z::LUstructInit(m, n, lu);
548 #endif
549  }
550 
551  static void Destroy_LU(SLUD::int_t m, SLUD::gridinfo_t* grid, type_map::LUstruct_t* lu)
552  {
553  SLUD::Z::Destroy_LU(m, grid, lu);
554  }
555 
556  static void LUstructFree(type_map::LUstruct_t* lu)
557  {
558  SLUD::Z::LUstructFree(lu);
559  }
560 
561  static void SolveFinalize(SLUD::amesos2_superlu_dist_options_t* options,
562  type_map::SOLVEstruct_t* solve_struct)
563  {
564  SLUD::Z::zSolveFinalize(options, solve_struct);
565  }
566  };
567 #endif // HAVE_TEUCHOS_COMPLEX
568 
569 } // end namespace Amesos2
570 
571 
572 #endif // AMESOS2_SUPERLUDIST_FUNCTIONMAP_HPP
Declaration of Function mapping class for Amesos2.
Provides definition of SuperLU_DIST types as well as conversions and type traits. ...