LCOV - code coverage report
Current view: top level - /builds/ug4-project/ugcore/ug4-new/plugins/SuperLU6 - super_lu.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 86 0
Test Date: 2026-06-01 23:54:59 Functions: 0.0 % 9 0

            Line data    Source code
       1              : /*
       2              :  * Copyright (c) 2014:  G-CSC, Goethe University Frankfurt
       3              :  * Author: Martin Rupp
       4              :  * 
       5              :  * This file is part of UG4.
       6              :  * 
       7              :  * UG4 is free software: you can redistribute it and/or modify it under the
       8              :  * terms of the GNU Lesser General Public License version 3 (as published by the
       9              :  * Free Software Foundation) with the following additional attribution
      10              :  * requirements (according to LGPL/GPL v3 §7):
      11              :  * 
      12              :  * (1) The following notice must be displayed in the Appropriate Legal Notices
      13              :  * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
      14              :  * 
      15              :  * (2) The following notice must be displayed at a prominent place in the
      16              :  * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
      17              :  * 
      18              :  * (3) The following bibliography is recommended for citation and must be
      19              :  * preserved in all covered files:
      20              :  * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
      21              :  *   parallel geometric multigrid solver on hierarchically distributed grids.
      22              :  *   Computing and visualization in science 16, 4 (2013), 151-164"
      23              :  * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
      24              :  *   flexible software system for simulating pde based models on high performance
      25              :  *   computers. Computing and visualization in science 16, 4 (2013), 165-179"
      26              :  * 
      27              :  * This program is distributed in the hope that it will be useful,
      28              :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      29              :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
      30              :  * GNU Lesser General Public License for more details.
      31              :  */
      32              : 
      33              : #include "super_lu.h"
      34              : 
      35              : // fix warning
      36              : #undef TRUE
      37              : #undef FALSE
      38              : #include "slu_ddefs.h"
      39              : 
      40              : namespace ug{
      41              : 
      42              : 
      43              : class SuperLUImplementation : public IExternalSolverImplementation
      44              : {
      45              :         bool m_bInited;
      46              :         std::vector<double> rhs, nzval;
      47              :         /* row permutations from partial pivoting */
      48              :         /* column permutation vector */
      49              :         std::vector<int> perm_r, perm_c, colind, rowptr;
      50              : 
      51              :         SuperMatrix SuperLU_A, SuperLU_L, SuperLU_U, SuperLU_B;
      52              : 
      53              :         SuperLUConfiguration &config;
      54              : 
      55              :         superlu_options_t options;
      56              :         trans_t  trans;
      57              : 
      58              : 
      59              : public:
      60              :         SuperLUImplementation(SuperLUConfiguration &_config)
      61            0 :         : m_bInited(false), config(_config),
      62            0 :           trans(NOTRANS)
      63              :         {
      64            0 :                 SuperLU_A.Store = NULL;
      65              :         }
      66              : 
      67            0 :         ~SuperLUImplementation()
      68            0 :         {
      69            0 :                 destroy();
      70            0 :         }
      71              : 
      72            0 :         void destroy()
      73              :         {
      74            0 :                 if(m_bInited)
      75              :                 {
      76              :                         // DO NOT destroy SuperLU_A and AA since we supplied all pointers!!!
      77            0 :                         Destroy_SuperMatrix_Store(&SuperLU_B);
      78              :                         memset(&SuperLU_B, 0, sizeof(SuperMatrix));
      79            0 :                         Destroy_SuperNode_Matrix(&SuperLU_L);
      80              :                         memset(&SuperLU_L, 0, sizeof(SuperMatrix));
      81            0 :                         Destroy_CompCol_Matrix(&SuperLU_U);
      82              :                         memset(&SuperLU_U, 0, sizeof(SuperMatrix));
      83              : 
      84            0 :                         if (SuperLU_A.Store)
      85            0 :                                 SUPERLU_FREE(SuperLU_A.Store);
      86              : 
      87            0 :                         m_bInited = false;
      88              :                 }
      89            0 :         }
      90              : 
      91              :         void get_options(superlu_options_t& opt)
      92              :         {
      93              :                 //opt.PrintStat = config.bPrintStat ? YES : NO;
      94            0 :                 opt.Equil = config.equil ? YES : NO;
      95            0 :                 switch(config.colPerm)
      96              :                 {
      97            0 :                 case SuperLUConfiguration::CPT_NATURAL: opt.ColPerm = NATURAL; break;
      98            0 :                 case SuperLUConfiguration::CPT_MMD_ATA: opt.ColPerm = MMD_ATA; break;
      99            0 :                 case SuperLUConfiguration::CPT_MMD_AT_PLUS_A: opt.ColPerm = MMD_AT_PLUS_A; break;
     100            0 :                 case SuperLUConfiguration::CPT_COLAMD: opt.ColPerm = COLAMD; break;
     101              :                 }
     102              :         }
     103              : 
     104              :         void
     105            0 :         dgssvA(superlu_options_t *options, SuperMatrix *A, int *perm_c, int *perm_r,
     106              :               SuperMatrix *L, SuperMatrix *U, SuperMatrix *B,
     107              :               SuperLUStat_t *stat, int *info )
     108              :         {
     109              :                 //DNformat *Bstore;
     110              : 
     111              :                 int      lwork = 0;
     112              : 
     113              :                 /* Set default values for some parameters */
     114              :                 int      panel_size;     /* panel size */
     115              :                 int      relax;          /* no of columns in a relaxed snodes */
     116              :                 int      permc_spec;
     117            0 :                 trans = NOTRANS;
     118              : 
     119              : 
     120              :                 /* Convert A to SLU_NC format when necessary. */
     121              :                 SuperMatrix* AA = NULL; // A in SLU_NC format used by the factorization routine.
     122              :                 bool bAANeedsFree = false;
     123            0 :                 if ( A->Stype == SLU_NR ) {
     124            0 :                         NRformat *Astore = (NRformat*) A->Store;
     125            0 :                         AA = (SuperMatrix*) SUPERLU_MALLOC(sizeof(SuperMatrix));
     126            0 :                         dCreate_CompCol_Matrix(AA, A->ncol, A->nrow, Astore->nnz,
     127            0 :                                         (double*) Astore->nzval, Astore->colind, Astore->rowptr,
     128              :                                         SLU_NC, A->Dtype, A->Mtype);
     129            0 :                         trans = TRANS;
     130              :                         bAANeedsFree = true;
     131              :                 } else {
     132            0 :                         if ( A->Stype == SLU_NC ) AA = A;
     133              :                 }
     134              : 
     135              :                 /*
     136              :                  * Get column permutation vector perm_c[], according to permc_spec:
     137              :                  *   permc_spec = NATURAL:  natural ordering
     138              :                  *   permc_spec = MMD_AT_PLUS_A: minimum degree on structure of A'+A
     139              :                  *   permc_spec = MMD_ATA:  minimum degree on structure of A'*A
     140              :                  *   permc_spec = COLAMD:   approximate minimum degree column ordering
     141              :                  *   permc_spec = MY_PERMC: the ordering already supplied in perm_c[]
     142              :                  */
     143            0 :                 permc_spec = options->ColPerm;
     144            0 :                 if ( permc_spec != MY_PERMC && options->Fact == DOFACT )
     145            0 :                         get_perm_c(permc_spec, AA, perm_c);
     146              : 
     147              : 
     148            0 :                 int* etree = intMalloc(A->ncol);
     149              : 
     150              :                 SuperMatrix AC; /* Matrix postmultiplied by Pc */
     151            0 :                 sp_preorder(options, AA, perm_c, etree, &AC);
     152              : 
     153            0 :                 panel_size = sp_ienv(1);
     154            0 :                 relax = sp_ienv(2);
     155              : 
     156              :                 /* Compute the LU factorization of A. */
     157              : #ifdef SUPERLU_6_EXPERIMENTAL
     158              :         GlobalLU_t glu;
     159            0 :         dgstrf(options, &AC, relax, panel_size, etree,
     160              :                         NULL, lwork, perm_c, perm_r, L, U, &glu, stat, info);
     161              : #else 
     162              :         dgstrf(options, &AC, relax, panel_size, etree,
     163              :                         NULL, lwork, perm_c, perm_r, L, U, stat, info);
     164              : #endif
     165              : 
     166            0 :             Destroy_CompCol_Permuted(&AC);
     167            0 :             if (bAANeedsFree)
     168              :             {
     169            0 :                 SUPERLU_FREE(AA->Store);
     170            0 :                 SUPERLU_FREE(AA);
     171              :             }
     172            0 :                 SUPERLU_FREE(etree);
     173            0 :         }
     174              : 
     175              : 
     176              :         void
     177              :         dgssvB(superlu_options_t *options, SuperMatrix *A, int *perm_c, int *perm_r,
     178              :               SuperMatrix *L, SuperMatrix *U, SuperMatrix *B,
     179              :               SuperLUStat_t *stat, int *info )
     180              :         {
     181            0 :             dgstrs (trans, L, U, perm_c, perm_r, B, stat, info);
     182              :         }
     183              : 
     184              : 
     185              : 
     186            0 :         virtual bool init(const CPUAlgebra::matrix_type &A)
     187              :         {
     188            0 :                 destroy();
     189              :                 PROFILE_BEGIN_GROUP(SuperLU_Preprocess, "algebra SuperLU");
     190              :                 typedef CPUAlgebra::matrix_type::const_row_iterator row_it;
     191              :                 typedef CPUAlgebra::matrix_type::value_type value_type;
     192              : 
     193            0 :                 if( A.num_rows() == 0 || A.num_cols() == 0) return true;
     194              : 
     195              :                 size_t numRows, numCols;
     196            0 :                 A.copy_crs(numRows, numCols, nzval, rowptr, colind);
     197            0 :                 THROW_IF_NOT_EQUAL(numRows, numCols);
     198              :                 size_t N = numRows;
     199              :                 size_t nnz = nzval.size();
     200              :                 //if(N > 40000 && nnz > 400000) { UG_LOG("SuperLU preprocess, N = " << N << ", nnz = " << nnz << "... "); }
     201              : 
     202            0 :                 dCreate_CompRow_Matrix(&SuperLU_A, N, N, nnz, &nzval[0], &colind[0], &rowptr[0], SLU_NR, SLU_D, SLU_GE);
     203              : 
     204              :                 //rhs = doubleMalloc(N);
     205            0 :                 rhs.resize(N, 0.0);
     206            0 :                 dCreate_Dense_Matrix(&SuperLU_B, N, 1, &rhs[0], N, SLU_DN, SLU_D, SLU_GE);
     207              : 
     208            0 :                 perm_r.resize(N+1);
     209            0 :                 perm_c.resize(N+1);
     210              :                 /* Set the default input options. */
     211            0 :                 set_default_options(&options);
     212              : 
     213              :                 get_options(options);
     214              : 
     215              :                 SuperLUStat_t stat;
     216            0 :                 StatInit(&stat);
     217              :                 int info;
     218              : 
     219            0 :                 dgssvA(&options, &SuperLU_A, &perm_c[0], &perm_r[0], &SuperLU_L, &SuperLU_U, &SuperLU_B, &stat, &info);
     220              : 
     221              :                 /*
     222              :                 dgssv_check_info(info, N);
     223              :                 if(config.bPrintStat)
     224              :                         StatPrint(&stat);
     225              :                 */
     226            0 :                 StatFree(&stat);
     227              :                 //if(N > 40000 && nnz > 400000) { UG_LOG("done.\n"); }
     228            0 :                 m_bInited = true;
     229            0 :                 return true;
     230              :         }
     231              : 
     232            0 :         void dgssv_check_info(int info, size_t N)
     233              :         {
     234            0 :                 if(info > 0)
     235              :                 {
     236            0 :                         if(info < (int)N)
     237              :                         {
     238            0 :                                 UG_THROW("ERROR in SuperLU: U(i,i) with i=" << info << "is exactly zero. The factorization has\
     239              :                                                         been completed, but the factor U is exactly singular,\
     240              :                                                         so the solution could not be computed.");
     241              :                         }
     242              :                         else
     243            0 :                         { UG_THROW("ERROR in SuperLU: memory allocation failure");}
     244              :                 }
     245            0 :                 else if(info < 0)
     246              :                 {
     247            0 :                         UG_THROW("ERROR in SuperLU: info < 0 ???");
     248              :                 }
     249            0 :         }
     250              : 
     251            0 :         virtual bool apply(CPUAlgebra::vector_type &c, const CPUAlgebra::vector_type &d)
     252              :         {
     253              :                 PROFILE_BEGIN_GROUP(SuperLU_Apply, "algebra SuperLU");
     254              :                 size_t N = c.size();
     255            0 :                 if(N == 0) return true;
     256            0 :                 double *b = (double*) ((DNformat*) SuperLU_B.Store)->nzval;
     257              : 
     258            0 :                 for (size_t i = 0; i < N; ++i)
     259            0 :                         b[i] = d[i];
     260              : 
     261              :                 superlu_options_t options;
     262            0 :                 set_default_options(&options);
     263            0 :                 options.Fact = FACTORED;
     264              :                 int info;
     265              :                 SuperLUStat_t stat;
     266            0 :                 StatInit(&stat);
     267            0 :                 dgssvB(&options, &SuperLU_A, &perm_c[0], &perm_r[0], &SuperLU_L, &SuperLU_U, &SuperLU_B, &stat, &info);
     268            0 :                 StatFree(&stat);
     269            0 :                 dgssv_check_info(info, N);
     270              : 
     271            0 :                 for (size_t i = 0; i < N; ++i)
     272            0 :                         c[i] = b[i];
     273              : 
     274              :                 return true;
     275              :         }
     276              : 
     277            0 :         virtual const char* name() const { return "SuperLU"; }
     278              : };
     279              : 
     280              : 
     281            0 : IExternalSolverImplementation *CreateSuperLUImplementation(SuperLUConfiguration &config)
     282              : {
     283            0 :         return new SuperLUImplementation(config);
     284              : }
     285              : 
     286              : }
     287              : 
        

Generated by: LCOV version 2.0-1