xref: /petsc/src/mat/impls/aij/seq/essl/essl.c (revision 4dfa11a44d5adf2389f1d3acbc8f3c1116dc6c3a)
1e8aa55a4SKris Buschelman 
2e8aa55a4SKris Buschelman /*
3e8aa55a4SKris Buschelman         Provides an interface to the IBM RS6000 Essl sparse solver
4e8aa55a4SKris Buschelman 
5e8aa55a4SKris Buschelman */
6c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/aij.h>
7b24902e0SBarry Smith 
8e8aa55a4SKris Buschelman /* #include <essl.h> This doesn't work!  */
9e8aa55a4SKris Buschelman 
108cc058d9SJed Brown PETSC_EXTERN void dgss(int *, int *, double *, int *, int *, int *, double *, double *, int *);
118cc058d9SJed Brown PETSC_EXTERN void dgsf(int *, int *, int *, double *, int *, int *, int *, int *, double *, double *, double *, int *);
12d3bad8c4SBarry Smith 
13e8aa55a4SKris Buschelman typedef struct {
14e8aa55a4SKris Buschelman   int          n, nz;
15e8aa55a4SKris Buschelman   PetscScalar *a;
16e8aa55a4SKris Buschelman   int         *ia;
17e8aa55a4SKris Buschelman   int         *ja;
18e8aa55a4SKris Buschelman   int          lna;
19e8aa55a4SKris Buschelman   int          iparm[5];
20e8aa55a4SKris Buschelman   PetscReal    rparm[5];
21e8aa55a4SKris Buschelman   PetscReal    oparm[5];
22e8aa55a4SKris Buschelman   PetscScalar *aux;
23e8aa55a4SKris Buschelman   int          naux;
24e8aa55a4SKris Buschelman 
25ace3abfcSBarry Smith   PetscBool CleanUpESSL;
26f0c56d0fSKris Buschelman } Mat_Essl;
27f0c56d0fSKris Buschelman 
289371c9d4SSatish Balay PetscErrorCode MatDestroy_Essl(Mat A) {
29ac913495SBarry Smith   Mat_Essl *essl = (Mat_Essl *)A->data;
30e8aa55a4SKris Buschelman 
31e8aa55a4SKris Buschelman   PetscFunctionBegin;
321baa6e33SBarry Smith   if (essl->CleanUpESSL) PetscCall(PetscFree4(essl->a, essl->aux, essl->ia, essl->ja));
339566063dSJacob Faibussowitsch   PetscCall(PetscFree(A->data));
34460c4903SKris Buschelman   PetscFunctionReturn(0);
35460c4903SKris Buschelman }
36460c4903SKris Buschelman 
379371c9d4SSatish Balay PetscErrorCode MatSolve_Essl(Mat A, Vec b, Vec x) {
38ac913495SBarry Smith   Mat_Essl    *essl = (Mat_Essl *)A->data;
39e8aa55a4SKris Buschelman   PetscScalar *xx;
40c5c20521SJed Brown   int          nessl, zero = 0;
41e8aa55a4SKris Buschelman 
42e8aa55a4SKris Buschelman   PetscFunctionBegin;
439566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &nessl));
449566063dSJacob Faibussowitsch   PetscCall(VecCopy(b, x));
459566063dSJacob Faibussowitsch   PetscCall(VecGetArray(x, &xx));
46c5c20521SJed Brown   dgss(&zero, &nessl, essl->a, essl->ia, essl->ja, &essl->lna, xx, essl->aux, &essl->naux);
479566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(x, &xx));
48e8aa55a4SKris Buschelman   PetscFunctionReturn(0);
49e8aa55a4SKris Buschelman }
50e8aa55a4SKris Buschelman 
519371c9d4SSatish Balay PetscErrorCode MatLUFactorNumeric_Essl(Mat F, Mat A, const MatFactorInfo *info) {
52e8aa55a4SKris Buschelman   Mat_SeqAIJ *aa   = (Mat_SeqAIJ *)(A)->data;
53ac913495SBarry Smith   Mat_Essl   *essl = (Mat_Essl *)(F)->data;
54c5c20521SJed Brown   int         nessl, i, one = 1;
55e8aa55a4SKris Buschelman 
56e8aa55a4SKris Buschelman   PetscFunctionBegin;
579566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n, &nessl));
58e8aa55a4SKris Buschelman   /* copy matrix data into silly ESSL data structure (1-based Frotran style) */
59d0f46423SBarry Smith   for (i = 0; i < A->rmap->n + 1; i++) essl->ia[i] = aa->i[i] + 1;
60e8aa55a4SKris Buschelman   for (i = 0; i < aa->nz; i++) essl->ja[i] = aa->j[i] + 1;
61e8aa55a4SKris Buschelman 
629566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy(essl->a, aa->a, aa->nz));
63e8aa55a4SKris Buschelman 
64e8aa55a4SKris Buschelman   /* set Essl options */
65e8aa55a4SKris Buschelman   essl->iparm[0] = 1;
66e8aa55a4SKris Buschelman   essl->iparm[1] = 5;
67e8aa55a4SKris Buschelman   essl->iparm[2] = 1;
68e8aa55a4SKris Buschelman   essl->iparm[3] = 0;
69e8aa55a4SKris Buschelman   essl->rparm[0] = 1.e-12;
7062331464SKris Buschelman   essl->rparm[1] = 1.0;
712205254eSKarl Rupp 
729566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetReal(NULL, ((PetscObject)A)->prefix, "-matessl_lu_threshold", &essl->rparm[1], NULL));
73e8aa55a4SKris Buschelman 
74c5c20521SJed Brown   dgsf(&one, &nessl, &essl->nz, essl->a, essl->ia, essl->ja, &essl->lna, essl->iparm, essl->rparm, essl->oparm, essl->aux, &essl->naux);
75e8aa55a4SKris Buschelman 
7635bd34faSBarry Smith   F->ops->solve     = MatSolve_Essl;
77719d5645SBarry Smith   (F)->assembled    = PETSC_TRUE;
78719d5645SBarry Smith   (F)->preallocated = PETSC_TRUE;
79e8aa55a4SKris Buschelman   PetscFunctionReturn(0);
80e8aa55a4SKris Buschelman }
81e8aa55a4SKris Buschelman 
829371c9d4SSatish Balay PetscErrorCode MatLUFactorSymbolic_Essl(Mat B, Mat A, IS r, IS c, const MatFactorInfo *info) {
83eef49c96SKris Buschelman   Mat_SeqAIJ *a = (Mat_SeqAIJ *)A->data;
84f0c56d0fSKris Buschelman   Mat_Essl   *essl;
85e8aa55a4SKris Buschelman   PetscReal   f = 1.0;
86e8aa55a4SKris Buschelman 
87e8aa55a4SKris Buschelman   PetscFunctionBegin;
88ac913495SBarry Smith   essl = (Mat_Essl *)(B->data);
89e8aa55a4SKris Buschelman 
90e8aa55a4SKris Buschelman   /* allocate the work arrays required by ESSL */
91e8aa55a4SKris Buschelman   f = info->fill;
929566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(a->nz, &essl->nz));
939566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast((PetscInt)(a->nz * f), &essl->lna));
949566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(100 + 10 * A->rmap->n, &essl->naux));
95e8aa55a4SKris Buschelman 
96e8aa55a4SKris Buschelman   /* since malloc is slow on IBM we try a single malloc */
979566063dSJacob Faibussowitsch   PetscCall(PetscMalloc4(essl->lna, &essl->a, essl->naux, &essl->aux, essl->lna, &essl->ia, essl->lna, &essl->ja));
982205254eSKarl Rupp 
992f71e704SKris Buschelman   essl->CleanUpESSL = PETSC_TRUE;
100e8aa55a4SKris Buschelman 
101db4efbfdSBarry Smith   B->ops->lufactornumeric = MatLUFactorNumeric_Essl;
102e8aa55a4SKris Buschelman   PetscFunctionReturn(0);
103e8aa55a4SKris Buschelman }
104e8aa55a4SKris Buschelman 
1059371c9d4SSatish Balay PetscErrorCode MatFactorGetSolverType_essl(Mat A, MatSolverType *type) {
10635bd34faSBarry Smith   PetscFunctionBegin;
1072692d6eeSBarry Smith   *type = MATSOLVERESSL;
10835bd34faSBarry Smith   PetscFunctionReturn(0);
10935bd34faSBarry Smith }
110719d5645SBarry Smith 
1112f71e704SKris Buschelman /*MC
11211a5261eSBarry Smith   MATSOLVERESSL - "essl" - Provides direct solvers, LU, for sequential matrices
1132f71e704SKris Buschelman                               via the external package ESSL.
1142f71e704SKris Buschelman 
1152f71e704SKris Buschelman   If ESSL is installed (see the manual for
1162f71e704SKris Buschelman   instructions on how to declare the existence of external packages),
1172f71e704SKris Buschelman 
11811a5261eSBarry Smith   Works with `MATSEQAIJ` matrices
1192f71e704SKris Buschelman 
1202f71e704SKris Buschelman    Level: beginner
1212f71e704SKris Buschelman 
122db781477SPatrick Sanan .seealso: `PCLU`, `PCFactorSetMatSolverType()`, `MatSolverType`
1232f71e704SKris Buschelman M*/
1242f71e704SKris Buschelman 
1259371c9d4SSatish Balay PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_essl(Mat A, MatFactorType ftype, Mat *F) {
126b24902e0SBarry Smith   Mat       B;
127b24902e0SBarry Smith   Mat_Essl *essl;
128e8aa55a4SKris Buschelman 
129e8aa55a4SKris Buschelman   PetscFunctionBegin;
13008401ef6SPierre Jolivet   PetscCheck(A->cmap->N == A->rmap->N, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "matrix must be square");
1319566063dSJacob Faibussowitsch   PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &B));
1329566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(B, PETSC_DECIDE, PETSC_DECIDE, A->rmap->n, A->cmap->n));
1339566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy("essl", &((PetscObject)B)->type_name));
1349566063dSJacob Faibussowitsch   PetscCall(MatSetUp(B));
135b24902e0SBarry Smith 
136*4dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&essl));
1372205254eSKarl Rupp 
138ac913495SBarry Smith   B->data                  = essl;
139b24902e0SBarry Smith   B->ops->lufactorsymbolic = MatLUFactorSymbolic_Essl;
140ac913495SBarry Smith   B->ops->destroy          = MatDestroy_Essl;
141ac913495SBarry Smith   B->ops->getinfo          = MatGetInfo_External;
1422205254eSKarl Rupp 
1439566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatFactorGetSolverType_C", MatFactorGetSolverType_essl));
1442205254eSKarl Rupp 
145d5f3da31SBarry Smith   B->factortype = MAT_FACTOR_LU;
1469566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&B->preferredordering[MAT_FACTOR_LU]));
1479566063dSJacob Faibussowitsch   PetscCall(PetscFree(B->solvertype));
1489566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATSOLVERESSL, &B->solvertype));
14900c67f3bSHong Zhang 
150b24902e0SBarry Smith   *F = B;
151e8aa55a4SKris Buschelman   PetscFunctionReturn(0);
152e8aa55a4SKris Buschelman }
15342c9c57cSBarry Smith 
1549371c9d4SSatish Balay PETSC_EXTERN PetscErrorCode MatSolverTypeRegister_Essl(void) {
15542c9c57cSBarry Smith   PetscFunctionBegin;
1569566063dSJacob Faibussowitsch   PetscCall(MatSolverTypeRegister(MATSOLVERESSL, MATSEQAIJ, MAT_FACTOR_LU, MatGetFactor_seqaij_essl));
15742c9c57cSBarry Smith   PetscFunctionReturn(0);
15842c9c57cSBarry Smith }
159