xref: /petsc/src/mat/impls/aij/seq/essl/essl.c (revision 623314640fcfe94a7994dda215080b89573add91)
1e8aa55a4SKris Buschelman 
2e8aa55a4SKris Buschelman /*
3e8aa55a4SKris Buschelman         Provides an interface to the IBM RS6000 Essl sparse solver
4e8aa55a4SKris Buschelman 
5e8aa55a4SKris Buschelman */
6e8aa55a4SKris Buschelman #include "src/mat/impls/aij/seq/aij.h"
7e8aa55a4SKris Buschelman /* #include <essl.h> This doesn't work!  */
8e8aa55a4SKris Buschelman 
9e8aa55a4SKris Buschelman typedef struct {
10e8aa55a4SKris Buschelman   int         n,nz;
11e8aa55a4SKris Buschelman   PetscScalar *a;
12e8aa55a4SKris Buschelman   int         *ia;
13e8aa55a4SKris Buschelman   int         *ja;
14e8aa55a4SKris Buschelman   int         lna;
15e8aa55a4SKris Buschelman   int         iparm[5];
16e8aa55a4SKris Buschelman   PetscReal   rparm[5];
17e8aa55a4SKris Buschelman   PetscReal   oparm[5];
18e8aa55a4SKris Buschelman   PetscScalar *aux;
19e8aa55a4SKris Buschelman   int         naux;
20e8aa55a4SKris Buschelman 
216849ba73SBarry Smith   PetscErrorCode (*MatDuplicate)(Mat,MatDuplicateOption,Mat*);
226849ba73SBarry Smith   PetscErrorCode (*MatAssemblyEnd)(Mat,MatAssemblyType);
236849ba73SBarry Smith   PetscErrorCode (*MatLUFactorSymbolic)(Mat,IS,IS,MatFactorInfo*,Mat*);
246849ba73SBarry Smith   PetscErrorCode (*MatDestroy)(Mat);
252f71e704SKris Buschelman   PetscTruth CleanUpESSL;
26f0c56d0fSKris Buschelman } Mat_Essl;
27f0c56d0fSKris Buschelman 
28dfbe8321SBarry Smith EXTERN PetscErrorCode MatDuplicate_Essl(Mat,MatDuplicateOption,Mat*);
29e8aa55a4SKris Buschelman 
30460c4903SKris Buschelman EXTERN_C_BEGIN
31460c4903SKris Buschelman #undef __FUNCT__
32460c4903SKris Buschelman #define __FUNCT__ "MatConvert_Essl_SeqAIJ"
33ceb03754SKris Buschelman PetscErrorCode MatConvert_Essl_SeqAIJ(Mat A,const MatType type,MatReuse reuse,Mat *newmat) {
34dfbe8321SBarry Smith   PetscErrorCode ierr;
35460c4903SKris Buschelman   Mat      B=*newmat;
36f0c56d0fSKris Buschelman   Mat_Essl *essl=(Mat_Essl*)A->spptr;
37460c4903SKris Buschelman 
38460c4903SKris Buschelman   PetscFunctionBegin;
39ceb03754SKris Buschelman   if (reuse == MAT_INITIAL_MATRIX) {
40460c4903SKris Buschelman     ierr = MatDuplicate(A,MAT_COPY_VALUES,&B);
41f0c56d0fSKris Buschelman   }
42f0c56d0fSKris Buschelman   B->ops->duplicate        = essl->MatDuplicate;
43f0c56d0fSKris Buschelman   B->ops->assemblyend      = essl->MatAssemblyEnd;
442f71e704SKris Buschelman   B->ops->lufactorsymbolic = essl->MatLUFactorSymbolic;
452f71e704SKris Buschelman   B->ops->destroy          = essl->MatDestroy;
462f71e704SKris Buschelman 
47460c4903SKris Buschelman   /* free the Essl datastructures */
48460c4903SKris Buschelman   ierr = PetscFree(essl);CHKERRQ(ierr);
49901853e0SKris Buschelman 
50901853e0SKris Buschelman   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_essl_C","",PETSC_NULL);CHKERRQ(ierr);
51901853e0SKris Buschelman   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_essl_seqaij_C","",PETSC_NULL);CHKERRQ(ierr);
52901853e0SKris Buschelman 
53460c4903SKris Buschelman   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
54460c4903SKris Buschelman   *newmat = B;
55460c4903SKris Buschelman   PetscFunctionReturn(0);
56460c4903SKris Buschelman }
57460c4903SKris Buschelman EXTERN_C_END
58460c4903SKris Buschelman 
59e8aa55a4SKris Buschelman #undef __FUNCT__
60f0c56d0fSKris Buschelman #define __FUNCT__ "MatDestroy_Essl"
61dfbe8321SBarry Smith PetscErrorCode MatDestroy_Essl(Mat A)
62dfbe8321SBarry Smith {
63dfbe8321SBarry Smith   PetscErrorCode ierr;
64f0c56d0fSKris Buschelman   Mat_Essl *essl=(Mat_Essl*)A->spptr;
65e8aa55a4SKris Buschelman 
66e8aa55a4SKris Buschelman   PetscFunctionBegin;
672f71e704SKris Buschelman   if (essl->CleanUpESSL) {
682f71e704SKris Buschelman     ierr = PetscFree(essl->a);CHKERRQ(ierr);
69e8aa55a4SKris Buschelman   }
70ceb03754SKris Buschelman   ierr = MatConvert_Essl_SeqAIJ(A,MATSEQAIJ,MAT_REUSE_MATRIX,&A);
712f71e704SKris Buschelman   ierr = (*A->ops->destroy)(A);CHKERRQ(ierr);
72460c4903SKris Buschelman   PetscFunctionReturn(0);
73460c4903SKris Buschelman }
74460c4903SKris Buschelman 
75460c4903SKris Buschelman #undef __FUNCT__
76f0c56d0fSKris Buschelman #define __FUNCT__ "MatSolve_Essl"
77dfbe8321SBarry Smith PetscErrorCode MatSolve_Essl(Mat A,Vec b,Vec x) {
78f0c56d0fSKris Buschelman   Mat_Essl    *essl = (Mat_Essl*)A->spptr;
79e8aa55a4SKris Buschelman   PetscScalar *xx;
80dfbe8321SBarry Smith   PetscErrorCode ierr;
81dfbe8321SBarry Smith   int         m,zero = 0;
82e8aa55a4SKris Buschelman 
83e8aa55a4SKris Buschelman   PetscFunctionBegin;
84e8aa55a4SKris Buschelman   ierr = VecGetLocalSize(b,&m);CHKERRQ(ierr);
85e8aa55a4SKris Buschelman   ierr = VecCopy(b,x);CHKERRQ(ierr);
86e8aa55a4SKris Buschelman   ierr = VecGetArray(x,&xx);CHKERRQ(ierr);
87e8aa55a4SKris Buschelman   dgss(&zero,&A->n,essl->a,essl->ia,essl->ja,&essl->lna,xx,essl->aux,&essl->naux);
88e8aa55a4SKris Buschelman   ierr = VecRestoreArray(x,&xx);CHKERRQ(ierr);
89e8aa55a4SKris Buschelman   PetscFunctionReturn(0);
90e8aa55a4SKris Buschelman }
91e8aa55a4SKris Buschelman 
92e8aa55a4SKris Buschelman #undef __FUNCT__
93f0c56d0fSKris Buschelman #define __FUNCT__ "MatLUFactorNumeric_Essl"
94af281ebdSHong Zhang PetscErrorCode MatLUFactorNumeric_Essl(Mat A,MatFactorInfo *info,Mat *F) {
95e8aa55a4SKris Buschelman   Mat_SeqAIJ     *aa=(Mat_SeqAIJ*)(A)->data;
96f0c56d0fSKris Buschelman   Mat_Essl       *essl=(Mat_Essl*)(*F)->spptr;
976849ba73SBarry Smith   PetscErrorCode ierr;
986849ba73SBarry Smith   int            i,one = 1;
99e8aa55a4SKris Buschelman 
100e8aa55a4SKris Buschelman   PetscFunctionBegin;
101e8aa55a4SKris Buschelman   /* copy matrix data into silly ESSL data structure (1-based Frotran style) */
102e8aa55a4SKris Buschelman   for (i=0; i<A->m+1; i++) essl->ia[i] = aa->i[i] + 1;
103e8aa55a4SKris Buschelman   for (i=0; i<aa->nz; i++) essl->ja[i]  = aa->j[i] + 1;
104e8aa55a4SKris Buschelman 
105e8aa55a4SKris Buschelman   ierr = PetscMemcpy(essl->a,aa->a,(aa->nz)*sizeof(PetscScalar));CHKERRQ(ierr);
106e8aa55a4SKris Buschelman 
107e8aa55a4SKris Buschelman   /* set Essl options */
108e8aa55a4SKris Buschelman   essl->iparm[0] = 1;
109e8aa55a4SKris Buschelman   essl->iparm[1] = 5;
110e8aa55a4SKris Buschelman   essl->iparm[2] = 1;
111e8aa55a4SKris Buschelman   essl->iparm[3] = 0;
112e8aa55a4SKris Buschelman   essl->rparm[0] = 1.e-12;
113*62331464SKris Buschelman   essl->rparm[1] = 1.0;
114*62331464SKris Buschelman   ierr = PetscOptionsGetReal(A->prefix,"-matessl_lu_threshold",&essl->rparm[1],PETSC_NULL);CHKERRQ(ierr);
115e8aa55a4SKris Buschelman 
116e8aa55a4SKris Buschelman   dgsf(&one,&A->m,&essl->nz,essl->a,essl->ia,essl->ja,&essl->lna,essl->iparm,
117e8aa55a4SKris Buschelman                essl->rparm,essl->oparm,essl->aux,&essl->naux);
118e8aa55a4SKris Buschelman 
119e8aa55a4SKris Buschelman   PetscFunctionReturn(0);
120e8aa55a4SKris Buschelman }
121e8aa55a4SKris Buschelman 
122e8aa55a4SKris Buschelman #undef __FUNCT__
123f0c56d0fSKris Buschelman #define __FUNCT__ "MatLUFactorSymbolic_Essl"
124dfbe8321SBarry Smith PetscErrorCode MatLUFactorSymbolic_Essl(Mat A,IS r,IS c,MatFactorInfo *info,Mat *F) {
125e8aa55a4SKris Buschelman   Mat        B;
126eef49c96SKris Buschelman   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
127dfbe8321SBarry Smith   PetscErrorCode ierr;
128dfbe8321SBarry Smith   int        len;
129f0c56d0fSKris Buschelman   Mat_Essl   *essl;
130e8aa55a4SKris Buschelman   PetscReal  f = 1.0;
131e8aa55a4SKris Buschelman 
132e8aa55a4SKris Buschelman   PetscFunctionBegin;
133e8aa55a4SKris Buschelman   if (A->N != A->M) SETERRQ(PETSC_ERR_ARG_SIZ,"matrix must be square");
134e8aa55a4SKris Buschelman   ierr = MatCreate(A->comm,PETSC_DECIDE,PETSC_DECIDE,A->m,A->n,&B);CHKERRQ(ierr);
135be5d1d56SKris Buschelman   ierr = MatSetType(B,A->type_name);CHKERRQ(ierr);
136e8aa55a4SKris Buschelman   ierr = MatSeqAIJSetPreallocation(B,0,PETSC_NULL);CHKERRQ(ierr);
137e8aa55a4SKris Buschelman 
138f0c56d0fSKris Buschelman   B->ops->solve           = MatSolve_Essl;
139f0c56d0fSKris Buschelman   B->ops->lufactornumeric = MatLUFactorNumeric_Essl;
140e8aa55a4SKris Buschelman   B->factor               = FACTOR_LU;
141e8aa55a4SKris Buschelman 
142f0c56d0fSKris Buschelman   essl = (Mat_Essl *)(B->spptr);
143e8aa55a4SKris Buschelman 
144e8aa55a4SKris Buschelman   /* allocate the work arrays required by ESSL */
145e8aa55a4SKris Buschelman   f = info->fill;
146e8aa55a4SKris Buschelman   essl->nz   = a->nz;
147e8aa55a4SKris Buschelman   essl->lna  = (int)a->nz*f;
148e8aa55a4SKris Buschelman   essl->naux = 100 + 10*A->m;
149e8aa55a4SKris Buschelman 
150e8aa55a4SKris Buschelman   /* since malloc is slow on IBM we try a single malloc */
151e8aa55a4SKris Buschelman   len               = essl->lna*(2*sizeof(int)+sizeof(PetscScalar)) + essl->naux*sizeof(PetscScalar);
152e8aa55a4SKris Buschelman   ierr              = PetscMalloc(len,&essl->a);CHKERRQ(ierr);
153e8aa55a4SKris Buschelman   essl->aux         = essl->a + essl->lna;
154e8aa55a4SKris Buschelman   essl->ia          = (int*)(essl->aux + essl->naux);
155e8aa55a4SKris Buschelman   essl->ja          = essl->ia + essl->lna;
1562f71e704SKris Buschelman   essl->CleanUpESSL = PETSC_TRUE;
157e8aa55a4SKris Buschelman 
15852e6d16bSBarry Smith   ierr = PetscLogObjectMemory(B,len+sizeof(Mat_Essl));CHKERRQ(ierr);
159e8aa55a4SKris Buschelman   *F = B;
160e8aa55a4SKris Buschelman   PetscFunctionReturn(0);
161e8aa55a4SKris Buschelman }
162e8aa55a4SKris Buschelman 
1632f71e704SKris Buschelman #undef __FUNCT__
164f0c56d0fSKris Buschelman #define __FUNCT__ "MatAssemblyEnd_Essl"
165dfbe8321SBarry Smith PetscErrorCode MatAssemblyEnd_Essl(Mat A,MatAssemblyType mode) {
166dfbe8321SBarry Smith   PetscErrorCode ierr;
167f0c56d0fSKris Buschelman   Mat_Essl *essl=(Mat_Essl*)(A->spptr);
1682f71e704SKris Buschelman 
1692f71e704SKris Buschelman   PetscFunctionBegin;
1702f71e704SKris Buschelman   ierr = (*essl->MatAssemblyEnd)(A,mode);CHKERRQ(ierr);
1712f71e704SKris Buschelman 
1722f71e704SKris Buschelman   essl->MatLUFactorSymbolic = A->ops->lufactorsymbolic;
173f0c56d0fSKris Buschelman   A->ops->lufactorsymbolic  = MatLUFactorSymbolic_Essl;
17452e6d16bSBarry Smith   PetscLogInfo(0,"MatAssemblyEnd_Essl:Using ESSL for LU factorization and solves");
1752f71e704SKris Buschelman   PetscFunctionReturn(0);
1762f71e704SKris Buschelman }
1772f71e704SKris Buschelman 
178460c4903SKris Buschelman EXTERN_C_BEGIN
179e8aa55a4SKris Buschelman #undef __FUNCT__
180460c4903SKris Buschelman #define __FUNCT__ "MatConvert_SeqAIJ_Essl"
181ceb03754SKris Buschelman PetscErrorCode MatConvert_SeqAIJ_Essl(Mat A,const MatType type,MatReuse reuse,Mat *newmat)
182521d7252SBarry Smith {
183460c4903SKris Buschelman   Mat      B=*newmat;
184dfbe8321SBarry Smith   PetscErrorCode ierr;
185f0c56d0fSKris Buschelman   Mat_Essl *essl;
186460c4903SKris Buschelman 
187e8aa55a4SKris Buschelman   PetscFunctionBegin;
188ceb03754SKris Buschelman   if (reuse == MAT_INITIAL_MATRIX) {
189460c4903SKris Buschelman     ierr = MatDuplicate(A,MAT_COPY_VALUES,&B);CHKERRQ(ierr);
190460c4903SKris Buschelman   }
191460c4903SKris Buschelman 
192f0c56d0fSKris Buschelman   ierr                      = PetscNew(Mat_Essl,&essl);CHKERRQ(ierr);
193f0c56d0fSKris Buschelman   essl->MatDuplicate        = A->ops->duplicate;
194460c4903SKris Buschelman   essl->MatAssemblyEnd      = A->ops->assemblyend;
195460c4903SKris Buschelman   essl->MatLUFactorSymbolic = A->ops->lufactorsymbolic;
196460c4903SKris Buschelman   essl->MatDestroy          = A->ops->destroy;
1972f71e704SKris Buschelman   essl->CleanUpESSL         = PETSC_FALSE;
198460c4903SKris Buschelman 
1992f71e704SKris Buschelman   B->spptr                  = (void*)essl;
200f0c56d0fSKris Buschelman   B->ops->duplicate         = MatDuplicate_Essl;
201f0c56d0fSKris Buschelman   B->ops->assemblyend       = MatAssemblyEnd_Essl;
202f0c56d0fSKris Buschelman   B->ops->lufactorsymbolic  = MatLUFactorSymbolic_Essl;
203f0c56d0fSKris Buschelman   B->ops->destroy           = MatDestroy_Essl;
204460c4903SKris Buschelman 
205460c4903SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_essl_C",
206460c4903SKris Buschelman                                            "MatConvert_SeqAIJ_Essl",MatConvert_SeqAIJ_Essl);CHKERRQ(ierr);
207460c4903SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_essl_seqaij_C",
208460c4903SKris Buschelman                                            "MatConvert_Essl_SeqAIJ",MatConvert_Essl_SeqAIJ);CHKERRQ(ierr);
209460c4903SKris Buschelman   ierr = PetscObjectChangeTypeName((PetscObject)B,type);CHKERRQ(ierr);
210*62331464SKris Buschelman 
211460c4903SKris Buschelman   *newmat = B;
212e8aa55a4SKris Buschelman   PetscFunctionReturn(0);
213e8aa55a4SKris Buschelman }
214460c4903SKris Buschelman EXTERN_C_END
215e8aa55a4SKris Buschelman 
216f0c56d0fSKris Buschelman #undef __FUNCT__
217f0c56d0fSKris Buschelman #define __FUNCT__ "MatDuplicate_Essl"
218dfbe8321SBarry Smith PetscErrorCode MatDuplicate_Essl(Mat A, MatDuplicateOption op, Mat *M) {
219dfbe8321SBarry Smith   PetscErrorCode ierr;
22013ee22deSSatish Balay   Mat_Essl *lu = (Mat_Essl *)A->spptr;
2218f340917SKris Buschelman 
222f0c56d0fSKris Buschelman   PetscFunctionBegin;
2238f340917SKris Buschelman   ierr = (*lu->MatDuplicate)(A,op,M);CHKERRQ(ierr);
2243f953163SKris Buschelman   ierr = PetscMemcpy((*M)->spptr,lu,sizeof(Mat_Essl));CHKERRQ(ierr);
225f0c56d0fSKris Buschelman   PetscFunctionReturn(0);
226f0c56d0fSKris Buschelman }
227f0c56d0fSKris Buschelman 
2282f71e704SKris Buschelman /*MC
229fafad747SKris Buschelman   MATESSL - MATESSL = "essl" - A matrix type providing direct solvers (LU) for sequential matrices
2302f71e704SKris Buschelman   via the external package ESSL.
2312f71e704SKris Buschelman 
2322f71e704SKris Buschelman   If ESSL is installed (see the manual for
2332f71e704SKris Buschelman   instructions on how to declare the existence of external packages),
2342f71e704SKris Buschelman   a matrix type can be constructed which invokes ESSL solvers.
2352f71e704SKris Buschelman   After calling MatCreate(...,A), simply call MatSetType(A,MATESSL).
2362f71e704SKris Buschelman   This matrix type is only supported for double precision real.
2372f71e704SKris Buschelman 
2382f71e704SKris Buschelman   This matrix inherits from MATSEQAIJ.  As a result, MatSeqAIJSetPreallocation is
23928b08bd3SKris Buschelman   supported for this matrix type.  One can also call MatConvert for an inplace conversion to or from
24028b08bd3SKris Buschelman   the MATSEQAIJ type without data copy.
2412f71e704SKris Buschelman 
2422f71e704SKris Buschelman   Options Database Keys:
2430bad9183SKris Buschelman . -mat_type essl - sets the matrix type to "essl" during a call to MatSetFromOptions()
2442f71e704SKris Buschelman 
2452f71e704SKris Buschelman    Level: beginner
2462f71e704SKris Buschelman 
2472f71e704SKris Buschelman .seealso: PCLU
2482f71e704SKris Buschelman M*/
2492f71e704SKris Buschelman 
250e8aa55a4SKris Buschelman EXTERN_C_BEGIN
251e8aa55a4SKris Buschelman #undef __FUNCT__
252f0c56d0fSKris Buschelman #define __FUNCT__ "MatCreate_Essl"
253dfbe8321SBarry Smith PetscErrorCode MatCreate_Essl(Mat A)
254dfbe8321SBarry Smith {
255dfbe8321SBarry Smith   PetscErrorCode ierr;
256e8aa55a4SKris Buschelman 
257e8aa55a4SKris Buschelman   PetscFunctionBegin;
2585441df8eSKris Buschelman   /* Change type name before calling MatSetType to force proper construction of SeqAIJ and Essl types */
2595441df8eSKris Buschelman   ierr = PetscObjectChangeTypeName((PetscObject)A,MATESSL);CHKERRQ(ierr);
260e8aa55a4SKris Buschelman   ierr = MatSetType(A,MATSEQAIJ);
261ceb03754SKris Buschelman   ierr = MatConvert_SeqAIJ_Essl(A,MATESSL,MAT_REUSE_MATRIX,&A);CHKERRQ(ierr);
262e8aa55a4SKris Buschelman   PetscFunctionReturn(0);
263e8aa55a4SKris Buschelman }
2644eb8e494SKris Buschelman EXTERN_C_END
265