xref: /petsc/src/mat/impls/aij/seq/essl/essl.c (revision da81f9329be15cc55f054c8a00978087195c9247)
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 
28d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDestroy_Essl(Mat A)
29d71ae5a4SJacob Faibussowitsch {
30ac913495SBarry Smith   Mat_Essl *essl = (Mat_Essl *)A->data;
31e8aa55a4SKris Buschelman 
32e8aa55a4SKris Buschelman   PetscFunctionBegin;
331baa6e33SBarry Smith   if (essl->CleanUpESSL) PetscCall(PetscFree4(essl->a, essl->aux, essl->ia, essl->ja));
349566063dSJacob Faibussowitsch   PetscCall(PetscFree(A->data));
35460c4903SKris Buschelman   PetscFunctionReturn(0);
36460c4903SKris Buschelman }
37460c4903SKris Buschelman 
38d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSolve_Essl(Mat A, Vec b, Vec x)
39d71ae5a4SJacob Faibussowitsch {
40ac913495SBarry Smith   Mat_Essl    *essl = (Mat_Essl *)A->data;
41e8aa55a4SKris Buschelman   PetscScalar *xx;
42c5c20521SJed Brown   int          nessl, zero = 0;
43e8aa55a4SKris Buschelman 
44e8aa55a4SKris Buschelman   PetscFunctionBegin;
459566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &nessl));
469566063dSJacob Faibussowitsch   PetscCall(VecCopy(b, x));
479566063dSJacob Faibussowitsch   PetscCall(VecGetArray(x, &xx));
48c5c20521SJed Brown   dgss(&zero, &nessl, essl->a, essl->ia, essl->ja, &essl->lna, xx, essl->aux, &essl->naux);
499566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(x, &xx));
50e8aa55a4SKris Buschelman   PetscFunctionReturn(0);
51e8aa55a4SKris Buschelman }
52e8aa55a4SKris Buschelman 
53d71ae5a4SJacob Faibussowitsch PetscErrorCode MatLUFactorNumeric_Essl(Mat F, Mat A, const MatFactorInfo *info)
54d71ae5a4SJacob Faibussowitsch {
55e8aa55a4SKris Buschelman   Mat_SeqAIJ *aa   = (Mat_SeqAIJ *)(A)->data;
56ac913495SBarry Smith   Mat_Essl   *essl = (Mat_Essl *)(F)->data;
57c5c20521SJed Brown   int         nessl, i, one = 1;
58e8aa55a4SKris Buschelman 
59e8aa55a4SKris Buschelman   PetscFunctionBegin;
609566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n, &nessl));
61*da81f932SPierre Jolivet   /* copy matrix data into silly ESSL data structure (1-based Fortran style) */
62d0f46423SBarry Smith   for (i = 0; i < A->rmap->n + 1; i++) essl->ia[i] = aa->i[i] + 1;
63e8aa55a4SKris Buschelman   for (i = 0; i < aa->nz; i++) essl->ja[i] = aa->j[i] + 1;
64e8aa55a4SKris Buschelman 
659566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy(essl->a, aa->a, aa->nz));
66e8aa55a4SKris Buschelman 
67e8aa55a4SKris Buschelman   /* set Essl options */
68e8aa55a4SKris Buschelman   essl->iparm[0] = 1;
69e8aa55a4SKris Buschelman   essl->iparm[1] = 5;
70e8aa55a4SKris Buschelman   essl->iparm[2] = 1;
71e8aa55a4SKris Buschelman   essl->iparm[3] = 0;
72e8aa55a4SKris Buschelman   essl->rparm[0] = 1.e-12;
7362331464SKris Buschelman   essl->rparm[1] = 1.0;
742205254eSKarl Rupp 
759566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetReal(NULL, ((PetscObject)A)->prefix, "-matessl_lu_threshold", &essl->rparm[1], NULL));
76e8aa55a4SKris Buschelman 
77c5c20521SJed Brown   dgsf(&one, &nessl, &essl->nz, essl->a, essl->ia, essl->ja, &essl->lna, essl->iparm, essl->rparm, essl->oparm, essl->aux, &essl->naux);
78e8aa55a4SKris Buschelman 
7935bd34faSBarry Smith   F->ops->solve     = MatSolve_Essl;
80719d5645SBarry Smith   (F)->assembled    = PETSC_TRUE;
81719d5645SBarry Smith   (F)->preallocated = PETSC_TRUE;
82e8aa55a4SKris Buschelman   PetscFunctionReturn(0);
83e8aa55a4SKris Buschelman }
84e8aa55a4SKris Buschelman 
85d71ae5a4SJacob Faibussowitsch PetscErrorCode MatLUFactorSymbolic_Essl(Mat B, Mat A, IS r, IS c, const MatFactorInfo *info)
86d71ae5a4SJacob Faibussowitsch {
87eef49c96SKris Buschelman   Mat_SeqAIJ *a = (Mat_SeqAIJ *)A->data;
88f0c56d0fSKris Buschelman   Mat_Essl   *essl;
89e8aa55a4SKris Buschelman   PetscReal   f = 1.0;
90e8aa55a4SKris Buschelman 
91e8aa55a4SKris Buschelman   PetscFunctionBegin;
92ac913495SBarry Smith   essl = (Mat_Essl *)(B->data);
93e8aa55a4SKris Buschelman 
94e8aa55a4SKris Buschelman   /* allocate the work arrays required by ESSL */
95e8aa55a4SKris Buschelman   f = info->fill;
969566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(a->nz, &essl->nz));
979566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast((PetscInt)(a->nz * f), &essl->lna));
989566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(100 + 10 * A->rmap->n, &essl->naux));
99e8aa55a4SKris Buschelman 
100e8aa55a4SKris Buschelman   /* since malloc is slow on IBM we try a single malloc */
1019566063dSJacob Faibussowitsch   PetscCall(PetscMalloc4(essl->lna, &essl->a, essl->naux, &essl->aux, essl->lna, &essl->ia, essl->lna, &essl->ja));
1022205254eSKarl Rupp 
1032f71e704SKris Buschelman   essl->CleanUpESSL = PETSC_TRUE;
104e8aa55a4SKris Buschelman 
105db4efbfdSBarry Smith   B->ops->lufactornumeric = MatLUFactorNumeric_Essl;
106e8aa55a4SKris Buschelman   PetscFunctionReturn(0);
107e8aa55a4SKris Buschelman }
108e8aa55a4SKris Buschelman 
109d71ae5a4SJacob Faibussowitsch PetscErrorCode MatFactorGetSolverType_essl(Mat A, MatSolverType *type)
110d71ae5a4SJacob Faibussowitsch {
11135bd34faSBarry Smith   PetscFunctionBegin;
1122692d6eeSBarry Smith   *type = MATSOLVERESSL;
11335bd34faSBarry Smith   PetscFunctionReturn(0);
11435bd34faSBarry Smith }
115719d5645SBarry Smith 
1162f71e704SKris Buschelman /*MC
11711a5261eSBarry Smith   MATSOLVERESSL - "essl" - Provides direct solvers, LU, for sequential matrices
1182f71e704SKris Buschelman                               via the external package ESSL.
1192f71e704SKris Buschelman 
1202f71e704SKris Buschelman   If ESSL is installed (see the manual for
1212f71e704SKris Buschelman   instructions on how to declare the existence of external packages),
1222f71e704SKris Buschelman 
12311a5261eSBarry Smith   Works with `MATSEQAIJ` matrices
1242f71e704SKris Buschelman 
1252f71e704SKris Buschelman    Level: beginner
1262f71e704SKris Buschelman 
127db781477SPatrick Sanan .seealso: `PCLU`, `PCFactorSetMatSolverType()`, `MatSolverType`
1282f71e704SKris Buschelman M*/
1292f71e704SKris Buschelman 
130d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_essl(Mat A, MatFactorType ftype, Mat *F)
131d71ae5a4SJacob Faibussowitsch {
132b24902e0SBarry Smith   Mat       B;
133b24902e0SBarry Smith   Mat_Essl *essl;
134e8aa55a4SKris Buschelman 
135e8aa55a4SKris Buschelman   PetscFunctionBegin;
13608401ef6SPierre Jolivet   PetscCheck(A->cmap->N == A->rmap->N, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "matrix must be square");
1379566063dSJacob Faibussowitsch   PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &B));
1389566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(B, PETSC_DECIDE, PETSC_DECIDE, A->rmap->n, A->cmap->n));
1399566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy("essl", &((PetscObject)B)->type_name));
1409566063dSJacob Faibussowitsch   PetscCall(MatSetUp(B));
141b24902e0SBarry Smith 
1424dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&essl));
1432205254eSKarl Rupp 
144ac913495SBarry Smith   B->data                  = essl;
145b24902e0SBarry Smith   B->ops->lufactorsymbolic = MatLUFactorSymbolic_Essl;
146ac913495SBarry Smith   B->ops->destroy          = MatDestroy_Essl;
147ac913495SBarry Smith   B->ops->getinfo          = MatGetInfo_External;
1482205254eSKarl Rupp 
1499566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatFactorGetSolverType_C", MatFactorGetSolverType_essl));
1502205254eSKarl Rupp 
151d5f3da31SBarry Smith   B->factortype = MAT_FACTOR_LU;
1529566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&B->preferredordering[MAT_FACTOR_LU]));
1539566063dSJacob Faibussowitsch   PetscCall(PetscFree(B->solvertype));
1549566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATSOLVERESSL, &B->solvertype));
15500c67f3bSHong Zhang 
156b24902e0SBarry Smith   *F = B;
157e8aa55a4SKris Buschelman   PetscFunctionReturn(0);
158e8aa55a4SKris Buschelman }
15942c9c57cSBarry Smith 
160d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode MatSolverTypeRegister_Essl(void)
161d71ae5a4SJacob Faibussowitsch {
16242c9c57cSBarry Smith   PetscFunctionBegin;
1639566063dSJacob Faibussowitsch   PetscCall(MatSolverTypeRegister(MATSOLVERESSL, MATSEQAIJ, MAT_FACTOR_LU, MatGetFactor_seqaij_essl));
16442c9c57cSBarry Smith   PetscFunctionReturn(0);
16542c9c57cSBarry Smith }
166