xref: /petsc/src/mat/impls/aij/seq/essl/essl.c (revision 1baa6e3354bfe224b33a0c158f482508792a8a6e)
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 
28dfbe8321SBarry Smith PetscErrorCode MatDestroy_Essl(Mat A)
29dfbe8321SBarry Smith {
30ac913495SBarry Smith   Mat_Essl       *essl=(Mat_Essl*)A->data;
31e8aa55a4SKris Buschelman 
32e8aa55a4SKris Buschelman   PetscFunctionBegin;
33*1baa6e33SBarry 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 
38b24902e0SBarry Smith PetscErrorCode MatSolve_Essl(Mat A,Vec b,Vec x)
39b24902e0SBarry Smith {
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 
530481f469SBarry Smith PetscErrorCode MatLUFactorNumeric_Essl(Mat F,Mat A,const MatFactorInfo *info)
54b24902e0SBarry Smith {
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));
61e8aa55a4SKris Buschelman   /* copy matrix data into silly ESSL data structure (1-based Frotran 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 
850481f469SBarry Smith PetscErrorCode MatLUFactorSymbolic_Essl(Mat B,Mat A,IS r,IS c,const MatFactorInfo *info)
86b24902e0SBarry Smith {
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 
1059566063dSJacob Faibussowitsch   PetscCall(PetscLogObjectMemory((PetscObject)B,essl->lna*(2*sizeof(int)+sizeof(PetscScalar)) + essl->naux*sizeof(PetscScalar)));
1062205254eSKarl Rupp 
107db4efbfdSBarry Smith   B->ops->lufactornumeric = MatLUFactorNumeric_Essl;
108e8aa55a4SKris Buschelman   PetscFunctionReturn(0);
109e8aa55a4SKris Buschelman }
110e8aa55a4SKris Buschelman 
111ea799195SBarry Smith PetscErrorCode MatFactorGetSolverType_essl(Mat A,MatSolverType *type)
11235bd34faSBarry Smith {
11335bd34faSBarry Smith   PetscFunctionBegin;
1142692d6eeSBarry Smith   *type = MATSOLVERESSL;
11535bd34faSBarry Smith   PetscFunctionReturn(0);
11635bd34faSBarry Smith }
117719d5645SBarry Smith 
1182f71e704SKris Buschelman /*MC
1192692d6eeSBarry Smith   MATSOLVERESSL - "essl" - Provides direct solvers (LU) for sequential matrices
1202f71e704SKris Buschelman                               via the external package ESSL.
1212f71e704SKris Buschelman 
1222f71e704SKris Buschelman   If ESSL is installed (see the manual for
1232f71e704SKris Buschelman   instructions on how to declare the existence of external packages),
1242f71e704SKris Buschelman 
12541c8de11SBarry Smith   Works with MATSEQAIJ matrices
1262f71e704SKris Buschelman 
1272f71e704SKris Buschelman    Level: beginner
1282f71e704SKris Buschelman 
129db781477SPatrick Sanan .seealso: `PCLU`, `PCFactorSetMatSolverType()`, `MatSolverType`
1302f71e704SKris Buschelman M*/
1312f71e704SKris Buschelman 
1328cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_essl(Mat A,MatFactorType ftype,Mat *F)
133dfbe8321SBarry Smith {
134b24902e0SBarry Smith   Mat            B;
135b24902e0SBarry Smith   Mat_Essl       *essl;
136e8aa55a4SKris Buschelman 
137e8aa55a4SKris Buschelman   PetscFunctionBegin;
13808401ef6SPierre Jolivet   PetscCheck(A->cmap->N == A->rmap->N,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"matrix must be square");
1399566063dSJacob Faibussowitsch   PetscCall(MatCreate(PetscObjectComm((PetscObject)A),&B));
1409566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(B,PETSC_DECIDE,PETSC_DECIDE,A->rmap->n,A->cmap->n));
1419566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy("essl",&((PetscObject)B)->type_name));
1429566063dSJacob Faibussowitsch   PetscCall(MatSetUp(B));
143b24902e0SBarry Smith 
1449566063dSJacob Faibussowitsch   PetscCall(PetscNewLog(B,&essl));
1452205254eSKarl Rupp 
146ac913495SBarry Smith   B->data                  = essl;
147b24902e0SBarry Smith   B->ops->lufactorsymbolic = MatLUFactorSymbolic_Essl;
148ac913495SBarry Smith   B->ops->destroy          = MatDestroy_Essl;
149ac913495SBarry Smith   B->ops->getinfo          = MatGetInfo_External;
1502205254eSKarl Rupp 
1519566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatFactorGetSolverType_C",MatFactorGetSolverType_essl));
1522205254eSKarl Rupp 
153d5f3da31SBarry Smith   B->factortype = MAT_FACTOR_LU;
1549566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL,(char**)&B->preferredordering[MAT_FACTOR_LU]));
1559566063dSJacob Faibussowitsch   PetscCall(PetscFree(B->solvertype));
1569566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATSOLVERESSL,&B->solvertype));
15700c67f3bSHong Zhang 
158b24902e0SBarry Smith   *F            = B;
159e8aa55a4SKris Buschelman   PetscFunctionReturn(0);
160e8aa55a4SKris Buschelman }
16142c9c57cSBarry Smith 
1623ca39a21SBarry Smith PETSC_EXTERN PetscErrorCode MatSolverTypeRegister_Essl(void)
16342c9c57cSBarry Smith {
16442c9c57cSBarry Smith   PetscFunctionBegin;
1659566063dSJacob Faibussowitsch   PetscCall(MatSolverTypeRegister(MATSOLVERESSL,MATSEQAIJ,          MAT_FACTOR_LU,MatGetFactor_seqaij_essl));
16642c9c57cSBarry Smith   PetscFunctionReturn(0);
16742c9c57cSBarry Smith }
168