TBCI Numerical high perf. C++ Library  2.8.0
superlu_d.cpp
Go to the documentation of this file.
1 
4 /* (w) Andreas Ahland */
5 /* $Id: superlu_d.cpp,v 1.4.2.16 2022/11/03 20:40:08 garloff Exp $ */
6 
7 #include "tbci/cscmatrix.h"
8 
9 #ifdef HAVE_SUPERLU3_INCLUDES
10 # include <superlu/slu_ddefs.h>
11 # include <superlu/supermatrix.h>
12 # include <superlu/slu_util.h>
13 #else
14 # include "tbci/superlu/util.h"
15 # include "tbci/superlu/dsp_defs.h"
16 #endif
17 
18 #if TBCI_NUMLIB_VERSION >= 20600
19 # define COLPERM_T_DECLARED
20 # include "tbci/solver/superlu.h"
21 #endif
22 
23 #ifdef HAVE_UNISTD_H
24 #include <unistd.h>
25 #endif
26 
28 
31  const Vector<double>& rhs,
32  colperm_t permc_spec,
33  bool verbose, bool symm)
34 {
35  int nrhs = 1;
36  int m = M.rows();
37  int n = M.columns();
38  int nnz = M.size();
39  double *a= M.dataPointer();
40  unsigned int *asub= M.rowIndexPointer();
41  unsigned int *xa = M.columnPointer();
42 
43  int *perm_r; /* row permutations from partial pivoting */
44  int *perm_c; /* column permutation vector */
45  SuperMatrix A;
46  SuperMatrix B;
47  SuperMatrix L; /* factor L */
48  SuperMatrix U; /* factor U */
49  int info;
50 
51 #ifdef HAVE_SUPERLU3_INCLUDES
52  superlu_options_t slu_opt;
53  SuperLUStat_t slu_stat;
54  set_default_options(&slu_opt);
55  slu_opt.ColPerm = permc_spec;
56  slu_opt.SymmetricMode = (yes_no_t)symm;
57  if (symm)
58  slu_opt.DiagPivotThresh = 0.1;
59  slu_opt.PrintStat = (yes_no_t)verbose;
60  StatInit(&slu_stat);
61 #elif defined(HAVE_UNISTD_H)
62  int savedstdout = 0;
63 #endif
64 
65  // Set up matrix structure
66  x = rhs;
67  dCreate_CompCol_Matrix(&A, m, n, nnz, a, (int*)asub, (int*)xa, SLU_NC, SLU_D, SLU_GE);
69  if ( !(perm_r = intMalloc(m)) )
70  ABORT("Malloc fails for perm_r[].");
71  if ( !(perm_c = intMalloc(n)) )
72  ABORT("Malloc fails for perm_c[].");
73 
74 #if defined(HAVE_UNISTD_H) && !defined(HAVE_SUPERLU3_INCLUDES)
75  // HACK: SuperLU is way too talkative. Shut it down ...
76  if (!verbose) {
77  savedstdout = dup(STDOUT_FILENO); close(STDOUT_FILENO);
78  }
79 #endif
80 #ifndef HAVE_SUPERLU3_INCLUDES
81  // Perform permutation
82  get_perm_c(permc_spec, &A, perm_c);
83 #endif
84 
85  // Solve
86 #ifdef HAVE_SUPERLU3_INCLUDES
87  dgssv(&slu_opt, &A, perm_c, perm_r, &L, &U, &B, &slu_stat, &info);
88  if (verbose)
89  StatPrint(&slu_stat);
90 #else
91  dgssv(&A, perm_c, perm_r, &L, &U, &B, &info);
92 #endif
93 #if defined(HAVE_UNISTD_H) && !defined(HAVE_SUPERLU3_INCLUDES)
94  // Restore stdout FD
95  if (!verbose) {
96  int newout = dup(savedstdout); close(savedstdout);
97  if (newout != STDOUT_FILENO)
98  fprintf(stderr, "Could not reopen stdout (%i)\n", newout);
99  }
100 #endif
101 
102  if (info != 0) {
103  fprintf(stderr, "SuperLU: dgssv() error returns INFO= %d\n", info);
104  if (info > n) {
105  /* We ran out of memory */
106  mem_usage_t mem_usage;
107 #ifdef HAVE_SUPERLU3_INCLUDES
108  dQuerySpace(&L, &U, &mem_usage);
109 #else
110  int panel_size = sp_ienv(1);
111  dQuerySpace(&L, &U, panel_size, &mem_usage);
112 #endif
113  fprintf(stderr, "SuperLU: Memory allocation of %i bytes failed!\n",
114  info - n);
115  fprintf(stderr, " L\\U MB %.3f\ttotal MB needed %.3f",
116  mem_usage.for_lu/1e6, mem_usage.total_needed/1e6);
117 #ifdef HAVE_MEM_USAGE_EXPANSIONS
118  fprintf(stderr, "\texpansions %d\n",
119  mem_usage.expansions);
120 #else
121  fprintf(stderr, "\n");
122 #endif
123  } else
124  fprintf(stderr, "SuperLU: Singular factor U(%i,%i) found!\n", info, info);
125  }
126 
127  SUPERLU_FREE(perm_r);
128  SUPERLU_FREE(perm_c);
131  // Huh, memleak :-O
134 #ifdef HAVE_SUPERLU3_INCLUDES
135  StatFree(&slu_stat);
136 #endif
137 
138  return info;
139 }
140 
141 #if TBCI_NUMLIB_VERSION < 20600
142 
147  const Vector<double>& rhs,
148  colperm_t permc_spec,
149  bool verbose, bool symm)
150 )
151 {
152  TVector<double> x(rhs.size());
153  const int info = lu_solve(M, (Vector<double>&)x, rhs, permc_spec, verbose, symm);
154  return x;
155 }
156 #endif
157 
void Destroy_SuperMatrix_Store(SuperMatrix *)
const Vector< T > const Vector< T > & x
Definition: LM_fit.h:97
int * intMalloc(int)
void StatInit(int, int)
#define NAMESPACE_TBCI
Definition: basics.h:317
float for_lu
Definition: csp_defs.h:119
F_TMatrix< double > lu_solve(const F_Matrix< double > &A, const F_Matrix< double > &B, int overwriteA=0)
Definition: lapack.cpp:156
unsigned int * columnPointer()
Definition: cscmatrix.h:130
#define SUPERLU_FREE(addr)
Definition: util.h:37
unsigned int rows() const
query matrix dimensions
Definition: cscmatrix.h:101
#define WEAK(x)
Definition: basics.h:485
unsigned int size() const
Definition: cscmatrix.h:103
void dgssv(SuperMatrix *, int *, int *, SuperMatrix *, SuperMatrix *, SuperMatrix *, int *)
enums and structs for the SuperMatrix being used in SuperLU
void dCreate_CompCol_Matrix(SuperMatrix *, int, int, int, double *, int *, int *, Stype_t, Dtype_t, Mtype_t)
colperm_t
get column permutation vector perm_c[], according to permc_spec: permc_spec = NATURAL(0): use the nat...
Definition: superlu.h:20
void dCreate_Dense_Matrix(SuperMatrix *, int, int, double *, int, Stype_t, Dtype_t, Mtype_t)
float total_needed
Definition: csp_defs.h:120
#define U
Definition: bdmatlib.cc:21
void Destroy_CompCol_Matrix(SuperMatrix *)
unsigned int * rowIndexPointer()
Definition: cscmatrix.h:131
void get_perm_c(int, SuperMatrix *, int *)
void Destroy_SuperNode_Matrix(SuperMatrix *)
int sp_ienv(int)
int expansions
Definition: csp_defs.h:121
int dQuerySpace(SuperMatrix *, SuperMatrix *, int, mem_usage_t *)
unsigned long size() const
Definition: vector.h:104
T *const & get_fortran_vector() const
Definition: bvector.h:164
exception class: Use MatErr from matrix.h
Definition: cscmatrix.h:49
Temporary Base Class Idiom: Class TVector is used for temporary variables.
Definition: bvector.h:52
#define ABORT(err_msg)
Definition: util.h:21
#define NAMESPACE_END
Definition: basics.h:323
Definition: bvector.h:54
T * dataPointer()
Definition: cscmatrix.h:129
const unsigned TMatrix< T > const Matrix< T > * a
unsigned int columns() const
Definition: cscmatrix.h:102
void StatFree()