xref: /petsc/src/mat/impls/aij/seq/essl/essl.c (revision 1cc06b555e92f8ec64db10330b8bbd830e5bc876)
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));
353ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
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));
503ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
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));
61da81f932SPierre 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;
823ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
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;
1063ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
107e8aa55a4SKris Buschelman }
108e8aa55a4SKris Buschelman 
109d71ae5a4SJacob Faibussowitsch PetscErrorCode MatFactorGetSolverType_essl(Mat A, MatSolverType *type)
110d71ae5a4SJacob Faibussowitsch {
11135bd34faSBarry Smith   PetscFunctionBegin;
1122692d6eeSBarry Smith   *type = MATSOLVERESSL;
1133ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
11435bd34faSBarry Smith }
115719d5645SBarry Smith 
1162f71e704SKris Buschelman /*MC
1172ef1f0ffSBarry Smith   MATSOLVERESSL - "essl" - Provides direct solvers, LU, for sequential matrices via the external package ESSL.
1182f71e704SKris Buschelman 
11911a5261eSBarry Smith   Works with `MATSEQAIJ` matrices
1202f71e704SKris Buschelman 
1212f71e704SKris Buschelman    Level: beginner
1222f71e704SKris Buschelman 
123*1cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `PCLU`, `PCFactorSetMatSolverType()`, `MatSolverType`
1242f71e704SKris Buschelman M*/
1252f71e704SKris Buschelman 
126d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_essl(Mat A, MatFactorType ftype, Mat *F)
127d71ae5a4SJacob Faibussowitsch {
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 
1384dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&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;
1533ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
154e8aa55a4SKris Buschelman }
15542c9c57cSBarry Smith 
156d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode MatSolverTypeRegister_Essl(void)
157d71ae5a4SJacob Faibussowitsch {
15842c9c57cSBarry Smith   PetscFunctionBegin;
1599566063dSJacob Faibussowitsch   PetscCall(MatSolverTypeRegister(MATSOLVERESSL, MATSEQAIJ, MAT_FACTOR_LU, MatGetFactor_seqaij_essl));
1603ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
16142c9c57cSBarry Smith }
162