Amesos2 - Direct Sparse Solver Interfaces Version of the Day
Amesos2_Superludist_FunctionMap.hpp
Go to the documentation of this file.
00001 // @HEADER
00002 //
00003 // ***********************************************************************
00004 //
00005 //           Amesos2: Templated Direct Sparse Solver Package 
00006 //                  Copyright 2011 Sandia Corporation
00007 //
00008 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
00009 // the U.S. Government retains certain rights in this software.
00010 //
00011 // Redistribution and use in source and binary forms, with or without
00012 // modification, are permitted provided that the following conditions are
00013 // met:
00014 //
00015 // 1. Redistributions of source code must retain the above copyright
00016 // notice, this list of conditions and the following disclaimer.
00017 //
00018 // 2. Redistributions in binary form must reproduce the above copyright
00019 // notice, this list of conditions and the following disclaimer in the
00020 // documentation and/or other materials provided with the distribution.
00021 //
00022 // 3. Neither the name of the Corporation nor the names of the
00023 // contributors may be used to endorse or promote products derived from
00024 // this software without specific prior written permission.
00025 //
00026 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00027 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00028 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00029 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00030 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00031 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00032 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00033 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00034 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00035 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00036 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00037 //
00038 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
00039 //
00040 // ***********************************************************************
00041 //
00042 // @HEADER
00043 
00053 #ifndef AMESOS2_SUPERLUDIST_FUNCTIONMAP_HPP
00054 #define AMESOS2_SUPERLUDIST_FUNCTIONMAP_HPP
00055 
00056 #ifdef HAVE_TEUCHOS_COMPLEX
00057 #include <complex>
00058 #endif
00059 
00060 #include "Amesos2_FunctionMap.hpp"
00061 #include "Amesos2_MatrixAdapter.hpp"
00062 #include "Amesos2_Superludist_TypeMap.hpp"
00063 
00064 
00065 // Declarations of SuperLU_DIST types and namespace are found in
00066 // Superludist_TypeMap.hpp
00067 
00068 #define AMESOS2_SLUD_GET_DIAG_SCALE(eq) (((eq)=='N') ? SLUD::NOEQUIL : ((eq)=='R') ? SLUD::ROW : ((eq)=='C') ? SLUD::COL : SLUD::BOTH)
00069 
00070 #define AMESOS2_SLUD_GET_EQUED(ds) (((ds)==SLUD::NOEQUIL) ? 'N' : ((ds)==SLUD::ROW) ? 'R' : ((ds)=='C') ? SLUD::COL : SLUD::BOTH)
00071 
00072 namespace Amesos2 {
00073 
00074   template <class Matrix, class Vector> class Superludist;
00075 
00076   SLUD::DiagScale_t get_diag_scale(char eq);
00077   char get_equed(SLUD::DiagScale_t ds);
00078 
00079 
00080   /* ==================== Specializations ====================
00081    *
00082    * \cond SuperLU_DIST_function_specializations 
00083    */
00084 
00107   template <>
00108   struct FunctionMap<Superludist,double>
00109   {
00110     typedef TypeMap<Superludist,double> type_map;
00111   
00125     static void gstrf(SLUD::superlu_options_t* options, int m, int n, double anorm, 
00126           type_map::LUstruct_t* LU, SLUD::gridinfo_t* grid, SLUD::SuperLUStat_t* stat, 
00127           int* info)
00128     {
00129       SLUD::D::pdgstrf(options, m, n, anorm, LU, grid, stat, info);
00130     }
00131 
00136     static void gstrs(SLUD::int_t n, type_map::LUstruct_t* lu_struct, 
00137           SLUD::ScalePermstruct_t* scale_perm_struct, SLUD::gridinfo_t* grid,
00138           type_map::type* B, SLUD::int_t l_numrows, SLUD::int_t fst_global_row, 
00139           SLUD::int_t ldb, int nrhs, type_map::SOLVEstruct_t* solve_struct, 
00140           SLUD::SuperLUStat_t* stat, int* info)
00141     {
00142       SLUD::D::pdgstrs(n, lu_struct, scale_perm_struct, grid, B, l_numrows,
00143            fst_global_row, ldb, nrhs, solve_struct, stat, info);
00144     }
00145 
00153     static void gstrs_Bglobal(SLUD::int_t n, type_map::LUstruct_t* lu_struct,
00154             SLUD::gridinfo_t* grid, type_map::type* B,
00155             SLUD::int_t ldb, int nrhs,
00156             SLUD::SuperLUStat_t* stat, int* info)
00157     {
00158       SLUD::D::pdgstrs_Bglobal(n, lu_struct, grid, B, ldb, nrhs, stat, info);
00159     }
00160 
00164     static void gsrfs(SLUD::int_t n, SLUD::SuperMatrix* A, double anorm, 
00165           type_map::LUstruct_t* lu_struct,
00166           SLUD::ScalePermstruct_t* scale_perm, 
00167           SLUD::gridinfo_t* grid, type_map::type* B, SLUD::int_t ldb, 
00168           type_map::type* X, SLUD::int_t ldx, int nrhs, 
00169           type_map::SOLVEstruct_t* solve_struct, double* berr, 
00170           SLUD::SuperLUStat_t* stat, int* info)
00171     {
00172       SLUD::D::pdgsrfs(n, A, anorm, lu_struct, scale_perm, grid, B, ldb, 
00173            X, ldx, nrhs, solve_struct, berr, stat, info);
00174     }
00175 
00183     static void gsrfs_ABXglobal(SLUD::int_t n, SLUD::SuperMatrix* A, double anorm,
00184         type_map::LUstruct_t* lu_struct, SLUD::gridinfo_t* grid,
00185         type_map::type* B, SLUD::int_t ldb, type_map::type* X,
00186         SLUD::int_t ldx, int nrhs, double* berr,
00187         SLUD::SuperLUStat_t* stat, int* info)
00188     {
00189       SLUD::D::pdgsrfs_ABXglobal(n, A, anorm, lu_struct, grid, B, ldb, 
00190          X, ldx, nrhs, berr, stat, info);
00191     }
00192   
00197     static void create_CompRowLoc_Matrix(SLUD::SuperMatrix* A, SLUD::int_t g_numrows,
00198            SLUD::int_t g_numcols, SLUD::int_t l_nnz,
00199            SLUD::int_t l_numrows, SLUD::int_t fst_global_row,
00200            type_map::type* nzval, SLUD::int_t* colind,
00201            SLUD::int_t* rowptr, SLUD::Stype_t storage_t,
00202            SLUD::Dtype_t data_t, SLUD::Mtype_t mat_t)
00203     {
00204       SLUD::D::dCreate_CompRowLoc_Matrix_dist(A, g_numrows, g_numcols, l_nnz, 
00205                 l_numrows, fst_global_row,
00206                 nzval, colind, rowptr,
00207                 storage_t, data_t, mat_t);
00208     }
00209 
00217     static void create_CompCol_Matrix(SLUD::SuperMatrix* A, SLUD::int_t numrows,
00218               SLUD::int_t numcols, SLUD::int_t nnz,
00219               type_map::type* nzval, SLUD::int_t* rowind,
00220               SLUD::int_t* colptr, SLUD::Stype_t storage_t,
00221               SLUD::Dtype_t data_t, SLUD::Mtype_t mat_t)
00222     {
00223       SLUD::D::dCreate_CompCol_Matrix_dist(A, numrows, numcols, nnz, 
00224              nzval, rowind, colptr,
00225              storage_t, data_t, mat_t);
00226     }
00227 
00236     static void create_Dense_Matrix(SLUD::SuperMatrix* X, int m, int n,
00237             type_map::type* x, int ldx, SLUD::Stype_t stype,
00238             SLUD::Dtype_t dtype, SLUD::Mtype_t mtype)
00239     {
00240       SLUD::D::dCreate_Dense_Matrix_dist(X, m, n, x, ldx, stype, dtype, mtype);
00241     }
00242 
00243     static void permute_Dense_Matrix(SLUD::int_t fst_row, SLUD::int_t m_loc,
00244              SLUD::int_t* row_to_proc, SLUD::int_t* perm,
00245              type_map::type* X, int ldx, type_map::type* B,
00246              int ldb, int nrhs, SLUD::gridinfo_t* grid)
00247     {
00248       SLUD::D::pdPermute_Dense_Matrix(fst_row, m_loc, row_to_proc, perm,
00249               X, ldx, B, ldb, nrhs, grid);
00250     }
00251   
00260     static void gsequ_loc(SLUD::SuperMatrix* A, double* r, double* c, 
00261         double* rowcnd, double* colcnd, double* amax, int* info, 
00262         SLUD::gridinfo_t* grid)
00263     {
00264       SLUD::D::pdgsequ(A, r, c, rowcnd, colcnd, amax, info, grid);
00265     }
00266 
00271     static void gsequ(SLUD::SuperMatrix* A, double* r, double* c, 
00272           double* rowcnd, double* colcnd, double* amax, int* info)
00273     {
00274       SLUD::D::dgsequ_dist(A, r, c, rowcnd, colcnd, amax, info);
00275     }
00276 
00280     static void laqgs_loc(SLUD::SuperMatrix* A, double* r, double* c, 
00281         double rowcnd, double colcnd, double amax,
00282         SLUD::DiagScale_t* equed)
00283     {
00284       char eq = AMESOS2_SLUD_GET_EQUED(*equed);
00285       SLUD::D::pdlaqgs(A, r, c, rowcnd, colcnd, amax, &eq);
00286       *equed = AMESOS2_SLUD_GET_DIAG_SCALE(eq);
00287     }
00288 
00302     static void laqgs(SLUD::SuperMatrix* A, double* r, double* c, 
00303           double rowcnd, double colcnd, double amax, SLUD::DiagScale_t* equed)
00304     {
00305       char eq = AMESOS2_SLUD_GET_EQUED(*equed);
00306       SLUD::D::dlaqgs_dist(A, r, c, rowcnd, colcnd, amax, &eq);
00307       *equed = AMESOS2_SLUD_GET_DIAG_SCALE(eq);
00308     }
00309 
00310     /*
00311      * This version suitable for A in NCPformat
00312      */
00313     static void distribute(SLUD::fact_t fact, SLUD::int_t n,
00314          SLUD::SuperMatrix* A, SLUD::Glu_freeable_t* glu_freeable,
00315          type_map::LUstruct_t* lu, SLUD::gridinfo_t* grid)
00316     {
00317       SLUD::D::ddistribute(fact, n, A, glu_freeable, lu, grid);
00318     }
00319 
00320     /*
00321      * This version suitable for A in NR_loc format.
00322      *
00323      * This routine should be used in the case where fact ==
00324      * SamePattern_SameRowPerm, otherwise dist_psymbtonum should be
00325      * called.o
00326      */
00327     static void pdistribute(SLUD::fact_t fact, SLUD::int_t n, 
00328           SLUD::SuperMatrix* A, SLUD::ScalePermstruct_t* scale_perm, 
00329           SLUD::Glu_freeable_t* glu_freeable, type_map::LUstruct_t* lu,
00330           SLUD::gridinfo_t* grid)
00331     {
00332       SLUD::D::pddistribute(fact, n, A, scale_perm, glu_freeable, lu, grid);
00333     }
00334 
00335     /*
00336      * Distributes the input matrix A onto the 2D process grid based on
00337      * the L/U graph data in pslu_freeable.  On exit the struct lu
00338      * contains the information necessary to perform a numeric
00339      * factorization using gstrf.
00340      *
00341      * This routine should always be called with fact == DOFACT
00342      */
00343     static void dist_psymbtonum(SLUD::fact_t fact, SLUD::int_t n, SLUD::SuperMatrix* A,
00344         SLUD::ScalePermstruct_t* scale_perm,
00345         SLUD::Pslu_freeable_t* pslu_freeable,
00346         type_map::LUstruct_t* lu, SLUD::gridinfo_t* grid)
00347     {
00348       SLUD::D::ddist_psymbtonum(fact, n, A, scale_perm, pslu_freeable, lu, grid);
00349     }
00350 
00351     /*
00352      * The parameter norm may be one of:
00353      *  - 'M' for the max absolute matrix entry value
00354      *  - '1' for the norm1(A)
00355      *  - 'I' for the normI(A)
00356      *  - 'F' for the Frobenius norm of A
00357      */
00358     static double plangs(char* norm, SLUD::SuperMatrix* A, SLUD::gridinfo_t* grid)
00359     {
00360       return SLUD::D::pdlangs(norm, A, grid);
00361     }
00362 
00363     static void SolveInit(SLUD::superlu_options_t* options, SLUD::SuperMatrix* A, 
00364         SLUD::int_t* perm_r, SLUD::int_t* perm_c, SLUD::int_t nrhs, 
00365         type_map::LUstruct_t* lu, SLUD::gridinfo_t* grid, 
00366         type_map::SOLVEstruct_t* solve_struct)
00367     {
00368       SLUD::D::dSolveInit(options, A, perm_r, perm_c, nrhs, lu, grid, solve_struct);
00369     }
00370 
00371     static void LUstructInit(SLUD::int_t m, SLUD::int_t n,
00372            type_map::LUstruct_t* lu)
00373     {
00374       SLUD::D::LUstructInit(m, n, lu);
00375     }
00376 
00377     static void Destroy_LU(SLUD::int_t m, SLUD::gridinfo_t* grid,
00378          type_map::LUstruct_t* lu)
00379     {
00380       SLUD::D::Destroy_LU(m, grid, lu);
00381     }
00382 
00383     static void LUstructFree(type_map::LUstruct_t* lu)
00384     {
00385       SLUD::D::LUstructFree(lu);
00386     }
00387 
00388     static void SolveFinalize(SLUD::superlu_options_t* options,
00389             type_map::SOLVEstruct_t* solve_struct)
00390     {
00391       SLUD::D::dSolveFinalize(options, solve_struct);
00392     }
00393   };
00394 
00395 
00396 #ifdef HAVE_TEUCHOS_COMPLEX
00397   /* The specializations for Teuchos::as<> for SLUD::complex and
00398    * SLUD::doublecomplex are provided in Amesos2_Superlu_Type.hpp
00399    */
00400   template <>
00401   struct FunctionMap<Superludist,SLUD::Z::doublecomplex>
00402   {
00403     typedef TypeMap<Superludist,std::complex<double> > type_map;
00404 
00405     static void gstrf(SLUD::superlu_options_t* options, int m, int n, double anorm, 
00406           type_map::LUstruct_t* LU, SLUD::gridinfo_t* grid,
00407           SLUD::SuperLUStat_t* stat, int* info)
00408     {
00409       SLUD::Z::pzgstrf(options, m, n, anorm, LU, grid, stat, info);
00410     }
00411 
00412     static void gstrs(SLUD::int_t n, type_map::LUstruct_t* lu_struct,
00413           SLUD::ScalePermstruct_t* scale_perm_struct,
00414           SLUD::gridinfo_t* grid, type_map::type* B,
00415           SLUD::int_t l_numrows, SLUD::int_t fst_global_row,
00416           SLUD::int_t ldb, int nrhs,
00417           type_map::SOLVEstruct_t* solve_struct,
00418           SLUD::SuperLUStat_t* stat, int* info)
00419     {
00420       SLUD::Z::pzgstrs(n, lu_struct, scale_perm_struct, grid, B, l_numrows,
00421            fst_global_row, ldb, nrhs, solve_struct, stat, info);
00422     }
00423 
00424     static void gstrs_Bglobal(SLUD::int_t n, type_map::LUstruct_t* lu_struct, 
00425             SLUD::gridinfo_t* grid, type_map::type* B, 
00426             SLUD::int_t ldb, int nrhs, SLUD::SuperLUStat_t* stat, int* info)
00427     {
00428       SLUD::Z::pzgstrs_Bglobal(n, lu_struct, grid, B, ldb, nrhs, stat, info);
00429     }
00430   
00431     static void create_CompRowLoc_Matrix(SLUD::SuperMatrix* A, SLUD::int_t g_numrows,
00432            SLUD::int_t g_numcols, SLUD::int_t l_nnz,
00433            SLUD::int_t l_numrows, SLUD::int_t fst_global_row,
00434            type_map::type* nzval, SLUD::int_t* colind,
00435            SLUD::int_t* rowptr, SLUD::Stype_t storage_t,
00436            SLUD::Dtype_t data_t, SLUD::Mtype_t mat_t)
00437     {
00438       SLUD::Z::zCreate_CompRowLoc_Matrix_dist(A, g_numrows, g_numcols, l_nnz, 
00439                 l_numrows, fst_global_row,
00440                 nzval, colind, rowptr,
00441                 storage_t, data_t, mat_t);
00442     }
00443 
00444     static void create_CompCol_Matrix(SLUD::SuperMatrix* A, SLUD::int_t numrows,
00445               SLUD::int_t numcols, SLUD::int_t nnz,
00446               type_map::type* nzval, SLUD::int_t* rowind,
00447               SLUD::int_t* colptr, SLUD::Stype_t storage_t,
00448               SLUD::Dtype_t data_t, SLUD::Mtype_t mat_t)
00449     {
00450       SLUD::Z::zCreate_CompCol_Matrix_dist(A, numrows, numcols, nnz, 
00451              nzval, rowind, colptr,
00452              storage_t, data_t, mat_t);
00453     }
00454 
00455     static void create_Dense_Matrix(SLUD::SuperMatrix* X, int m, int n,
00456             TypeMap<Superludist,std::complex<double> >::type* x, int ldx, 
00457             SLUD::Stype_t stype, SLUD::Dtype_t dtype, SLUD::Mtype_t mtype)
00458     {
00459       SLUD::Z::zCreate_Dense_Matrix_dist(X, m, n, x, ldx, stype, dtype, mtype);
00460     }
00461 
00462     static void permute_Dense_Matrix(SLUD::int_t fst_row, SLUD::int_t m_loc,
00463              SLUD::int_t* row_to_proc, SLUD::int_t* perm,
00464              type_map::type* X, int ldx,
00465              type_map::type* B, int ldb,
00466              int nrhs, SLUD::gridinfo_t* grid)
00467     {
00468       SLUD::Z::pzPermute_Dense_Matrix(fst_row, m_loc, row_to_proc, perm,
00469               X, ldx, B, ldb, nrhs, grid);
00470     }
00471   
00472     static void gsequ_loc(SLUD::SuperMatrix* A, double* r, double* c, 
00473         double* rowcnd, double* colcnd, double* amax, int* info, 
00474         SLUD::gridinfo_t* grid)
00475     {
00476       SLUD::Z::pzgsequ(A, r, c, rowcnd, colcnd, amax, info, grid);
00477     }
00478 
00479     static void gsequ(SLUD::SuperMatrix* A, double* r, double* c, 
00480           double* rowcnd, double* colcnd, double* amax, int* info)
00481     {
00482       SLUD::Z::zgsequ_dist(A, r, c, rowcnd, colcnd, amax, info);
00483     }
00484 
00485     static void laqgs_loc(SLUD::SuperMatrix* A, double* r, double* c, 
00486         double rowcnd, double colcnd, double amax, SLUD::DiagScale_t* equed)
00487     {
00488       char eq = AMESOS2_SLUD_GET_EQUED(*equed);
00489       SLUD::Z::pzlaqgs(A, r, c, rowcnd, colcnd, amax, &eq);
00490       *equed = AMESOS2_SLUD_GET_DIAG_SCALE(eq);
00491     }
00492 
00493     static void laqgs(SLUD::SuperMatrix* A, double* r, double* c, 
00494           double rowcnd, double colcnd, double amax, SLUD::DiagScale_t* equed)
00495     {
00496       char eq = AMESOS2_SLUD_GET_EQUED(*equed);
00497       SLUD::Z::zlaqgs_dist(A, r, c, rowcnd, colcnd, amax, &eq);
00498       *equed = AMESOS2_SLUD_GET_DIAG_SCALE(eq);
00499     }
00500 
00501     static void distribute(SLUD::fact_t fact, SLUD::int_t n,
00502          SLUD::SuperMatrix* A, SLUD::Glu_freeable_t* glu_freeable,
00503          type_map::LUstruct_t* lu, SLUD::gridinfo_t* grid)
00504     {
00505       SLUD::Z::zdistribute(fact, n, A, glu_freeable, lu, grid);
00506     }
00507 
00508     static void pdistribute(SLUD::fact_t fact, SLUD::int_t n, 
00509           SLUD::SuperMatrix* A, SLUD::ScalePermstruct_t* scale_perm, 
00510           SLUD::Glu_freeable_t* glu_freeable, type_map::LUstruct_t* lu,
00511           SLUD::gridinfo_t* grid)
00512     {
00513       SLUD::Z::pzdistribute(fact, n, A, scale_perm, glu_freeable, lu, grid);
00514     }
00515 
00516     static void dist_psymbtonum(SLUD::fact_t fact, SLUD::int_t n,
00517         SLUD::SuperMatrix* A, SLUD::ScalePermstruct_t* scale_perm, 
00518         SLUD::Pslu_freeable_t* pslu_freeable, type_map::LUstruct_t* lu,
00519         SLUD::gridinfo_t* grid)
00520     {
00521       SLUD::Z::zdist_psymbtonum(fact, n, A, scale_perm, pslu_freeable, lu, grid);
00522     }
00523 
00524     static double plangs(char* norm, SLUD::SuperMatrix* A, SLUD::gridinfo_t* grid)
00525     {
00526       return SLUD::Z::pzlangs(norm, A, grid);
00527     }
00528 
00529     static void SolveInit(SLUD::superlu_options_t* options, SLUD::SuperMatrix* A,
00530         SLUD::int_t* perm_r, SLUD::int_t* perm_c, SLUD::int_t nrhs,
00531         type_map::LUstruct_t* lu, SLUD::gridinfo_t* grid, 
00532         type_map::SOLVEstruct_t* solve_struct)
00533     {
00534       SLUD::Z::zSolveInit(options, A, perm_r, perm_c, nrhs, lu, grid, solve_struct);
00535     }
00536 
00537     static void LUstructInit(SLUD::int_t m, SLUD::int_t n, type_map::LUstruct_t* lu)
00538     {
00539       SLUD::Z::LUstructInit(m, n, lu);
00540     }
00541 
00542     static void Destroy_LU(SLUD::int_t m, SLUD::gridinfo_t* grid, type_map::LUstruct_t* lu)
00543     {
00544       SLUD::Z::Destroy_LU(m, grid, lu);
00545     }
00546 
00547     static void LUstructFree(type_map::LUstruct_t* lu)
00548     {
00549       SLUD::Z::LUstructFree(lu);
00550     }
00551 
00552     static void SolveFinalize(SLUD::superlu_options_t* options,
00553             type_map::SOLVEstruct_t* solve_struct)
00554     {
00555       SLUD::Z::zSolveFinalize(options, solve_struct);
00556     }
00557   };
00558 #endif  // HAVE_TEUCHOS_COMPLEX
00559 
00560 } // end namespace Amesos2
00561 
00562 
00563 #endif  // AMESOS2_SUPERLUDIST_FUNCTIONMAP_HPP