xref: /petsc/src/mat/impls/aij/seq/essl/essl.c (revision 9371c9d470a9602b6d10a8bf50c9b2280a79e45a)
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 
28*9371c9d4SSatish 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 
37*9371c9d4SSatish 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 
51*9371c9d4SSatish 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 
82*9371c9d4SSatish 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 
1019566063dSJacob Faibussowitsch   PetscCall(PetscLogObjectMemory((PetscObject)B, essl->lna * (2 * sizeof(int) + sizeof(PetscScalar)) + essl->naux * sizeof(PetscScalar)));
1022205254eSKarl Rupp 
103db4efbfdSBarry Smith   B->ops->lufactornumeric = MatLUFactorNumeric_Essl;
104e8aa55a4SKris Buschelman   PetscFunctionReturn(0);
105e8aa55a4SKris Buschelman }
106e8aa55a4SKris Buschelman 
107*9371c9d4SSatish Balay PetscErrorCode MatFactorGetSolverType_essl(Mat A, MatSolverType *type) {
10835bd34faSBarry Smith   PetscFunctionBegin;
1092692d6eeSBarry Smith   *type = MATSOLVERESSL;
11035bd34faSBarry Smith   PetscFunctionReturn(0);
11135bd34faSBarry Smith }
112719d5645SBarry Smith 
1132f71e704SKris Buschelman /*MC
1142692d6eeSBarry Smith   MATSOLVERESSL - "essl" - Provides direct solvers (LU) for sequential matrices
1152f71e704SKris Buschelman                               via the external package ESSL.
1162f71e704SKris Buschelman 
1172f71e704SKris Buschelman   If ESSL is installed (see the manual for
1182f71e704SKris Buschelman   instructions on how to declare the existence of external packages),
1192f71e704SKris Buschelman 
12041c8de11SBarry Smith   Works with MATSEQAIJ matrices
1212f71e704SKris Buschelman 
1222f71e704SKris Buschelman    Level: beginner
1232f71e704SKris Buschelman 
124db781477SPatrick Sanan .seealso: `PCLU`, `PCFactorSetMatSolverType()`, `MatSolverType`
1252f71e704SKris Buschelman M*/
1262f71e704SKris Buschelman 
127*9371c9d4SSatish Balay PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_essl(Mat A, MatFactorType ftype, Mat *F) {
128b24902e0SBarry Smith   Mat       B;
129b24902e0SBarry Smith   Mat_Essl *essl;
130e8aa55a4SKris Buschelman 
131e8aa55a4SKris Buschelman   PetscFunctionBegin;
13208401ef6SPierre Jolivet   PetscCheck(A->cmap->N == A->rmap->N, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "matrix must be square");
1339566063dSJacob Faibussowitsch   PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &B));
1349566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(B, PETSC_DECIDE, PETSC_DECIDE, A->rmap->n, A->cmap->n));
1359566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy("essl", &((PetscObject)B)->type_name));
1369566063dSJacob Faibussowitsch   PetscCall(MatSetUp(B));
137b24902e0SBarry Smith 
1389566063dSJacob Faibussowitsch   PetscCall(PetscNewLog(B, &essl));
1392205254eSKarl Rupp 
140ac913495SBarry Smith   B->data                  = essl;
141b24902e0SBarry Smith   B->ops->lufactorsymbolic = MatLUFactorSymbolic_Essl;
142ac913495SBarry Smith   B->ops->destroy          = MatDestroy_Essl;
143ac913495SBarry Smith   B->ops->getinfo          = MatGetInfo_External;
1442205254eSKarl Rupp 
1459566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatFactorGetSolverType_C", MatFactorGetSolverType_essl));
1462205254eSKarl Rupp 
147d5f3da31SBarry Smith   B->factortype = MAT_FACTOR_LU;
1489566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&B->preferredordering[MAT_FACTOR_LU]));
1499566063dSJacob Faibussowitsch   PetscCall(PetscFree(B->solvertype));
1509566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATSOLVERESSL, &B->solvertype));
15100c67f3bSHong Zhang 
152b24902e0SBarry Smith   *F = B;
153e8aa55a4SKris Buschelman   PetscFunctionReturn(0);
154e8aa55a4SKris Buschelman }
15542c9c57cSBarry Smith 
156*9371c9d4SSatish Balay PETSC_EXTERN PetscErrorCode MatSolverTypeRegister_Essl(void) {
15742c9c57cSBarry Smith   PetscFunctionBegin;
1589566063dSJacob Faibussowitsch   PetscCall(MatSolverTypeRegister(MATSOLVERESSL, MATSEQAIJ, MAT_FACTOR_LU, MatGetFactor_seqaij_essl));
15942c9c57cSBarry Smith   PetscFunctionReturn(0);
16042c9c57cSBarry Smith }
161