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  {
377 #if defined(AMESOS2_ENABLES_SUPERLUDIST_VERSION5_AND_HIGHER)
378  SLUD::D::LUstructInit(n, lu);
379 #else
380 #ifdef HAVE_SUPERLUDIST_LUSTRUCTINIT_2ARG
381  SLUD::D::LUstructInit(n, lu);
382 #else
383  SLUD::D::LUstructInit(m, n, lu);
384 #endif
385 #endif
386  }
387 
388  static void Destroy_LU(SLUD::int_t m, SLUD::gridinfo_t* grid,
389  type_map::LUstruct_t* lu)
390  {
391  SLUD::D::Destroy_LU(m, grid, lu);
392  }
393 
394  static void LUstructFree(type_map::LUstruct_t* lu)
395  {
396  SLUD::D::LUstructFree(lu);
397  }
398 
399  static void SolveFinalize(SLUD::amesos2_superlu_dist_options_t* options,
400  type_map::SOLVEstruct_t* solve_struct)
401  {
402  SLUD::D::dSolveFinalize(options, solve_struct);
403  }
404  };
405 
406 
407 #if defined(HAVE_TEUCHOS_COMPLEX) && !defined(__clang__)
408  /* The specializations for Teuchos::as<> for SLUD::complex and
409  * SLUD::doublecomplex are provided in Amesos2_Superlu_Type.hpp
410  */
411  template <>
412  struct FunctionMap<Superludist,SLUD::Z::doublecomplex>
413  {
414  typedef TypeMap<Superludist,std::complex<double> > type_map;
415 
416  static void gstrf(SLUD::amesos2_superlu_dist_options_t* options, int m, int n, double anorm,
417  type_map::LUstruct_t* LU, SLUD::gridinfo_t* grid,
418  SLUD::SuperLUStat_t* stat, int* info)
419  {
420  SLUD::Z::pzgstrf(options, m, n, anorm, LU, grid, stat, info);
421  }
422 
423  static void gstrs(SLUD::int_t n, type_map::LUstruct_t* lu_struct,
424  SLUD::ScalePermstruct_t* scale_perm_struct,
425  SLUD::gridinfo_t* grid, type_map::type* B,
426  SLUD::int_t l_numrows, SLUD::int_t fst_global_row,
427  SLUD::int_t ldb, int nrhs,
428  type_map::SOLVEstruct_t* solve_struct,
429  SLUD::SuperLUStat_t* stat, int* info)
430  {
431  SLUD::Z::pzgstrs(n, lu_struct, scale_perm_struct, grid, B, l_numrows,
432  fst_global_row, ldb, nrhs, solve_struct, stat, info);
433  }
434 
435  static void gstrs_Bglobal(SLUD::int_t n, type_map::LUstruct_t* lu_struct,
436  SLUD::gridinfo_t* grid, type_map::type* B,
437  SLUD::int_t ldb, int nrhs, SLUD::SuperLUStat_t* stat, int* info)
438  {
439  SLUD::Z::pzgstrs_Bglobal(n, lu_struct, grid, B, ldb, nrhs, stat, info);
440  }
441 
442  static void create_CompRowLoc_Matrix(SLUD::SuperMatrix* A, SLUD::int_t g_numrows,
443  SLUD::int_t g_numcols, SLUD::int_t l_nnz,
444  SLUD::int_t l_numrows, SLUD::int_t fst_global_row,
445  type_map::type* nzval, SLUD::int_t* colind,
446  SLUD::int_t* rowptr, SLUD::Stype_t storage_t,
447  SLUD::Dtype_t data_t, SLUD::Mtype_t mat_t)
448  {
449  SLUD::Z::zCreate_CompRowLoc_Matrix_dist(A, g_numrows, g_numcols, l_nnz,
450  l_numrows, fst_global_row,
451  nzval, colind, rowptr,
452  storage_t, data_t, mat_t);
453  }
454 
455  static void create_CompCol_Matrix(SLUD::SuperMatrix* A, SLUD::int_t numrows,
456  SLUD::int_t numcols, SLUD::int_t nnz,
457  type_map::type* nzval, SLUD::int_t* rowind,
458  SLUD::int_t* colptr, SLUD::Stype_t storage_t,
459  SLUD::Dtype_t data_t, SLUD::Mtype_t mat_t)
460  {
461  SLUD::Z::zCreate_CompCol_Matrix_dist(A, numrows, numcols, nnz,
462  nzval, rowind, colptr,
463  storage_t, data_t, mat_t);
464  }
465 
466  static void create_Dense_Matrix(SLUD::SuperMatrix* X, int m, int n,
467  TypeMap<Superludist,std::complex<double> >::type* x, int ldx,
468  SLUD::Stype_t stype, SLUD::Dtype_t dtype, SLUD::Mtype_t mtype)
469  {
470  SLUD::Z::zCreate_Dense_Matrix_dist(X, m, n, x, ldx, stype, dtype, mtype);
471  }
472 
473  static void permute_Dense_Matrix(SLUD::int_t fst_row, SLUD::int_t m_loc,
474  SLUD::int_t* row_to_proc, SLUD::int_t* perm,
475  type_map::type* X, int ldx,
476  type_map::type* B, int ldb,
477  int nrhs, SLUD::gridinfo_t* grid)
478  {
479  SLUD::Z::pzPermute_Dense_Matrix(fst_row, m_loc, row_to_proc, perm,
480  X, ldx, B, ldb, nrhs, grid);
481  }
482 
483  static void gsequ_loc(SLUD::SuperMatrix* A, double* r, double* c,
484  double* rowcnd, double* colcnd, double* amax, int* info,
485  SLUD::gridinfo_t* grid)
486  {
487  SLUD::Z::pzgsequ(A, r, c, rowcnd, colcnd, amax, info, grid);
488  }
489 
490  static void gsequ(SLUD::SuperMatrix* A, double* r, double* c,
491  double* rowcnd, double* colcnd, double* amax, int* info)
492  {
493  SLUD::Z::zgsequ_dist(A, r, c, rowcnd, colcnd, amax, info);
494  }
495 
496  static void laqgs_loc(SLUD::SuperMatrix* A, double* r, double* c,
497  double rowcnd, double colcnd, double amax, SLUD::DiagScale_t* equed)
498  {
499  char eq = AMESOS2_SLUD_GET_EQUED(*equed);
500  SLUD::Z::pzlaqgs(A, r, c, rowcnd, colcnd, amax, &eq);
501  *equed = AMESOS2_SLUD_GET_DIAG_SCALE(eq);
502  }
503 
504  static void laqgs(SLUD::SuperMatrix* A, double* r, double* c,
505  double rowcnd, double colcnd, double amax, SLUD::DiagScale_t* equed)
506  {
507  char eq = AMESOS2_SLUD_GET_EQUED(*equed);
508  SLUD::Z::zlaqgs_dist(A, r, c, rowcnd, colcnd, amax, &eq);
509  *equed = AMESOS2_SLUD_GET_DIAG_SCALE(eq);
510  }
511 
512  static void distribute(SLUD::fact_t fact, SLUD::int_t n,
513  SLUD::SuperMatrix* A, SLUD::Glu_freeable_t* glu_freeable,
514  type_map::LUstruct_t* lu, SLUD::gridinfo_t* grid)
515  {
516  SLUD::Z::zdistribute(fact, n, A, glu_freeable, lu, grid);
517  }
518 
519  static void pdistribute(SLUD::fact_t fact, SLUD::int_t n,
520  SLUD::SuperMatrix* A, SLUD::ScalePermstruct_t* scale_perm,
521  SLUD::Glu_freeable_t* glu_freeable, type_map::LUstruct_t* lu,
522  SLUD::gridinfo_t* grid)
523  {
524  SLUD::Z::pzdistribute(fact, n, A, scale_perm, glu_freeable, lu, grid);
525  }
526 
527  static void dist_psymbtonum(SLUD::fact_t fact, SLUD::int_t n,
528  SLUD::SuperMatrix* A, SLUD::ScalePermstruct_t* scale_perm,
529  SLUD::Pslu_freeable_t* pslu_freeable, type_map::LUstruct_t* lu,
530  SLUD::gridinfo_t* grid)
531  {
532  SLUD::Z::zdist_psymbtonum(fact, n, A, scale_perm, pslu_freeable, lu, grid);
533  }
534 
535  static double plangs(char* norm, SLUD::SuperMatrix* A, SLUD::gridinfo_t* grid)
536  {
537  return SLUD::Z::pzlangs(norm, A, grid);
538  }
539 
540  static void SolveInit(SLUD::amesos2_superlu_dist_options_t* options, SLUD::SuperMatrix* A,
541  SLUD::int_t* perm_r, SLUD::int_t* perm_c, SLUD::int_t nrhs,
542  type_map::LUstruct_t* lu, SLUD::gridinfo_t* grid,
543  type_map::SOLVEstruct_t* solve_struct)
544  {
545  SLUD::Z::zSolveInit(options, A, perm_r, perm_c, nrhs, lu, grid, solve_struct);
546  }
547 
548  static void LUstructInit(SLUD::int_t m, SLUD::int_t n, type_map::LUstruct_t* lu)
549  {
552 #if defined(AMESOS2_ENABLES_SUPERLUDIST_VERSION5_AND_HIGHER)
553  SLUD::Z::LUstructInit(n, lu);
554 #else
555 #ifdef HAVE_SUPERLUDIST_LUSTRUCTINIT_2ARG
556  SLUD::Z::LUstructInit(n, lu);
557 #else
558  SLUD::Z::LUstructInit(m, n, lu);
559 #endif
560 #endif
561  }
562 
563  static void Destroy_LU(SLUD::int_t m, SLUD::gridinfo_t* grid, type_map::LUstruct_t* lu)
564  {
565  SLUD::Z::Destroy_LU(m, grid, lu);
566  }
567 
568  static void LUstructFree(type_map::LUstruct_t* lu)
569  {
570  SLUD::Z::LUstructFree(lu);
571  }
572 
573  static void SolveFinalize(SLUD::amesos2_superlu_dist_options_t* options,
574  type_map::SOLVEstruct_t* solve_struct)
575  {
576  SLUD::Z::zSolveFinalize(options, solve_struct);
577  }
578  };
579 #endif // HAVE_TEUCHOS_COMPLEX
580 
581 } // end namespace Amesos2
582 
583 
584 #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. ...