37 #if defined(GMM_USES_SUPERLU)
39 #ifndef GMM_SUPERLU_INTERFACE_H
40 #define GMM_SUPERLU_INTERFACE_H
58 #if defined(GMM_NO_SUPERLU_INCLUDE_SUBDIR)
60 #include "slu_Cnames.h"
61 #include "supermatrix.h"
65 #include "slu_sdefs.h"
68 #include "slu_ddefs.h"
71 #include "slu_cdefs.h"
74 #include "slu_zdefs.h"
79 #include "superlu/slu_Cnames.h"
80 #include "superlu/supermatrix.h"
81 #include "superlu/slu_util.h"
84 #include "superlu/slu_sdefs.h"
87 #include "superlu/slu_ddefs.h"
90 #include "superlu/slu_cdefs.h"
93 #include "superlu/slu_zdefs.h"
98 #if (SUPERLU_MAJOR_VERSION > 6)
99 # define SuperLuComplexFloat SuperLU_C::singlecomplex
101 # define SuperLuComplexFloat SuperLU_C::complex
108 inline void Create_CompCol_Matrix(SuperMatrix *A,
int m,
int n,
int nnz,
109 float *a,
int *ir,
int *jc) {
110 SuperLU_S::sCreate_CompCol_Matrix(A, m, n, nnz, a, ir, jc,
111 SLU_NC, SLU_S, SLU_GE);
114 inline void Create_CompCol_Matrix(SuperMatrix *A,
int m,
int n,
int nnz,
115 double *a,
int *ir,
int *jc) {
116 SuperLU_D::dCreate_CompCol_Matrix(A, m, n, nnz, a, ir, jc,
117 SLU_NC, SLU_D, SLU_GE);
120 inline void Create_CompCol_Matrix(SuperMatrix *A,
int m,
int n,
int nnz,
121 std::complex<float> *a,
int *ir,
int *jc) {
122 SuperLU_C::cCreate_CompCol_Matrix(A, m, n, nnz, (SuperLuComplexFloat *)(a),
123 ir, jc, SLU_NC, SLU_C, SLU_GE);
126 inline void Create_CompCol_Matrix(SuperMatrix *A,
int m,
int n,
int nnz,
127 std::complex<double> *a,
int *ir,
int *jc) {
128 SuperLU_Z::zCreate_CompCol_Matrix(A, m, n, nnz,
129 (SuperLU_Z::doublecomplex *)(a), ir, jc,
130 SLU_NC, SLU_Z, SLU_GE);
135 inline void Create_Dense_Matrix(SuperMatrix *A,
int m,
int n,
float *a,
int k)
136 { SuperLU_S::sCreate_Dense_Matrix(A, m, n, a, k, SLU_DN, SLU_S, SLU_GE); }
137 inline void Create_Dense_Matrix(SuperMatrix *A,
int m,
int n,
double *a,
139 { SuperLU_D::dCreate_Dense_Matrix(A, m, n, a, k, SLU_DN, SLU_D, SLU_GE); }
140 inline void Create_Dense_Matrix(SuperMatrix *A,
int m,
int n,
141 std::complex<float> *a,
int k) {
142 SuperLU_C::cCreate_Dense_Matrix(A, m, n, (SuperLuComplexFloat *)(a),
143 k, SLU_DN, SLU_C, SLU_GE);
145 inline void Create_Dense_Matrix(SuperMatrix *A,
int m,
int n,
146 std::complex<double> *a,
int k) {
147 SuperLU_Z::zCreate_Dense_Matrix(A, m, n, (SuperLU_Z::doublecomplex *)(a),
148 k, SLU_DN, SLU_Z, SLU_GE);
153 #define DECL_GSSV(NAMESPACE,FNAME,KEYTYPE) \
154 inline void SuperLU_gssv(superlu_options_t *options, SuperMatrix *A, int *p, \
155 int *q, SuperMatrix *L, SuperMatrix *U, SuperMatrix *B, \
156 SuperLUStat_t *stats, int *info, KEYTYPE) { \
157 NAMESPACE::FNAME(options, A, p, q, L, U, B, stats, info); \
160 DECL_GSSV(SuperLU_S,sgssv,
float)
161 DECL_GSSV(SuperLU_C,cgssv, std::complex<float>)
162 DECL_GSSV(SuperLU_D,dgssv,
double)
163 DECL_GSSV(SuperLU_Z,zgssv, std::complex<double>)
167 #define DECL_GSSVX(NAMESPACE,FNAME,FLOATTYPE,KEYTYPE) \
168 inline float SuperLU_gssvx(superlu_options_t *options, SuperMatrix *A, \
169 int *perm_c, int *perm_r, int *etree, \
171 FLOATTYPE *R, FLOATTYPE *C, SuperMatrix *L, \
172 SuperMatrix *U, void *work, int lwork, \
173 SuperMatrix *B, SuperMatrix *X, \
174 FLOATTYPE *recip_pivot_growth, \
175 FLOATTYPE *rcond, FLOATTYPE *ferr, \
177 SuperLUStat_t *stats, int *info, KEYTYPE) { \
178 mem_usage_t mem_usage; \
180 NAMESPACE::FNAME(options, A, perm_c, perm_r, etree, equed, R, C, L, \
181 U, work, lwork, B, X, recip_pivot_growth, rcond, \
182 ferr, berr, &Glu, &mem_usage, stats, info); \
183 return mem_usage.for_lu; \
186 DECL_GSSVX(SuperLU_S, sgssvx,
float,
float)
187 DECL_GSSVX(SuperLU_C, cgssvx,
float, std::complex<float>)
188 DECL_GSSVX(SuperLU_D, dgssvx,
double,
double)
189 DECL_GSSVX(SuperLU_Z, zgssvx,
double, std::complex<double>)
195 template <
typename MAT,
typename VECTX,
typename VECTB>
196 int SuperLU_solve(
const MAT &A,
const VECTX &X,
const VECTB &B,
197 double& rcond_,
int permc_spec = 3) {
205 typedef typename linalg_traits<MAT>::value_type T;
206 typedef typename number_traits<T>::magnitude_type R;
208 int m = int(mat_nrows(A)), n = int(mat_ncols(A)), nrhs = 1, info = 0;
210 csc_matrix<T> csc_A(m, n);
212 std::vector<T> rhs(m), sol(m);
215 int nz = int(
nnz(csc_A));
216 if ((2 * nz / n) >= m)
217 GMM_WARNING2(
"CAUTION : it seems that SuperLU has a problem"
218 " for nearly dense sparse matrices");
220 superlu_options_t options;
221 set_default_options(&options);
222 options.ColPerm = NATURAL;
223 options.PrintStat = NO;
224 options.ConditionNumber = YES;
225 switch (permc_spec) {
226 case 1 : options.ColPerm = MMD_ATA;
break;
227 case 2 : options.ColPerm = MMD_AT_PLUS_A;
break;
228 case 3 : options.ColPerm = COLAMD;
break;
233 SuperMatrix SA, SL, SU, SB, SX;
234 Create_CompCol_Matrix(&SA, m, n, nz, (T *)(&csc_A.pr[0]),
235 (
int *)(&csc_A.ir[0]),
236 (
int *)(&csc_A.jc[0]));
237 Create_Dense_Matrix(&SB, m, nrhs, &rhs[0], m);
238 Create_Dense_Matrix(&SX, m, nrhs, &sol[0], m);
239 memset(&SL,0,
sizeof SL);
240 memset(&SU,0,
sizeof SU);
242 std::vector<int> etree(n);
244 std::vector<R> Rscale(m),Cscale(n);
245 std::vector<R> ferr(nrhs), berr(nrhs);
246 R recip_pivot_gross, rcond;
247 std::vector<int> perm_r(m), perm_c(n);
249 SuperLU_gssvx(&options, &SA, &perm_c[0], &perm_r[0],
265 if (SB.Store) Destroy_SuperMatrix_Store(&SB);
266 if (SX.Store) Destroy_SuperMatrix_Store(&SX);
267 if (SA.Store) Destroy_SuperMatrix_Store(&SA);
268 if (SL.Store) Destroy_SuperNode_Matrix(&SL);
269 if (SU.Store) Destroy_CompCol_Matrix(&SU);
271 GMM_ASSERT1(info != -333333333,
"SuperLU was cancelled.");
273 GMM_ASSERT1(info >= 0,
"SuperLU solve failed: info =" << info);
274 if (info > 0) GMM_WARNING1(
"SuperLU solve failed: info =" << info);
280 class SuperLU_factor {
281 typedef typename number_traits<T>::magnitude_type R;
284 mutable SuperMatrix SA, SL, SB, SU, SX;
285 mutable SuperLUStat_t stat;
286 mutable superlu_options_t options;
288 mutable std::vector<int> etree, perm_r, perm_c;
289 mutable std::vector<R> Rscale, Cscale;
290 mutable std::vector<R> ferr, berr;
291 mutable std::vector<T> rhs;
292 mutable std::vector<T> sol;
293 mutable bool is_init;
297 enum { LU_NOTRANSP, LU_TRANSP, LU_CONJUGATED };
298 void free_supermatrix() {
300 if (SB.Store) Destroy_SuperMatrix_Store(&SB);
301 if (SX.Store) Destroy_SuperMatrix_Store(&SX);
302 if (SA.Store) Destroy_SuperMatrix_Store(&SA);
303 if (SL.Store) Destroy_SuperNode_Matrix(&SL);
304 if (SU.Store) Destroy_CompCol_Matrix(&SU);
307 template <
class MAT>
void build_with(
const MAT &A,
int permc_spec = 3);
308 template <
typename VECTX,
typename VECTB>
312 void solve(
const VECTX &X_,
const VECTB &B,
int transp=LU_NOTRANSP)
const;
313 SuperLU_factor() { is_init =
false; }
314 SuperLU_factor(
const SuperLU_factor& other) {
315 GMM_ASSERT2(!(other.is_init),
316 "copy of initialized SuperLU_factor is forbidden");
319 SuperLU_factor& operator=(
const SuperLU_factor& other) {
320 GMM_ASSERT2(!(other.is_init) && !is_init,
321 "assignment of initialized SuperLU_factor is forbidden");
324 ~SuperLU_factor() { free_supermatrix(); }
325 float memsize() {
return memory_used; }
329 template <
class T>
template <
class MAT>
330 void SuperLU_factor<T>::build_with(
const MAT &A,
int permc_spec) {
339 int n = int(mat_nrows(A)), m = int(mat_ncols(A)), info = 0;
342 rhs.resize(m); sol.resize(m);
344 int nz = int(
nnz(csc_A));
346 set_default_options(&options);
347 options.ColPerm = NATURAL;
348 options.PrintStat = NO;
349 options.ConditionNumber = NO;
350 switch (permc_spec) {
351 case 1 : options.ColPerm = MMD_ATA;
break;
352 case 2 : options.ColPerm = MMD_AT_PLUS_A;
break;
353 case 3 : options.ColPerm = COLAMD;
break;
357 Create_CompCol_Matrix(&SA, m, n, nz, (T *)(&csc_A.pr[0]),
358 (
int *)(&csc_A.ir[0]),
359 (
int *)(&csc_A.jc[0]));
360 Create_Dense_Matrix(&SB, m, 0, &rhs[0], m);
361 Create_Dense_Matrix(&SX, m, 0, &sol[0], m);
362 memset(&SL,0,
sizeof SL);
363 memset(&SU,0,
sizeof SU);
365 Rscale.resize(m); Cscale.resize(n); etree.resize(n);
366 ferr.resize(1); berr.resize(1);
367 R recip_pivot_gross, rcond;
368 perm_r.resize(m); perm_c.resize(n);
369 memory_used = SuperLU_gssvx(&options, &SA, &perm_c[0], &perm_r[0],
386 Destroy_SuperMatrix_Store(&SB);
387 Destroy_SuperMatrix_Store(&SX);
388 Create_Dense_Matrix(&SB, m, 1, &rhs[0], m);
389 Create_Dense_Matrix(&SX, m, 1, &sol[0], m);
392 GMM_ASSERT1(info != -333333333,
"SuperLU was cancelled.");
393 GMM_ASSERT1(info == 0,
"SuperLU solve failed: info=" << info);
397 template <
class T>
template <
typename VECTX,
typename VECTB>
398 void SuperLU_factor<T>::solve(
const VECTX &X,
const VECTB &B,
401 options.Fact = FACTORED;
402 options.IterRefine = NOREFINE;
404 case LU_NOTRANSP: options.Trans = NOTRANS;
break;
405 case LU_TRANSP: options.Trans = TRANS;
break;
406 case LU_CONJUGATED: options.Trans = CONJ;
break;
407 default: GMM_ASSERT1(
false,
"invalid value for transposition option");
411 R recip_pivot_gross, rcond;
412 SuperLU_gssvx(&options, &SA, &perm_c[0], &perm_r[0],
428 GMM_ASSERT1(info == 0,
"SuperLU solve failed: info=" << info);
432 template <
typename T,
typename V1,
typename V2>
inline
433 void mult(
const SuperLU_factor<T>& P,
const V1 &v1,
const V2 &v2) {
437 template <
typename T,
typename V1,
typename V2>
inline
438 void transposed_mult(
const SuperLU_factor<T>& P,
const V1 &v1,
const V2 &v2) {
439 P.solve(v2, v1, SuperLU_factor<T>::LU_TRANSP);
size_type nnz(const L &l)
count the number of non-zero entries of a vector or matrix.
void copy(const L1 &l1, L2 &l2)
*/
void clear(L &l)
clear (fill with zeros) a vector or matrix.
void mult(const L1 &l1, const L2 &l2, L3 &l3)
*/
Include the base gmm files.